0
votes

I am trying to deserialize a JSON response from Nutritionix API. When I attempt to deserialize the object I keep getting a HTTP Status 500 - Request processing failed; nested exception is java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map error. I am extremely confused and dont know why this keeps happenings because is seems that I am getting a valid JSON response but I am unsure.

public class CallSearch {

    String value;

    public CallSearch(String search){
        value = search.replace(" ", "%20");
    }
    public FullResponse search() throws ClientProtocolException, IOException{

        CloseableHttpClient client = HttpClients.createDefault();
        HttpGet getProducts = new HttpGet("https://api.nutritionix.com/v1_1/search/"+ value +"?results=0%3A6&cal_min=0&cal_max=50000&fields=item_name%2Citem_id&appId=ac23ceb3&appKey=e2b579c55b4857157fc6045d6296b532");
        CloseableHttpResponse productResponse = client.execute(getProducts);
        String entityString = EntityUtils.toString(productResponse.getEntity());
        FullResponse test = new JSONDeserializer<FullResponse>().deserialize(entityString,FullResponse.class);

        return test;
    }
}

The classes I have created to deserialize into are as follows

public class FullResponse {

    String total_hits;
    String max_score;
    List<Hits> hits;

    public FullResponse(){

    }

    public String getTotal_hits() {
        return total_hits;
    }

    public void setTotal_hits(String total_hits) {
        this.total_hits = total_hits;
    }

    public String getMax_score() {
        return max_score;
    }

    public void setMax_score(String max_score) {
        this.max_score = max_score;
    }

    public List<Hits> getHits() {
        return hits;
    }

    public void setHits(List<Hits> hits) {
        this.hits = hits;
    }

Hits Class that is a list within the full response

public class Hits {

       String _index;
       String _type;
       String _id;
       String _score;
       List<Fields> fields;

       public Hits(){

       }

        public String get_index() {
        return _index;
    }

    public void set_index(String _index) {
        this._index = _index;
    }

    public String get_type() {
        return _type;
    }

    public void set_type(String _type) {
        this._type = _type;
    }

    public String get_id() {
        return _id;
    }

    public void set_id(String _id) {
        this._id = _id;
    }

    public String get_score() {
        return _score;
    }

    public void set_score(String _score) {
        this._score = _score;
    }

    public List<Fields> getFields() {
        return fields;
    }

    public void setFields(List<Fields> fields) {
        this.fields = fields;
    }
}

And finally the Fields class:

public class Fields {

    String item_name;

    public Fields(){

    }

    public String getField(){
        return item_name;
    }
    public void setField(String name){
        item_name=name;
    }
}

Any help on where I might be going wrong would be much appreciated. Thanks

Ok I made the change and here is the the JSON response I am getting

{
"total_hits":11025,
"max_score":11.122117,
"hits":[{
"_index":"nixproductionv13",
"_type":"item",
"_id":"513fceb375b8dbbc210000e4",
"_score":11.122117,
"fields":{"item_name":"Whole Milk - 1 tbsp"}},

{"_index":"nixproductionv13",
"_type":"item",
"_id":"513fceb375b8dbbc2100017b",
"_score":10.7038355,
"fields":{"item_name":"2% Milk - 1 cup"}},

{"_index":"nixproductionv13",
"_type":"item",
"_id":"513fceb375b8dbbc210000f3",
"_score":10.7038355,
"fields":{"item_name":"1% Milk - 1 cup"}},

{"_index":"nixproductionv13",
"_type":"item",
"_id":"513fceb375b8dbbc210000fb",
"_score":10.689078,
"fields":{"item_name":"Skim Milk - 1 cup"}},

{"_index":"nixproductionv13",
"_type":"item",
"_id":"513fceb375b8dbbc210000e3",
"_score":10.65872,
"fields":{"item_name":"Whole Milk - 1 fl oz"}},

{"_index":"nixproductionv13",
"_type":"item",
"_id":"513fceb375b8dbbc2100017a",
"_score":10.392,
"fields":{"item_name":"2% Milk - 1 quart"}}]}

It is now causing a nested exception is java.lang.IllegalArgumentException: argument type mismatch

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: argument type mismatch org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778) javax.servlet.http.HttpServlet.service(HttpServlet.java:621) javax.servlet.http.HttpServlet.service(HttpServlet.java:728) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)

1
Post the full stack trace of the exception, and the JSON string.JB Nizet
Do a System.out.println(entityString) and post what it prints.Sotirios Delimanolis
Do you get a different exception? Post it if you do.Sotirios Delimanolis
Hey I really appreciate your help Sotirios, Thanks for taking time to look at this.user3080107

1 Answers

3
votes

This won't solve everything, but it will put us on the right track

String entityString = productResponse.getEntity().toString();

should be

String entityString = EntityUtils.toString(productResponse.getEntity());

The javadoc of EntityUtils.toString() states

Read the contents of an entity and return it as a String. The content is converted using the character set from the entity (if any), failing that, "ISO-8859-1" is used.

When you do

productResponse.getEntity().toString();

you are invoking the toString() method of the Object class, which ResponseEntityWrapper inherits. That simply returns the String value org.apache.http.impl.execchain.ResponseEntityWrapper@8f6b087 which is not at all the body of your HTTP response.