Search code examples
javajsonrestresteasy

Handle JSON Response that comes without 'root' element with RestEasy


I invoke some web service (constructed in Ruby) and get JSON response like this:

{
    "error_code": "02",
    "message": "Param not valid",
    "field_name": "title"
}

To model that response object in Java I try with:

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "response")
public class Response {
    
    private String error_code;
    private String message;
    private String field_name;
    
    public String getError_code() {
        return error_code;
    }
    public void setError_code(String error_code) {
        this.error_code = error_code;
    }
    
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    
    public String getField_name() {
        return field_name;
    }
    public void setField_name(String field_name) {
        this.field_name = field_name;
    }
            
}

... and to read the response of a WS invocation in my WS Client I try:

Response response = responseWs.readEntity(Response.class);

... but I get following exception:

org.jboss.resteasy.plugins.providers.jaxb.JAXBUnmarshalException: javax.xml.bind.UnmarshalException 
 - with linked exception: 
[com.sun.istack.internal.SAXParseException2; columnNumber: 0 unexpected element ... Expected elements are

That is because my code is trying to handle JSON response object like this (with some 'root' element):

{
    "response":
    {
        "error_code": "02",
        "message": "Param not valid",
        "field_name": "title"
    }       
}

Does somebody knows how can I solve this situation, on my side?

Thanks


Solution

  • For me, this snippet solves the issue:

    String responseAsString = responseWs.readEntity(String.class);
    ObjectMapper mapper = new ObjectMapper();
    JsonNode pathNode = mapper.readTree(responseAsString);
    Response response = mapper.convertValue(pathNode, Response.class);