使用构建器模式编组解组不可变对象的最佳方法

时间:2011-06-14 10:51:43

标签: java jaxb jersey jackson

我有一个简单的宁静服务,我正在用java开发。我一直在寻找编组/解组json的一些选项。可用的方法,jaxb jackson等,对我来说都是一个新手,我正试图找到他们的脚。我想知道我是否可以得到一些关于什么是最好的方法和技术的建议,特别是考虑到我感兴趣的许多对象已经实现为不可变并且我使用了构建器模式。所以没有setter,构造函数是私有的。

我看过上一个问题:Jackson + Builder Pattern?发布在stackoverflow上。我正在考虑类似这种方法的东西,尽管获得关于使用@JsonDeserialize

的更多资源的指示会很棒

这是我正在考虑的对象类型的一个非常简单的例子

public class Reading {

private final double xCoord;
private final double yCoord;
private final double diameter;
private final double reliability;
private final String qualityCode;


private Reading(Builder builder){
    xCoord = builder.xCoord;
    yCoord = builder.yCoord;
    diameter = builder.diameter;
    reliability = builder.reliability;
    qualityCode = builder.qualityCode;
}


public static class Builder {
    //required parameters
    private final double diameter;
    //optional parameters
    private double xCoord = 0.0;
    private double yCoord = 0.0;
    private double reliability = 1.0;
    private String qualityCode;


    public Builder (double diameter){
        this.diameter = diameter;
    }

    public Builder reliability(double val){
        reliability = val;
        return this;
    }

    public Builder qualityCode(String qualityCode){
        this.qualityCode = qualityCode;
        return this;
    }

    public Builder coordinates(double xCoord, double yCoord){
        this.xCoord = xCoord;
        this.yCoord = yCoord;
        return this;
    }

    public Reading build(){
        return new Reading(this);
    }

}

public double getXCoord() {return xCoord;}

public double getYCoord() {return yCoord;}

public String getQualityCode() {return qualityCode;}

public double getDiameter() { return diameter;}

public double getReliability() {return reliability; }

}

编组此对象没有问题,但解组似乎不是直截了当的。还是支持省略对象值为null的条目吗?

5 个答案:

答案 0 :(得分:6)

你可以这样做:(只实现getter并使用XmlAccessType.FIELD)

@XmlAccessorType(XmlAccessType.FIELD)
public class CreditCardVO implements Serializable {

  private Long ccNumber;
  private String ccName;


  public CreditCardVO(Long ccNumber, String ccName) {
   this.ccNumber = ccNumber;
   this.ccName = ccName;
  }


  private CreditCardVO() {
     // for JAXB's Magic
  }

  public Long getCcNumber() {
    return ccNumber;
  }

  public String getCcName() {
   return ccName;
  }    
}

取自http://aniketshaligram.blogspot.com/2010/05/jaxb-immutable-objects.html

答案 1 :(得分:2)

您可以将XmlAdapter与JAXB一起使用来处理不可变对象:

答案 2 :(得分:0)

简单易行:不要去那里。 Jersey / Jackson只应对值对象进行序列化/反序列化,并且没有理由使它们不可变,因为(应该)没有共享访问权限。

即。每个服务调用都应生成一个其他线程无法使用的新值对象。这样你就不必担心不变性,因此可以使用getter和setter的标准方法。

如果不给你任何东西,不要让生活变得不必要的复杂!


稍后再回来查看,我不同意这一点。 今天,我主要使用Immutables库生成值对象,它附带good support for standard JSON serialization

答案 3 :(得分:0)

如果你想要一些marshlling / unmarshilling,你可以在需要XML输出时使用JAXB,否则对于JSON,我宁愿添加一些Facades,将JSON字符串转换为Objects。

这意味着,每个线程都有自己的Facade实例,因此没有不可变性的点,如果你倾向于制作Facade单例,那么也不会出现任何问题。

使用JSON时,你可以编写自己的逻辑来创建对象,这意味着你可以使用构造函数或setter。添加到上面,然后使用Facade,您还可以在同一个外观下支持子类。

答案 4 :(得分:0)

对于它的价值,有计划(但不是现成的代码)支持反序列化的Builder样式(根据this Jira entry)。每当它实施时,取决于处理该问题的人数(或至少表达兴趣)。