Unable to deserialiaze Jaxrs response entity get - java

im using below code
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
WebTarget webTarget = client.target(uri);
Builder builder = webTarget.request();
Response response = builder.accept(MediaType.APPLICATION_JSON).get(Response.class);
final List<MyResponse> accountList = response.readEntity(new GenericType<List<MyResponse>>(){});
This returns accountList but all the values inside the list Objects were **null ie(Each property value inside MyResponse object is null)
But If i use below code
String myResponse = response
.readEntity(String.class);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyResponse[] obj = mapper.readValue(myResponse, MyResponse[].class);
obj returns the proper array of Objects..but i dont want to read as string and deserialize..Please suggest!
Uri response is as follows
[
{
"type": "A1",
"attrs": {
"test_card": "Y"
}
}, {
"type": "A2"
"attrs": {
"issue_card": "N"
}
}
]
MyResponse Object
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
#JsonIgnoreProperties(ignoreUnknown = true)
public class MyResponse implements Serializable {
#JsonProperty("type")
private String Type;
#JsonProperty("attrs")
private MyAttributes myAttributes;
public MyAttributes getattrs() {
return myAttributes;
}
public void setattrs(MyAttributes myAttributes) {
this.myAttributes = myAttributes;
}
public MyResponse() {
}
public String gettype() {
return Type;
}
public void settype(String Type) {
this.Type = Type;
}
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
}
MyAttributes Object
#JsonIgnoreProperties(ignoreUnknown = true)
public class MyAttributes implements Serializable {
/**
*
*/
private static final long serialVersionUID = -4************;
#JsonProperty("test_card")
private String testCard;
public DecisionActionAttributes() {
}
public String getNewCardInd() {
return testCard;
}
public void setNewCardInd(String testCard) {
this.testCard = testCard;
}
#Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, false);
}
#Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}

Related

Not Able to Cast the Object to Custom Object

I have the APIResponse class which extends the Object class like <T extends Object> but while getting the response body from the rest template getting the data into the Object class, not to the Book class.
If I try to fetch the data into the Book class it gives the null.
I have tried typecasting the response in The Book Object but no success.
ex.ApiResponse<Book>.
public void testCreate(){
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory());
RestTemplate restTemplate = new RestTemplate(factory);
BookDto bookDto = new BookDto("Pranav","dummy","dummy");
String url = "http://localhost:9090/books";
HttpEntity<BookDto> httpEntity = getHttpEntity(bookDto);
ResponseEntity<Object> book = restTemplate.exchange(url,HttpMethod.POST,httpEntity,Object.class);
//Able to Get the response body in Object but if I try to change it to the Book the response body is coming null.
}
private HttpEntity<BookDto> getHttpEntity(BookDto bookDto) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Accept",MediaType.APPLICATION_JSON_VALUE);
return new HttpEntity<>(bookDto,headers);
}
#JsonInclude(JsonInclude.Include.NON_NULL)
public class APIResponse<T extends Object> implements Serializable {
/**
* status & message fields have not setter. They are assigned value when
* initial by APIStatus parameter
*/
private int status;
private String message;
private T data;
public APIResponse(APIStatus apiStatus, T data) {
if (apiStatus == null) {
throw new IllegalArgumentException("APIStatus must not be null");
}
this.status = apiStatus.getCode();
this.message = apiStatus.getDescription();
this.data = data;
}
public int getStatus() {
return status;
}
public String getMessage() {
return message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
public enum APIStatus {
// Common status
OK(200, null);
private final int code;
private final String description;
private APIStatus(int s, String v) {
code = s;
description = v;
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
}
#Component
public class ResponseUtil {
private APIResponse<Book> createResponse(APIStatus apiStatus, Object data) {
return new APIResponse(apiStatus, data);
}
// base method
public ResponseEntity<APIResponse<Book>> buildResponse(APIStatus apiStatus, Object data, HttpStatus httpStatus) {
return new ResponseEntity(createResponse(apiStatus, data), httpStatus);
}
public ResponseEntity<APIResponse<Book>> successResponse(Object data) {
return buildResponse(APIStatus.OK, data, HttpStatus.OK);
}
}
#RestController
public class BookController {
#Autowired
BookService bookService;
#Autowired
protected ResponseUtil responseUtil;
#GetMapping("/books")
ResponseEntity<APIResponse<Book>> read(){
return responseUtil.successResponse(bookService.findAll());
}
}
I expect the response body result into the Book Object, not to the General Object class.

Unable to parse JSON with Jackson (mapping doesn't work)

I am trying to use Jackson to parse sample json as demonstrated below. However, I the parsing doesn't work (fails without any exceptions - as I get an empty string for event.getAccountId(); What could I be doing wrong?
Thanks!
ObjectMapper om = new ObjectMapper();
String json = "{\"_procurementEvent\" : [{ \"accountId\" : \"3243234\",\"procurementType\" : \"view\"," +
"\"_procurementSubType\" : \"Standard Connector\",\"_quantity\" : \"4\", \"_pricePerMonth\" : \"100.00\"" +
",\"_annualPrice\" : \"1200.00\"}]}";
ProcurementEvent event = om.readValue(json, ProcurementEvent.class);
event.getAccountId(); // returns null
#JsonIgnoreProperties(ignoreUnknown = true)
private static class ProcurementEvent {
private String _accountId;
private String _procurementType;
private String _quantity;
private String _pricePerMonth;
private String _annualPrice;
#JsonProperty("accountId")
public String getAccountId() {
return _accountId;
}
public void setAccountId(String accountId) {
_accountId = accountId;
}
#JsonProperty("procurementType")
public String getProcurementType() {
return _procurementType;
}
public void setProcurementType(String procurementType) {
_procurementType = procurementType;
}
#JsonProperty("_quantity")
public String getQuantity() {
return _quantity;
}
public void setQuantity(String quantity) {
_quantity = quantity;
}
#JsonProperty("_pricePerMonth")
public String getPricePerMonth() {
return _pricePerMonth;
}
public void setPricePerMonth(String pricePerMonth) {
_pricePerMonth = pricePerMonth;
}
#JsonProperty("_annualPrice")
public String getAnnualPrice() {
return _annualPrice;
}
public void setAnnualPrice(String annualPrice) {
_annualPrice = annualPrice;
}
}
In the question, try the following approach:
class ProcurementEvents {
private List<ProcurementEvent> _procurementEvent; // + annotations like #JsonIgnoreProperties, getters/ setters, etc.
}
// json from your example
ProcurementEvents events = om.readValue(json, ProcurementEvents.class);
events.get(0).getAccountId();

Java.net(RestFul service JSON reponse parsing issue) How to convert list of same item in JSON reponse String to Java Object?

I am calling Restful service using below code :(Java.net implementation )
StringBuilder responseStrBuilder = new StringBuilder();
try
{
URL url = new URL(restUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(httpRequestMethod);
conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
conn.setRequestProperty("Content-Type", "application/json");
if (requestHeaders != null)
{
for (Map.Entry<String, String> entry : requestHeaders.entrySet())
{
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
}
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
os.write(urlParameters.getBytes());
os.flush();
os.close();
if (conn.getResponseCode() != 200) {//do something}
br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
while ((output = br.readLine()) != null)
responseStrBuilder.append(output);
Approach 1:
I have below string(JSON String) as my Restful service response , how can I convert it to Java object. Since same(Itm) object is repeated multiple times if I use org.codehaus.jettison.json.JSONObject myObject = new org.codehaus.jettison.json.JSONObject(responseStrBuilder.toString());
It only reads first Itm Object and does not bring list of all item object.
JSON String output from service :
{"Response":{"RID":"04'34'",
"Itm":{"id":{"ab":"1","cd":"12"},"qw":"JK","name":"abcd "},
"Itm":{"id":{"ab":"2","cd":"34},"qw":"JK","name":"asdf "},
"Itm":{"id":{"ab":"3","cd":"12"},"qw":"JK","name":"fghj "}
}}
Approach 2:
I also tried below snippet with correct Java object with setters and getters
ObjectMapper objectMapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyJavaReponseObject javaObj = mapper.readValue(json, MyJavaReponseObject.class);
This approach also reads only one object of Itm and not all the object as its not coming in array format in JSON string. Is there any better way of getting all the object(Itm) mapped to single List of Object in java pojo ?
You can use the List class in your response object, if you should parse that json string itself.
I have a ReponseJSON class with json objects, one Response and three Itms
static class ReponseJSON {
private Response Response;
#JsonProperty("Response")
public Response getResponse() {
return Response;
}
public void setResponse(Response Response) {
this.Response = Response;
}
static class Response {
private String rid;
private Itm Itm;
private List<Itm> listItm = new ArrayList<Itm>();
public Itm getItm() {
return Itm;
}
#JsonProperty("Itm")
public void setItm(Itm Itm) {
this.Itm = Itm;
listItm.add(Itm);
}
public String getRID() {
return rid;
}
public List<Itm> getItms() {
return listItm;
}
#JsonProperty("RID")
public void setRID(String rid) {
this.rid = rid;
}
static class Itm {
private Id id;
private String qw, name;
public String getQw() {
return qw;
}
public void setQw(String qw) {
this.qw = qw;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Id getId() {
return id;
}
public void setId(Id id) {
this.id = id;
}
static class Id {
private String ab, cd;
public String getCd() {
return cd;
}
public void setCd(String cd) {
this.cd = cd;
}
public String getAb() {
return ab;
}
public void setAb(String ab) {
this.ab = ab;
}
}
}
}
}
In a Response class, I have a list class and save a Itm object whenever object mapper call this class.
static class Response {
... skip ..
private List<Itm> listItm = new ArrayList<Itm>();
... skip ..
#JsonProperty("Itm")
public void setItm(Itm Itm) {
this.Itm = Itm;
listItm.add(Itm);
}
}
Check the full source code as follows.
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonParserTest {
static class ReponseJSON {
private Response Response;
#JsonProperty("Response")
public Response getResponse() {
return Response;
}
public void setResponse(Response Response) {
this.Response = Response;
}
static class Response {
private String rid;
private Itm Itm;
private List<Itm> listItm = new ArrayList<Itm>();
public Itm getItm() {
return Itm;
}
#JsonProperty("Itm")
public void setItm(Itm Itm) {
this.Itm = Itm;
listItm.add(Itm);
}
public String getRID() {
return rid;
}
public List<Itm> getItms() {
return listItm;
}
#JsonProperty("RID")
public void setRID(String rid) {
this.rid = rid;
}
static class Itm {
private Id id;
private String qw, name;
public String getQw() {
return qw;
}
public void setQw(String qw) {
this.qw = qw;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Id getId() {
return id;
}
public void setId(Id id) {
this.id = id;
}
static class Id {
private String ab, cd;
public String getCd() {
return cd;
}
public void setCd(String cd) {
this.cd = cd;
}
public String getAb() {
return ab;
}
public void setAb(String ab) {
this.ab = ab;
}
}
}
}
}
public static void main(String[] args) {
String responseJson =
"{\"Response\":{\"RID\":\"04'34'\","
+ "\"Itm\":{\"id\":{\"ab\":\"1\",\"cd\":\"12\"},\"qw\":\"JK\",\"name\":\"abcd\"}"
+ ",\"Itm\":{\"id\":{\"ab\":\"2\",\"cd\":\"34\"},\"qw\":\"JK\",\"name\":\"asdf\"}"
+ ",\"Itm\":{\"id\":{\"ab\":\"3\",\"cd\":\"12\"},\"qw\":\"JK\",\"name\":\"fghj\"}"
+ "}} ";
ObjectMapper mapper = new ObjectMapper();
ReponseJSON responseObj = null;
try {
responseObj = mapper.readValue(responseJson, ReponseJSON.class);
ReponseJSON.Response response = responseObj.getResponse();
for(int i = 0; i < response.getItms().size(); i++)
{
ReponseJSON.Response.Itm item = response.getItms().get(i);
System.out.println(item.getId().getAb());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
The version of my jackson mapper is 2.9.1.
You check the main method of the source, because the JSON string you prepared is invalid as coddemonkey mentioned.
Have a good day.
Make your json response looks something similar to this
{"Response":{"RID":"04'34'",
"Itms":[{"id":{"ab":"1","cd":"12"},"qw":"JK","name":"abcd "},
{"id":{"ab":"2","cd":"34"},"qw":"JK","name":"asdf "},
{"id":{"ab":"3","cd":"12"},"qw":"JK","name":"fghj "}]
}}
then, use org.json jar to parse the string to jsonObject
JSONObject jsonObject=new JSONObject(responseString);
This is one type of solution, if you can't change the response as mentioned above then you have to manually parse the string(using java bean) there is no other option available.

Consuming a third party RESTful API passing a parameter

I need to consume a third party RESTful API. This is my controller class:
#Controller
public class BrokerController {
#RequestMapping(value = "/broker", method = RequestMethod.POST)
public #ResponseBody MyPojo brokers(#RequestBody BrokerRequest brokerRequest){
RestTemplate restTemplate = new RestTemplate();
final String uri = "http://www.nepalipaisa.com/Modules/MarketMovers/Services/MarketMoversServices.asmx/GetTopBrokers";
MyPojo myPojo = restTemplate.postForObject(uri,brokerRequest,MyPojo.class);
return myPojo;
}
}
Edited:- My pojo class:
public class MyPojo {
private String __type;
private Integer RowTotal;
private Integer StockID;
private Object CodedCompany;
private Object ClosingPrice;
private Integer Amount;
private Integer PreviousClosing;
private Integer DifferenceRS;
private Object Symbol;
private Integer Price;
private Integer Diff;
private Integer PercentageDiff;
private Object Volume;
private Integer TotalTurnOverAmount;
private String FirmName;
private Integer BrokerID;
private String BrokerCode;
private Integer TotalTransactions;
private Object Traded;
private Object MaxPrice;
private Object MinPrice;
private Object OpeningPrice;
private Object TotalShare;
private Integer NoOfTransaction;
private Integer Purchase;
private Integer Sales;
private Integer Matching;
public String get__type() {
return __type;
}
public void set__type(String __type) {
this.__type = __type;
}
public Integer getRowTotal() {
return RowTotal;
}
public void setRowTotal(Integer rowTotal) {
this.RowTotal = rowTotal;
}
public Integer getStockID() {
return StockID;
}
public void setStockID(Integer stockID) {
this.StockID = stockID;
}
public Object getCodedCompany() {
return CodedCompany;
}
public void setCodedCompany(Object codedCompany) {
this.CodedCompany = codedCompany;
}
public Object getClosingPrice() {
return ClosingPrice;
}
public void setClosingPrice(Object closingPrice) {
this.ClosingPrice = closingPrice;
}
public Integer getAmount() {
return Amount;
}
public void setAmount(Integer amount) {
this.Amount = amount;
}
public Integer getPreviousClosing() {
return PreviousClosing;
}
public void setPreviousClosing(Integer previousClosing) {
this.PreviousClosing = previousClosing;
}
public Integer getDifferenceRS() {
return DifferenceRS;
}
public void setDifferenceRS(Integer differenceRS) {
this.DifferenceRS = differenceRS;
}
public Object getSymbol() {
return Symbol;
}
public void setSymbol(Object symbol) {
this.Symbol = symbol;
}
public Integer getPrice() {
return Price;
}
public void setPrice(Integer price) {
this.Price = price;
}
public Integer getDiff() {
return Diff;
}
public void setDiff(Integer diff) {
this.Diff = diff;
}
public Integer getPercentageDiff() {
return PercentageDiff;
}
public void setPercentageDiff(Integer percentageDiff) {
this.PercentageDiff = percentageDiff;
}
public Object getVolume() {
return Volume;
}
public void setVolume(Object volume) {
this.Volume = volume;
}
public Integer getTotalTurnOverAmount() {
return TotalTurnOverAmount;
}
public void setTotalTurnOverAmount(Integer totalTurnOverAmount) {
this.TotalTurnOverAmount = totalTurnOverAmount;
}
public String getFirmName() {
return FirmName;
}
public void setFirmName(String firmName) {
this.FirmName = firmName;
}
public Integer getBrokerID() {
return BrokerID;
}
public void setBrokerID(Integer brokerID) {
this.BrokerID = brokerID;
}
public String getBrokerCode() {
return BrokerCode;
}
public void setBrokerCode(String brokerCode) {
this.BrokerCode = brokerCode;
}
public Integer getTotalTransactions() {
return TotalTransactions;
}
public void setTotalTransactions(Integer totalTransactions) {
this.TotalTransactions = totalTransactions;
}
public Object getTraded() {
return Traded;
}
public void setTraded(Object traded) {
this.Traded = traded;
}
public Object getMaxPrice() {
return MaxPrice;
}
public void setMaxPrice(Object maxPrice) {
this.MaxPrice = maxPrice;
}
public Object getMinPrice() {
return MinPrice;
}
public void setMinPrice(Object minPrice) {
this.MinPrice = minPrice;
}
public Object getOpeningPrice() {
return OpeningPrice;
}
public void setOpeningPrice(Object openingPrice) {
this.OpeningPrice = openingPrice;
}
public Object getTotalShare() {
return TotalShare;
}
public void setTotalShare(Object totalShare) {
this.TotalShare = totalShare;
}
public Integer getNoOfTransaction() {
return NoOfTransaction;
}
public void setNoOfTransaction(Integer noOfTransaction) {
this.NoOfTransaction = noOfTransaction;
}
public Integer getPurchase() {
return Purchase;
}
public void setPurchase(Integer purchase) {
this.Purchase = purchase;
}
public Integer getSales() {
return Sales;
}
public void setSales(Integer sales) {
this.Sales = sales;
}
public Integer getMatching() {
return Matching;
}
public void setMatching(Integer matching) {
this.Matching = matching;
}
}
The JSON iI need to consume, i.e the exact result given below:
{
"d": [
{
"__type": "SageFrame.MarketMovers.MarketInfo",
"RowTotal": 0,
"StockID": 0,
"CodedCompany": null,
"ClosingPrice": null,
"Amount": 0,
"PreviousClosing": 0,
"DifferenceRS": 0,
"Symbol": null,
"Price": 0,
"Diff": 0,
"PercentageDiff": 0,
"Volume": null,
"TotalTurnOverAmount": 109969058,
"FirmName": "Vision Securities Pvt. Ltd.",
"BrokerID": 0,
"BrokerCode": "34",
"TotalTransactions": 0,
"Traded": null,
"MaxPrice": null,
"MinPrice": null,
"OpeningPrice": null,
"TotalShare": null,
"NoOfTransaction": 0,
"Purchase": 70691939,
"Sales": 39277119,
"Matching": 6381555
},
{
"__type": "SageFrame.MarketMovers.MarketInfo",
"RowTotal": 0,
"StockID": 0,
"CodedCompany": null,
"ClosingPrice": null,
"Amount": 0,
"PreviousClosing": 0,
"DifferenceRS": 0,
"Symbol": null,
"Price": 0,
"Diff": 0,
"PercentageDiff": 0,
"Volume": null,
"TotalTurnOverAmount": 104830489,
"FirmName": "Online Securities Pvt. Ltd.",
"BrokerID": 0,
"BrokerCode": "49",
"TotalTransactions": 0,
"Traded": null,
"MaxPrice": null,
"MinPrice": null,
"OpeningPrice": null,
"TotalShare": null,
"NoOfTransaction": 0,
"Purchase": 51927902,
"Sales": 52902587,
"Matching": 3049044
}
]
}
Currently when I send a POST request with two parameters
{
"offset":"1",
"limit":"2000"
}
I can get the result given above. Now I need to return the same result but through my own controller. The above controller returns MyPojo class with null value on every properties.
You can always try to put the results from the third party API into a Map.
Map results = restTemplate.postForObject(uri,brokerRequest, Map.class);
Or you can create a new pojo just for that third part API.
ThirdPartyPojo results = restTemplate.postForObject(uri,brokerRequest, ThirdPartyPojo.class);
Right now the issue is that your pojo MyPojo is not compatible with the response of 3rd party API.
Your pojo should be something like following.
-----------------------------------com.example.D.java-----------------------------------
package com.example;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
public class D {
private String type;
private Integer rowTotal;
private Integer stockID;
private Object codedCompany;
private Object closingPrice;
private Integer amount;
private Integer previousClosing;
private Integer differenceRS;
private Object symbol;
private Integer price;
private Integer diff;
private Integer percentageDiff;
private Object volume;
private Integer totalTurnOverAmount;
private String firmName;
private Integer brokerID;
private String brokerCode;
private Integer totalTransactions;
private Object traded;
private Object maxPrice;
private Object minPrice;
private Object openingPrice;
private Object totalShare;
private Integer noOfTransaction;
private Integer purchase;
private Integer sales;
private Integer matching;
// Getter .. Setter//
}
-----------------------------------com.example.MyPojo.java-----------------------------------
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
public class Example {
#JsonProperty("d")
private List<D> d = null;
// Getter ... Setter
}
Or simply you can use Map.
This can be accomplished easily not even requiring you to provide custom mappings or whatever like that and guarantee that your controller wil provide the same response (not the same headers, though):
#RestController
final class Controller {
// Both RestTemplate and URI instances can be cached
private static final RestTemplate restTemplate = new RestTemplate();
private static final URI testUri = URI.create("http://www.nepalipaisa.com/Modules/MarketMovers/Services/MarketMoversServices.asmx/GetTopBrokers");
// I'm using GET just to simplify the testing using a web browser
#RequestMapping(method = GET, value = "/")
public void post(final ServletResponse response)
throws IOException {
// Create a POST request entity
final RequestEntity<?> requestEntity = new RequestEntity<>(getRequest(0, 10), POST, testUri);
// And send the request to the remote server
final ResponseEntity<Resource> responseEntity = restTemplate.exchange(requestEntity, Resource.class);
// Now just copy the response input stream to the output stream of this controller
try ( final InputStream inputStream = responseEntity.getBody().getInputStream() ) {
// Or provide HttpServletResponse via the controller method to be able to configure the response more accurately
StreamUtils.copy(inputStream, response.getOutputStream());
}
}
private static Object getRequest(final long offset, final long limit) {
final Map<String, Object> request = new HashMap<>();
request.put("offset", offset);
request.put("limit", limit);
return request;
}
}
The remote server can respond with a non-successful response code, so you can also have a custom controller advice to handle RestTemplate exceptions:
#ControllerAdvice
final class ExceptionControllerAdvice {
#ExceptionHandler(HttpServerErrorException.class)
#ResponseBody
public ResponseEntity<?> handleHttpServerErrorException(final HttpServerErrorException ex) {
return new ResponseEntity<Object>("Bad gateway: " + ex.getMessage(), BAD_GATEWAY);
}
}

Failed to bind JSON response to GSON annotated POJO

I intended to bind a JSON string to POJO annotated with GSON, the JSON response is from the ReSTFUL service to list all countries: http://services.groupkt.com/country/get/all
the response is fine, which looks like
{
"RestResponse": {
"messages": [
"More webservices are available at http://www.groupkt.com/post/f2129b88/services.htm",
"Total [249] records found."
],
"result": [
{
"name": "Afghanistan",
"alpha2_code": "AF",
"alpha3_code": "AFG"
},
{
"name": "Ă…land Islands",
"alpha2_code": "AX",
"alpha3_code": "ALA"
},
...
]
}
}
The POJO Country and its associated classes were created using this tool:http://www.jsonschema2pojo.org/ and they look like:
Country.java
public class Country implements Serializable{
#SerializedName("RestResponse")
#Expose
private RestResponse restResponse;
public RestResponse getRestResponse() {
return restResponse;
}
public void setRestResponse(RestResponse restResponse) {
this.restResponse = restResponse;
}
}
RestResponse.java
public class RestResponse implements Serializable{
#SerializedName("messages")
#Expose
private List<String> messages = null;
#SerializedName("result")
#Expose
private List<Result> result = null;
public List<String> getMessages() {
return messages;
}
public void setMessages(List<String> messages) {
this.messages = messages;
}
public List<Result> getResult() {
return result;
}
public void setResult(List<Result> result) {
this.result = result;
}
}
Result.java
public class Result implements Serializable{
#SerializedName("name")
#Expose
private String name;
#SerializedName("alpha2_code")
#Expose
private String alpha2Code;
#SerializedName("alpha3_code")
#Expose
private String alpha3Code;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAlpha2Code() {
return alpha2Code;
}
public void setAlpha2Code(String alpha2Code) {
this.alpha2Code = alpha2Code;
}
public String getAlpha3Code() {
return alpha3Code;
}
public void setAlpha3Code(String alpha3Code) {
this.alpha3Code = alpha3Code;
}
}
The code below however failed to bind the JSON string to the GSON annotated POJOs - the restResponse is NULL, so are the message and result. Can anyone tell me what went wrong?
#SpringBootApplication
public class App implements CommandLineRunner
{
private static Logger log = LoggerFactory.getLogger(App.class);
/*
* boiler plate code
* */
public static void main( String[] args )
{
SpringApplication.run(App.class, args);
}
/*
* Configuration section
* */
#Bean
public RestTemplate newRestTemplate(){
RestTemplate rt = new RestTemplate();
return rt;
}
/*
* public APIs section
* */
#Autowired
private RestTemplate restTemplate;
#Override
public void run(String... args) throws Exception {
String url = "http://services.groupkt.com/country/get/all";
ResponseEntity<String> res = restTemplate.getForEntity(url, String.class);
log.info("{}",res.getBody());
GsonHttpMessageConverter msgConverter = new GsonHttpMessageConverter();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
msgConverter.setGson(gson);
restTemplate.getMessageConverters().add(msgConverter);
Country country = restTemplate.getForObject(url, Country.class);
RestResponse resp = country.getRestResponse();
List<Result> l = resp.getResult();
for(Result r : l){
log.info("country name = {}",r.getName());
}
}
}
I managed to update the code like below and it works now:
RestTemplate rt = new RestTemplate();
String url = "http://services.groupkt.com/country/get/all";
ResponseEntity<String> resp = rt.getForEntity(url, String.class);
assertEquals(resp.getStatusCode(), HttpStatus.OK);
Gson gson = new GsonBuilder().create();
Country c = gson.fromJson(resp.getBody(), Country.class);
still don't know why the code below didn't work, though.
Country country = restTemplate.getForObject(url, Country.class);

Categories

Resources