Map json using Jackson

Asked

Viewed 978 times

1

I have a question on how to map a json to a model, I really have no idea which way to go, I saw some material on the internet, but what I really lack is to really understand how this works there in the part of Jackson. my code goes below, who can help.

Zenviarequest

@JsonIgnoreProperties(ignoreUnknown = true)
public class ZenviaRequest {

@JsonProperty("id")
private String id;
@JsonProperty("from")
private String from;
@JsonProperty("to")
private String to;
@JsonProperty("msg")
private String msg;
@JsonProperty("schedule")
private String schedule;
@JsonProperty("callbackOption")
private String callbackOption;
@JsonProperty("aggregateId")
private String aggregateId;
@JsonProperty("flashSms")
private boolean flashSms;

//todos os getters and setters
}

Zenviaresponse

@JsonIgnoreProperties(ignoreUnknown = true)
public class ZenviaResponse {

    @JsonProperty("statusCode")
    private String statusCode;
    @JsonProperty("statusDescription")
    private String statusDescription;
    @JsonProperty("detailCode")
    private String detailCode;
    @JsonProperty("detailDescription")
    private String detailDescription;
    @JsonProperty("mobileOperatorName")
    private String mobileOperatorName;
    @JsonProperty("received")
    private String received;

    //todos os getters and setters
    }

My call

public void senderMulti(List<ZenviaRequest> zenvia) {

   //pego a lista que recebi e faço aqui toda lógica para gerar uma String Full

    Response response = null;
    try {

        Client client = ClientBuilder.newClient();
        Entity payload = Entity.json(full); // <-----

        response = client.target("https://api-rest.zenvia360.com.br/services/send-sms-multiple")
                .request(MediaType.APPLICATION_JSON_TYPE)
                .header("Authorization", "Basic ***************")
                .header("Accept", "application/json")
                .post(payload);

        System.out.println("status: " + response.getStatus());
        System.out.println("headers: " + response.getHeaders());
        System.out.println("body:" + response.readEntity(String.class));

        // aqui meu codigo desanda, não sei oque fazer aqui
        ObjectMapper mapper = new ObjectMapper();
        String jsonInString = response.readEntity(String.class);

        List<ZenviaResponse> objList = mapper.readValue(jsonInString, new TypeReference<List<ZenviaResponse>>(){});

        response.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

The return of the Json

status: 200
headers: {Server=[Jetty(9.2.9.v20150224)], Connection=[close], Date=[Tue, 17 Apr 2018 00:01:51 GMT], Content-Type=[application/json]}
body:{
  "sendSmsMultiResponse" : {
"sendSmsResponseList" : [ {
  "statusCode" : "10",
  "statusDescription" : "Error",
  "detailCode" : "080",
  "detailDescription" : "Message with same ID already sent"
}, {
  "statusCode" : "10",
  "statusDescription" : "Error",
  "detailCode" : "080",
  "detailDescription" : "Message with same ID already sent"
}, {
  "statusCode" : "10",
  "statusDescription" : "Error",
  "detailCode" : "080",
  "detailDescription" : "Message with same ID already sent"
} ]
  }
}

it comes all beautiful there, but how to consume it for a List of Zenviaresponse, if anyone can help me thank you very much.

trying with this code now I get this error below.

java.lang.IllegalStateException: Entity input stream has already been closed.
    at org.glassfish.jersey.message.internal.EntityInputStream.ensureNotClosed(EntityInputStream.java:225)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:832)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:785)
    at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:267)
    at org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:111)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:397)
    at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:108)
    at br.com.trendplataform.rotas.ZenviaSender.senderMulti(ZenviaSender.java:122)
    at testando.main(testando.java:52)

1 answer

0


The method readEntity(Class<T> entityType) can only be used once per response, since when it is executed, the input stream is consumed and the connection is closed (if the response is read as a input stream, it should be closed so that the connection is also).

In its code, it is being evoked twice in the following excerpts:

System.out.println("body:" + response.readEntity(String.class));

And:

String jsonInString = response.readEntity(String.class);

To prevent the exception from occurring, reverse the order of the lines above and pass the variable jsonInString as an argument for the method println:

String jsonInString = response.readEntity(String.class);
System.out.println("body: " + jsonInString);

As for the mapping use, you need to make your class match the JSON format. Then you should have the following classes:

Sendsmsmultiresponse:

public class SendSmsMultiResponse {

    @JsonProperty("sendSmsMultiResponse")
    private SendSmsMultiResponseList sendSmsMultiResponse;

    //getters e setters
}

Sendsmsmultiresponselist:

public class SendSmsMultiResponseList {

    @JsonProperty("sendSmsResponseList")
    private List<SendSmsResponse> sendSmsResponseList;

    //getters e setters
}

Sendsmsresponse:

public class SendSmsResponse {

    @JsonProperty("statusCode")
    private String statusCode;
    @JsonProperty("statusDescription")
    private String statusDescription;
    @JsonProperty("detailCode")
    private String detailCode;
    @JsonProperty("detailDescription")
    private String detailDescription;

    //getters e setters
}

And to deserialize the JSON:

ObjectMapper mapper = new ObjectMapper();
SendSmsMultiResponse sendSmsMultiResponse = mapper.readValue(jsonInString, SendSmsMultiResponse.class);

Obs: Jackson can be integrated into Jersey using dependency jersey-media-json-jackson (which must be in the same version of Jersey used), no additional configuration is required. If you add it, you could read the entity directly from the reply in this way:

response.readEntity(SendSmsMultiResponse.class);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.