Java rest模板&;Jackson-自定义JSON反序列化?

Java rest模板&;Jackson-自定义JSON反序列化?,java,json,jackson,resttemplate,Java,Json,Jackson,Resttemplate,webservice返回一个空字符串,而不是导致Jackson崩溃的NULL。 所以我创建了一个自定义解析器,并尝试手动解析它?你知道我怎样才能做到这一点吗 我做错了什么?我所要做的就是像平常一样将JSON解析为object。字段名使用@JsonProperty添加到我的属性中,因此解析器应该知道如何转换它 public class InsertReplyDeserializer extends JsonDeserializer<ListingReply> { @Overr

webservice返回一个空字符串,而不是导致Jackson崩溃的NULL。 所以我创建了一个自定义解析器,并尝试手动解析它?你知道我怎样才能做到这一点吗

我做错了什么?我所要做的就是像平常一样将JSON解析为object。字段名使用@JsonProperty添加到我的属性中,因此解析器应该知道如何转换它

public class InsertReplyDeserializer extends JsonDeserializer<ListingReply> {

    @Override
    public ListingReply deserialize(JsonParser jsonParser, DeserializationContext arg1)
            throws IOException, JsonProcessingException {

        ObjectCodec oc = jsonParser.getCodec();
        JsonNode node = oc.readTree(jsonParser);

        // If service returns "" instead of null return a NULL object and don't try to parse
        if (node.getValueAsText() == "")
            return null;


       ObjectMapper objectMapper = new ObjectMapper();
       ListingReply listingReply = objectMapper.readValue(node, ListingReply.class);


       return listingReply;
    }

}
公共类InsertReplyDeserializer扩展JsonDeserializer{
@凌驾
public ListingReply反序列化(JsonParser JsonParser,反序列化上下文arg1)
抛出IOException、JsonProcessingException{
ObjectCodec oc=jsonParser.getCodec();
JsonNode=oc.readTree(jsonParser);
//如果服务返回“”而不是null,则返回null对象,并且不尝试解析
如果(node.getValueAsText()=“”)
返回null;
ObjectMapper ObjectMapper=新的ObjectMapper();
ListingReply ListingReply=objectMapper.readValue(节点,ListingReply.class);
返回列表回复;
}
}

以下是我解决问题的方法

@Override
public MyObject deserialize(JsonParser jsonParser, DeserializationContext arg1)
        throws IOException, JsonProcessingException {

    ObjectCodec oc = jsonParser.getCodec();
    JsonNode node = oc.readTree(jsonParser);

    if (node.getValueAsText() == "")
        return null;

    MyObject myObject = new MyObject();
    myObject.setMyStirng(node.get("myString").getTextValue());

    JsonNode childNode = node.get("childObject");
    ObjectMapper objectMapper = new ObjectMapper();
    ChildObject childObject = objectMapper.readValue(childNode,
            ChildObject.class);

             myObject.setChildObject(childObject);
             return myObject;
}

我不确定您是否需要手动解析响应。你的解决方案会起作用,但在我看来似乎是次优的。因为看起来您正在使用RestTemplate,所以应该编写(或将解析器代码移动到)您自己的消息转换器。然后将此转换器添加到rest模板对象,该对象将在内部为您反序列化该值。沿着这条路线

public class CustomHttpmsgConverter extends  AbstractHttpMessageConverter<Object> {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
   InputStream istream = inputMessage.getBody();
   String responseString = IOUtils.toString(istream);
   if(responseString.isEmpty()) //if your response is empty
     return null;
   JavaType javaType = getJavaType(clazz);
   try {
       return this.objectMapper.readValue(responseString, javaType);
   } catch (Exception ex) {
    throw new HttpMessageNotReadableException(responseString);
    }
}

//add this converter to your resttemplate
    RestTemplate template = new RestTemplate();
    List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
    converters.add(new CustomHttpmsgConverter());
    template.setMessageConverters(converters);
公共类CustomHttpmsgConverter扩展了AbstractHttpMessageConverter{
私有ObjectMapper ObjectMapper=新ObjectMapper();
@凌驾
受保护的对象readInternal(类clazz,HttpInputMessage inputMessage)引发IOException,HttpMessageGenetradableException{
InputStream istream=inputMessage.getBody();
字符串responseString=IOUtils.toString(istream);
if(responseString.isEmpty())//如果您的响应为空
返回null;
JavaType JavaType=getJavaType(clazz);
试一试{
返回this.objectMapper.readValue(responseString,javaType);
}捕获(例外情况除外){
抛出新的HttpMessageTreadableException(responseString);
}
}
//将此转换器添加到resttemplate
RestTemplate=新的RestTemplate();
列表>();
添加(新的CustomHttpmsgConverter());
模板.setMessageConverters(转换器);

在大多数情况下,我不必做任何关于反序列化的事情,这是一种特殊情况,即坏数据来自服务器,导致解析崩溃,因为解析器需要对象结构,但响应是空字符串(对于结果中的特定字段)。因此,这是一个仅对我应用程序中的一个模型进行反序列化的变通方法。在应用程序的其余部分,我不必做任何事情来反序列化JSON,它都由RestTemplate&Jackson(使用@JsonProperty注释)自动执行。正是这样,我上面的解决方案建议您将此特殊转换器添加到rest模板中,该模板将处理空响应字符串,从而消除手动反序列化。提供转换器的目的是准确地处理OOH这样的情况,因此您可以将其移到MessageConverter,然后将应用于所有内容。我会尝试一下,并将其发回给您。请查看MappingJackson2HttpMessageConverter源代码。您希望保留自定义转换器中的所有方法,与MappingJackson2HttpMessageConverter完全相同,但使用上面的代码/或我的代码重写readInternal()。readInternal()当反序列化对象时,从相应的转换器(由rest模板根据响应内容类型选择)调用。