反序列化问题

Posted

技术标签:

【中文标题】反序列化问题【英文标题】:Deserialize Issue 【发布时间】:2013-12-25 16:47:08 【问题描述】:

我正在尝试反序列化来自 Nutritionix API 的 JSON 响应。当我尝试反序列化对象时,我不断收到 HTTP 状态 500 - 请求处理失败;嵌套异常是 java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map 错误。我非常困惑,不知道为什么会这样,因为我似乎得到了一个有效的 JSON 响应,但我不确定。

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;
    

我创建的要反序列化的类如下

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 是完整响应中的列表

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;
    

最后是 Fields 类:

public class Fields 

    String item_name;

    public Fields()

    

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

任何关于我可能出错的地方的帮助将不胜感激。谢谢

好的,我进行了更改,这是我得到的 JSON 响应


"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"]

现在导致嵌套异常是 java.lang.IllegalArgumentException: argument type mismatch

org.springframework.web.util.NestedServletException: 请求 处理失败;嵌套异常是 java.lang.IllegalArgumentException:参数类型不匹配 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)

【问题讨论】:

发布异常的完整堆栈跟踪和 JSON 字符串。 做一个System.out.println(entityString) 并发布它打印的内容。 你有不同的例外吗?如果有,请发布。 嘿,非常感谢您的帮助 Sotirios,感谢您抽出宝贵时间查看此内容。 【参考方案1】:

这不会解决所有问题,但它会让我们走上正轨

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

应该是

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

EntityUtils.toString() 状态的 javadoc

读取实体的内容并将其作为字符串返回。内容 使用实体中的字符集(如果有)进行转换,失败 即,使用“ISO-8859-1”。

当你这样做时

productResponse.getEntity().toString();

您正在调用Object 类的toString() 方法,ResponseEntityWrapper 继承了该方法。这只是返回 Stringorg.apache.http.impl.execchain.ResponseEntityWrapper@8f6b087,它根本不是 HTTP 响应的正文。

【讨论】:

以上是关于反序列化问题的主要内容,如果未能解决你的问题,请参考以下文章

ctf serialize 序列化和反序列化

如何序列化/反序列化的ArrayList

使用 gson 反序列化反序列化对象的内部对象

xmldecoder反序列化漏洞分析

关于使用XmlSerializer 序列化和反序列化的问题?

NewtonSoft.JSON 反序列化 - 未正确反序列化。 (VB.NET)