0

I have a simple Spring Boot project in which a scheduler periodically consumes a RESTful API and converts the incoming JSON file.

The JSON file is actually an array of Objects with some Keys and Values:

[
{"CoID":1,"CoName":"کشاورزی و دامپروری مگسال","CoNameEnglish":"MagsalAgriculture & Animal Husbandry Co.","CompanySymbol":"MAGS","CoTSESymbol":"زمگسا","GroupID":1,"GroupName":"كشاورزی و دامپروری","IndustryID":1,"IndustryName":"كشاورزی، دامپروری و خدمات وابسته به آن","InstCode":"5054819322815158","TseCIsinCode":"IRO1MAGS0006","TseSIsinCode":"IRO1MAGS0001","MarketID":1,"MarketName":"بورس"},
{"CoID":2,"CoName":"ذغالسنگ نگین طبس","CoNameEnglish":"Negin Tabas Lignite Co.","CompanySymbol":"TBAS","CoTSESymbol":"کطبس","GroupID":2,"GroupName":"استخراج و انبار ذغال سنگ سخت","IndustryID":2,"IndustryName":"استخراج ذغال سنگ","InstCode":"8977369674477111","TseCIsinCode":"IRO1TBAS0004","TseSIsinCode":"IRO1TBAS0001","MarketID":1,"MarketName":"بورس"},{"CoID":3,"CoName":"معدنی و صنعتی چادرملو","CoNameEnglish":"Chadormalu Mining & Industrial Co.","CompanySymbol":"CHML","CoTSESymbol":"کچاد","GroupID":3,"GroupName":"استخراج سنگ معدن های فلزی آهنی","IndustryID":3,"IndustryName":"استخراج كانه های فلزی","InstCode":"18027801615184692","TseCIsinCode":"IRO1CHML0000","TseSIsinCode":"IRO1CHML0001","MarketID":1,"MarketName":"بورس"}
...
]

I have a class called Company with similar fields to one of objects in the array within the JSON file:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Company {

private int CoID;
private String CoName;
private String CoNameEnglish;
private String CompanySymbl;
private String CoTSESymbl;
private int GroupID;
private String GroupName;
private int IndustryID;
private String IndustryName;
private String IndustryCode;
private String TseCIsinCode;
private String TseSIsinCode;
private int MarketID;
private String MarketName;
    // And proper getters, setters and constructor //

I also created a wrapping class called CompanyList:

public class CompanyList {

private ArrayList<Company> companyList;

public ArrayList<Company> getCompanyList() {
    return companyList;
}

public void setCompanyList(ArrayList<Company> companyList) {
    this.companyList = companyList;
}

public CompanyList() {

}

@Override
public String toString() {
    return "CompanyList [companyList=" + companyList + "]";
}

}

I have tried three different ways to fulfill this requirement:

First:

Object[] forNow = restTemplate.getForObject("somewhere", Object[].class);
List<Object> cp= Arrays.asList(forNow);

This one works properly.

Second:

    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<List<Company>> response = restTemplate.exchange(
      "somewhere",
      HttpMethod.GET,
      null,
      new ParameterizedTypeReference<List<Company>>(){});
    List<Company> companies = response.getBody();

    log.info(companies.toString());

This one is compiled successfully but returns null and 0 in all fields.

Third:

    CompanyList cp = restTemplate.getForObject("somewhere", CompanyList.class);
    log.info(cp.getCompanyList().toString());

This one raises an exception:

Error while extracting response for type [class ir.pisys.rest.CompanyList] and content type [application/json;charset=utf-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of ir.pisys.rest.CompanyList out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of ir.pisys.rest.CompanyList out of START_ARRAY token

So I have some questions here:

1- Is the first approach an optimized one? (Compared to others)

2- How can I fix the two other approaches?

4
  • 1. You never showed your API function or repository. 2. When your API function successfully returns Object[].class why would you expect it to return CompanyList.class ? Commented Sep 10, 2019 at 5:27
  • @Iman H Please replace your api URLs seems like they are public. Does Company has toString? As the rest API response is array/list(assume from 1) getCompanyList method in the ComapnyList should annotate with @JsonGetter("list") Commented Sep 10, 2019 at 5:40
  • @mallikarjun Yes it has toString. I added the noticed annotation but the following exception raises: content type [application/json;charset=utf-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of ir.pisys.rest.CompanyList out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of ir.pisys.rest.CompanyList out of START_ARRAY token at [Source: (PushbackInputStream); line: 1, column: 1] Commented Sep 10, 2019 at 5:59
  • your second approach is wrong. You are missing basic syntax. Commented Sep 10, 2019 at 6:04

1 Answer 1

1

The second and third approaches should work fine. You need to check your json response structure.

You could use following jsons for tests (they work with your code):

Second approach:

[{"tseCIsinCode":null,"tseSIsinCode":null,"coName":"n1","industryID":0,"coID":0,"coNameEnglish":null,"companySymbl":null,"coTSESymbl":null,"groupID":0,"groupName":null,"industryName":null,"industryCode":null,"marketID":0,"marketName":null},{"tseCIsinCode":null,"tseSIsinCode":null,"coName":"n2","industryID":0,"coID":0,"coNameEnglish":null,"companySymbl":null,"coTSESymbl":null,"groupID":0,"groupName":null,"industryName":null,"industryCode":null,"marketID":0,"marketName":null}]

Third:

{"companyList":[{"coName":"n1","coID":0,"coNameEnglish":null,"companySymbl":null,"coTSESymbl":null,"groupID":0,"groupName":null,"industryID":0,"industryName":null,"industryCode":null,"tseCIsinCode":null,"tseSIsinCode":null,"marketID":0,"marketName":null},{"coName":"n2","coID":0,"coNameEnglish":null,"companySymbl":null,"coTSESymbl":null,"groupID":0,"groupName":null,"industryID":0,"industryName":null,"industryCode":null,"tseCIsinCode":null,"tseSIsinCode":null,"marketID":0,"marketName":null}]}

Update:

Second approach fix: Change your json fields name - "CoName" -> "coName", "CoID" -> "coID" and so on. After that changes it will work pirfectly.

Third approach fix: Wrap your json with "{\"companyList\":[...] And change fields name as for second approach

Second Update If you can't change json from response. You could use mapping in your Company class

@JsonProperty("CoName")
private String CoName;
Sign up to request clarification or add additional context in comments.

2 Comments

thanks. my JSON structure is as the first one you provided.
Glad to help you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.