2012-04-20 108 views
6

我使用Spring的MappingJacksonHttpMessageConverter将JSON消息转换为我的控制器中的对象。从串反序列化ArrayList使用Jackson

<bean id="jsonConverter" 
    class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> 
    <property name="prefixJson" value="false" /> 
    <property name="supportedMediaTypes" value="application/json" /> 
</bean> 

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> 
    <property name="messageConverters"> 
     <list> 
      <ref bean="jsonConverter" /> 
     </list> 
    </property> 
</bean> 

对于被声明为ArrayList的字段,如果该JSON消息包含字符串代替,下面将引发异常:

org.springframework.http.converter.HttpMessageNotReadableException: 
Could not read JSON: Can not deserialize instance of java.util.ArrayList out of VALUE_STRING token 

一个例子是下面的类定义:

public class Product { 
    private String name; 
    private List<String> images; 
} 

如果传入的JSON是:

{name:"Widget", images:"image1.jpg"} 

正如你所看到的,这将产生异常,因为图像应该是一个数组。

我想制作一个更耐用的自定义解串器。如果反序列化失败,请从String中创建一个单个元素的ArrayList。我将如何去注入MappingJacksonHttpMessageConverter或ObjectMapper?

我不想使用注释来标记每个ArrayList字段,因此可以使用自定义的反序列化。 我正在寻找一种方法来覆盖默认的解串器来执行此功能。

+0

什么是你试图反序列化原始字符串? – 2012-04-20 14:46:12

+0

说它是{产品:“1234”}而不是{产品:[“1234”]} – ltfishie 2012-04-20 15:06:33

+0

,你是如何试图反序列化它?你可以发布一些代码吗? – 2012-04-20 15:10:42

回答

14

查看本文描述如何使用jackson objectMapper的功能来完成此操作。

https://github.com/FasterXML/jackson-dataformat-xml/issues/21

对我来说,加入以下解决了这个问题

jsonMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); 
+4

或版本2 jsonMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY,true); – 2013-02-03 08:37:38

+3

基督,为什么这么难在网上找到? *这是我一直在寻找的解决方案 - 谢谢。 – Ryan 2014-06-05 06:51:44

1

据我看到传入的JSON不包含任何数组。问题是:“图像”应该是分离的还是包含单个图像?我们假设它们是逗号分隔的:

public class Product { 
    private String name; 
    private List<String> images; 

    @JsonProperty("images") 
    public String getImagesAsString() { 
     StringBuilder sb = new StringBuilder(); 
     for (String img : images) { 
      if (sb.length() > 0) sb.append(','); 
      sb.append(img); 
     } 
     return sb.toString(); 
    } 

    public void setImagesAsString(String img) { 
     this.images = Arrays.asList(img.split(",")); 
    } 

    @JsonIgnore 
    public List<String> getImages() { 
     return images; 
    } 
} 
+0

谢谢你的回答。对不起,如果我没有说清楚,但我想要做的是使解析更宽容一点。我也想把它应用到默认的解析行为,所以我不需要使用注释或为每个字段创建第二个setter方法。 – ltfishie 2012-04-23 14:41:17

+0

另一种选择是将图像字段设置为纯字符串(如果它包含单个图像),或者更改JSON字符串的格式以发送数组而不是字符串。 – 2012-04-23 17:14:19