【问题标题】:Jackon custom deserializer never calledJackon 自定义反序列化器从未调用过
【发布时间】:2017-08-10 14:32:01
【问题描述】:

这是我使用@JsonDeserialize 的属性

@Transient
@JsonDeserialize(using = SharedUserDeserializer.class)
private Set<UserVehicleMappingVO> sharedVehicle;

public Set<UserVehicleMappingVO> getSharedVehicle() {
    return sharedVehicle;
}
public void setSharedVehicle(Set<UserVehicleMappingVO> sharedVehicle) {
    this.sharedVehicle = sharedVehicle;
}

而自定义的解串器代码是

public class SharedUserDeserializer extends JsonDeserializer<Set<UserVehicleMappingVO>> {

@Override
public Set<UserVehicleMappingVO> deserialize(JsonParser paramJsonParser,
        DeserializationContext paramDeserializationContext)
        throws IOException, JsonProcessingException {
    try {
        Set<UserVehicleMappingVO> list = new ObjectMapper().readValue(paramJsonParser.toString(),
                new TypeReference<Set<UserVehicleMappingVO>>() {});
        return list;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return new HashSet<>();
}
}

但是从不调用反序列化器。请帮忙

每次我得到这个异常时......

 ERROR :::9,gajendranc@azuga.com - Exception in 
method===org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'trackee' on field 'sharedVehicle': rejected value 
[[{"userId":"5d48b74f-7da2-11e7-87bf-
1383429d1d89","expireTime":1504190100000}]]; codes 
 [typeMismatch.trackee.sharedVehicle,typeMismatch.sharedVehicle,
typeMismatch.java.util.Set,typeMismatch]; arguments 
[org.springframework.context.support.DefaultMessageSourceResolvable: codes 
[trackee.sharedVehicle,sharedVehicle]; arguments []; default message 
[sharedVehicle]]; default message [Failed to convert property value of type 
[java.lang.String] to required type [java.util.Set] for property 
'sharedVehicle'; nested exception is java.lang.IllegalStateException: Cannot 
convert value of type [java.lang.String] to required type 
[com.azuga.user.manager.UserVehicleMappingVO] for property 
'sharedVehicle[0]':

请帮忙........

【问题讨论】:

  • 为什么是@Transient?您想在序列化过程中忽略该字段吗?
  • @Barath : Transient 是为了让休眠在持久化到表时忽略这个字段...它与序列化无关。
  • 感谢您的教育。因为我找不到任何用于瞬态的导入语句,所以我认为它必须与 java 序列化有关。

标签: java spring jackson json-deserialization objectmapper


【解决方案1】:

您是否注册了本示例中提到的模块 http://www.baeldung.com/jackson-deserialization

        ObjectMapper mapper=new ObjectMapper();
        SimpleModule module = new SimpleModule();

        module.addDeserializer(Set.class, new SharedUserDeserializer());
        mapper.registerModule(module);

它对我有用:

    @Test
    public void test() throws IOException {

        ObjectMapper mapper=new ObjectMapper();
        SimpleModule module = new SimpleModule();

        module.addDeserializer(Set.class, new SharedUserDeserializer());
        mapper.registerModule(module);
       TestUser user=new TestUser();

    Set<UserVehicleMappingVO> sets=new HashSet<>();

    sets.add(new UserVehicleMappingVO("test1"));
    user.setVechicles(sets);

    String jsonString=mapper.writeValueAsString(user);
    Set<UserVehicleMappingVO> vechiles=mapper.readValue(jsonString, new TypeReference<Set<UserVehicleMappingVO>>() {
    });

}

型号:

public class TestUser {

    @JsonDeserialize(using = SharedUserDeserializer.class)
    private Set<UserVehicleMappingVO> vechicles;
   //getters and setters 
}

public class UserVehicleMappingVO {

    private String name;

//getters and setters 

}

自定义反序列化器类:

public class SharedUserDeserializer extends JsonDeserializer<Set<UserVehicleMappingVO>> {

@Override
public Set<UserVehicleMappingVO> deserialize(JsonParser paramJsonParser,
        DeserializationContext paramDeserializationContext)
        throws IOException, JsonProcessingException {
    try {
        System.out.println("hello");
        Set<UserVehicleMappingVO> list = new ObjectMapper().readValue(paramJsonParser.toString(),
                new TypeReference<Set<UserVehicleMappingVO>>() {});
        return list;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return new HashSet<>();
}

回应:

Output {"vechicles":[{"name":"test1"}]}
hello

自定义 HttpMessageConverters :

@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
 MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
 ObjectMapper objectMapper = new ObjectMapper();
 SimpleModule module = new SimpleModule();

            module.addDeserializer(Set.class, new SharedUserDeserializer());
            objectMapper.registerModule(module);

 jsonConverter.setObjectMapper(objectMapper);
 return jsonConverter;
}

参考这里:https://dzone.com/articles/customizing

【讨论】:

  • 对我来说 json 来自 UI,那么在哪里注册反序列化器??
  • 自定义httpmessageconverter,查看更新答案
【解决方案2】:

尝试仅反序列化“Set” -> 扩展 JsonDeserializer

【讨论】:

  • 想通了...使用 RequestPart 注释时不调用反序列化器。但是当使用 RequestBody 注释时,它会被调用。不确定为什么?
  • RequestBody 表示请求的正文可以通过 HttpMessageConverter 进行转换,以根据其类型解析内容。 (将内容(xml/json/...等)转换为对象)RequestPart 它适用于多部分表单数据 - 主要用于文件上传。
猜你喜欢
  • 2017-01-30
  • 1970-01-01
  • 2021-10-26
  • 2017-09-10
  • 2011-04-25
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多