8

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?

Community
  • 1
  • 1
Conor
  • 775
  • 3
  • 10
  • 23
  • thanks guys, I really appreciated all the responses. I guess I'll probably look at using either XmlAdapter for JaxB as @Blaise suggested or the @JsonDeserialize equivalent for Jackson. Some other approaches for dealing with immutable objects with the Jackson framework are also discussed on the [CowTalk blog](http://www.cowtowncoder.com/blog/archives/2010/08/entry_409.html) which might be worth a look if you run into slightly different issues to do with immutable objects – Conor Jun 15 '11 at 12:30

5 Answers5

6

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

ekeren
  • 3,408
  • 3
  • 35
  • 55
2

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

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • Thanks Blaise, that is a really nicely written blog entry. I'll have a look at taking that approach and see how I get on. – Conor Jun 14 '11 at 12:57
0

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.

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • Thanks for you quick reply Sean. I went with an immutable objects because my service provides access to algorithms that can run in a threaded form. The objects can also act as keys in maps too. – Conor Jun 14 '11 at 12:10
  • sorry I meant to write the following- Thanks for you quick reply Sean. I went with the use of immutable objects because my service provides access to algorithms that can run in a threaded form. The objects can also act as keys in maps too. I think you are right, I'm probably making things unnecessarily complex and at the very least I should look at maybe using intermediate objects for marshalling/unsmarshalling data – Conor Jun 14 '11 at 12:17
  • @Conor all of that makes sense, for your service's internal workings. But in the web service layer there should not be concurrent access to the Objects. You can still use them as map keys, because web service frameworks won't change them, but you can't design them as immutable objects – Sean Patrick Floyd Jun 14 '11 at 12:24
  • Or, if you absolutely want to go with this usage, use [@XmlAccessorType(FIELD)](http://download.oracle.com/javaee/6/api/javax/xml/bind/annotation/XmlAccessorType.html) – Sean Patrick Floyd Jun 14 '11 at 12:26
  • Thanks again for your help Sean. Between your and Blaise's advice I think I should be able to get cracking on this. I think I'll try using the XmlAdapter to handle the marshalling/unmarshalling – Conor Jun 14 '11 at 13:00
0

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.

M.J.
  • 16,266
  • 28
  • 75
  • 97
0

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).

StaxMan
  • 113,358
  • 34
  • 211
  • 239