为了账号安全,请及时绑定邮箱和手机立即绑定

当我尝试反序列化抽象类时,Jackson Objectmapper 在配置为 bean 后未由

当我尝试反序列化抽象类时,Jackson Objectmapper 在配置为 bean 后未由

jeck猫 2023-07-13 14:10:47
我在 Spring Boot 应用程序中使用 Jackson xml 版本 2.9.9。我有一个接受 Vehicle 的控制器,它是一个具有 2 个子类的抽象类。当我从邮递员传递 JSON 数据时,我无法反序列化车辆,因为自动连接的对象映射器始终为空(我将对象映射器配置为 bean,因为我将反序列化器设置为映射器的简单模块)。@RequestMapping(path = "/jackson", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)    public void forSingleObject(@RequestBody MyModel myModel){        System.out.println("Deserialization successful");    }MyModel.javapublic class MyModel {    private String name;    private Vehicle value;}Vehicle.javapublic abstract class Vehicle {    private String vehicleName;}Car.javapublic class Car extends Vehicle{    private String carType;    private String carDriverName;}Auto.javapublic class Auto extends Vehicle {    private String autoType;    private String autoDriverName;}ObjectMapper bean 配置@Configurationpublic class MapperConfig {    @Bean    public ObjectMapper objectMapper(){        ObjectMapper objectMapper = new ObjectMapper();//Jackson2ObjectMapperBuilder.json().build();        List<Module> modules = new ArrayList<>();        modules.add(new SimpleModule().addDeserializer(Vehicle.class, new VehicleDeserializer()));        objectMapper.registerModules(modules);        return objectMapper;    }}VehicleDeserializer.javapublic class VehicleDeserializer extends JsonDeserializer<Vehicle> {    @Autowired    private ObjectMapper objectMapper;    @Override    public Vehicle deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {        JsonNode jsonNode = jsonParser.getCodec().readTree(jsonParser);        Vehicle vehicle=null;        if (!jsonNode.findPath("carDriverName").equals("")){            vehicle = objectMapper.readValue(jsonParser, Car.class);        }else if (!jsonNode.findPath("autoDriverName").equals("")){            vehicle = objectMapper.readValue(jsonParser, Auto.class);        }        return vehicle;    }
查看完整描述

3 回答

?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

无需尝试注入ObjectMapper您的自定义解串器。你可以使用:

ObjectMapper mapper = (ObjectMapper) jsonParser.getCodec();

如果您不需要 中的任何方法ObjectMapper,则不需要强制转换:

ObjectCodec codec = jsonParser.getCodec();


查看完整回答
反对 回复 2023-07-13
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

问题的原因,你正在这样做:

modules.add(new SimpleModule().addDeserializer(Vehicle.class, new VehicleDeserializer()));

您正在自己实例化该对象,因此映射器将为空。


查看完整回答
反对 回复 2023-07-13
?
达令说

TA贡献1821条经验 获得超6个赞

您在反序列化器中犯了一些错误:

  • 因为您将反序列化器注册到反序列化器内的对象,所以您可以通过where is typeObjectMapper获取它。(ObjectMapper) parser.getCodec()parserJsonParser

  • findPath方法返回JsonNode并不String总是.equals("")返回false。你应该使用isMissingNode方法来代替。

  • 当您在对象上使用readTree方法时parser,您不能再次使用它,因为反序列化已经完成并且您有一个JsonNode. 从现在开始,你应该使用它。您可以使用convertValue方法将其转换为所需的Class

事情应该是这样的:

class VehicleDeserializer extends JsonDeserializer<Vehicle> {


    @Override

    public Vehicle deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException {

        // cast to ObjectMapper

        ObjectMapper mapper = (ObjectMapper) parser.getCodec();


        // read JSON as tree to JsonNode object

        // since now `parser` should not be used anymore.

        JsonNode root = mapper.readTree(parser);

        Vehicle vehicle = null;

        if (!root.findPath("carDriverName").isMissingNode()) {

            vehicle = mapper.convertValue(root, Car.class);

        } else if (!root.findPath("autoDriverName").isMissingNode()) {

            vehicle = mapper.convertValue(root, Auto.class);

        }

        return vehicle;

    }

}


查看完整回答
反对 回复 2023-07-13
  • 3 回答
  • 0 关注
  • 164 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信