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

发布于 2024-11-15 11:34:25 字数 1916 浏览 2 评论 0原文

我有一个用java开发的简单的restful服务。我一直在研究一些编组/解组 json 的选项。可用的可能方法,jaxb jackson 等,对我来说是相当新的,我正在尝试用它们找到我的立足点。我想知道我是否可以获得一些关于什么是最好的方法和技术的建议,特别是考虑到我感兴趣的许多对象已经实现为不可变的,并且我已经使用了构建器模式。所以没有设置器,并且构造函数是私有的。

我看过之前的问题: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; }

}

编组这个对象没有问题,但解组没有问题看起来很简单。是否还支持省略空对象值的条目?

I have a simple restful service that I'm developing in java. I have been looking at a few of the options for marshalling/unmarshalling json. The possible approaches available, jaxb jackson etc, are quite new to me and I'm trying to find my feet with them. I was wondering if I could get some advice on what would be the best approach and technology to use especially given that many of the objects I'm interested in I have implemented as being immutable and I have used the builder pattern. So there are no setters and the constructor is private.

I have looked at this previous question: Jackson + Builder Pattern? posted on stackoverflow. I am considering something like this approach although it would be great to get some pointers to more resources about using @JsonDeserialize

Here is a very simple example of the type of object I'm considering

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; }

}

There are no problems marshalling this object but unmarshalling doesn't seem to be straight forward. Also is there support for leaving out entries for object values that are null?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

仅此而已 2024-11-22 11:34:25

你可以这样做:(仅实现 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

you can do this: (implement only getters and use 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;
  }    
}

taken from http://aniketshaligram.blogspot.com/2010/05/jaxb-immutable-objects.html

萌能量女王 2024-11-22 11:34:25

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

You can use an XmlAdapter with JAXB to handle immutable objects:

梦在深巷 2024-11-22 11:34:25

如果你想要一些编组/解组,当你想要 XML 输出时,你可以使用 JAXB,否则对于 JSON,我更愿意添加一些 Facade,将 JSON 字符串转换为对象。

这意味着,每个线程都会有自己的 Facade 实例,因此不会有不变性,如果您倾向于使 Facade 单例,那么也不会有任何问题。

使用 JSON 时,您可以编写自己的逻辑来创建对象,这意味着您可以使用构造函数或设置器。添加到上面,然后使用 Facade,您还可以支持子类,并且所有子类都位于同一外观下。

If u want some marshlling/unmarshilling u can use JAXB when you want an XML output, otherwise for JSON i will prefer to add some Facades, that convert the JSON String into Objects.

and that means, every thread will have its own instance of Facade, so there will be no point of immutability and if u tend to make the Facade singleton then also there won't be any problem.

When using JSON, u can write own logic to create object, means u can use constructor or setters. Adding to above, then using Facade you will also be able to support subclasses and all under the same facade.

薄情伤 2024-11-22 11:34:25

就其价值而言,有计划(但尚未准备好代码)来支持 Builder 样式的反序列化(根据 此 Jira 条目)。何时实施取决于解决该问题(或至少表达兴趣)的人数。

For what it is worth, there are plans (but not ready code) to support Builder style for deserialization (as per this Jira entry). Whenever it gets implemented depends on number of people working on the issue (or at least expressing interest).

逆流 2024-11-22 11:34:25

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

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

如果生活不能给你带来任何好处,就不要让生活变得不必要的复杂化!


很久以后再回来看,我不同意这一点。
今天,我主要使用 Immutables 库来生成值对象,它附带 对标准 JSON 序列化的良好支持

To make things simple: don't go there. Only value objects should be serialized / deserialized by Jersey / Jackson, and there is no reason to make them immutable because there is (should be) no shared access to them.

I.e. each service call should generate a new Value Object that is not available to other threads. That way you don't have to worry about immutability and hence can use the standard way with getters and setters.

Don't make life unnecessarily complicated if it doesn't buy you anything!


Checking back in much later, I disagree with this.
Today, I mostly use the Immutables library to generate value objects, and it comes with good support for standard JSON serialization.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文