2

Deserializing works fine if I just pass my custom object through

@POST
public Response saveCustomObject(CustomObject data)
{
    // Prints correct value
    System.out.println(data);
}

However, if it is a property on another object, it just gets the default value of my custom object

@POST
public Response saveCustomObjectWrapper(CustomObjectWrapper data)
{
    // Prints incorrect value
    System.out.println(data.getCustomObject());
}

My provider is registered and looks like this:

public CustomObject readFrom(Class<CustomObject> type, Type type1, Annotation[] antns, MediaType mt, MultivaluedMap<String, String> mm, InputStream in) throws IOException, WebApplicationException
{
    try {
        return new CustomObject(IOUtils.toString(in));
    } catch (Exception ex) {
        throw new ProcessingException("Error deserializing a CustomObject.", ex);
    }
}
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720

1 Answers1

1

The problem is that the reader for all other objects doesn't do lookup/delegation while unmarshalling. What I mean by that, can be seen in this answer, where one reader looks up another reader based on the type. Assuming the format is JSON, whether you're using MOXy (the default with Glassfish) or Jackson, the result is the same. The reader is smart enough to handle the the JSON by itself, so doesn't need to lookup any other readers.

One solution would be to create another reader for the wrapper class, and do lookup/delegation, as seen in the link above. If you have a lot of these situations, you may can extend the default reader, and override its unmarshalling method, but I would completely advise against this, unless you really know what you're doing.

Another solution, depending on the serializer you're using, is to write JsonDeserializer (for Jackson) or XmlAdapter (for MOXy or Jackson). For Jackson an example would be something like (you can see a better example here)

public class CustomObjectDeserializer extends JsonDeserializer<CustomObject> { 

    @Override
    public CustomObject deserialize(JsonParser jp, DeserializationContext dc) 
            throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        return new CustomObject("Hello World");
    }
}

@JsonDeserialize(using = CustomObjectDeserializer.class)
public class CustomObject {
    public String message;
    public String getMessage() { return message; }
    public void setMessage(String message) { this.message = message; }
    public CustomObject(String message) { this.message = message; }
    public CustomObject(){}
}

In which case, there is no need for a custom reader at all. This will handle CustomObjects and objects that have CustomObject as a member. One problem with this is I'm not sure how or if you can get the InputStream. You just need to use the Jackson APIs to parse the JSON.

If you want to use Jackson instead of the default MOXy for glassfish, you can just add the Jackson dependency

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.13</version>
</dependency>

Then register the JacksonFeature, or simply disable MOXy, as mentioned here. If you want to continue using MOXy, I don't know if there is such thing as a class level adapter, so you will still need the reader as well as create a XmlAdapter for class members. It's a bit of a hassle, but that's why I recommend Jackson, for many other reasons, besides this particular use case. You can see an example of an adapter here

Now a lot of this answer is based on the assumption you are using JSON format, as you haven't specified the media type you are using. If it some other format, then I think maybe your only solution is to create another customer reader for the wrapper.

Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Switching to Jackson and setting up a deserializer worked great, thanks! –  Mar 29 '15 at 19:28
  • Could you please help me this this question: https://stackoverflow.com/questions/50098794/supply-polymorphic-de-serialization-serialization-parameters-to-rest-endpoint-wi – Kishor Prakash Apr 30 '18 at 10:46