如何在 Spring Boot 3.4.0 中配置 PersistentEntityJackson2Module?

问题描述 投票:0回答:1

我们正在将 Spring Boot 应用程序(Spring Data Rest 与普通 mvc 的混合)从版本 2.5.12 迁移到 3.4.0。该应用程序很大程度上依赖于使用 https://docs.spring.io/spring-data/rest/docs/current/api/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.html 模块配置的 ObjectMapper。

应用程序使用 ObjectMapper 在补丁调用期间将带有嵌套子对象链接的 JSON 反序列化为实体。升级后,所有补丁调用在反序列化时都会失败。进一步的调查揭示了根本原因。 ObjectMapper.getRegisteredModuleIs() 显示为 Spring Boot 2.15 注册的 persistentEntityJackson2Module,并且在版本 3.4.0 中不显示此(或类似)模块

较旧的 Spring Boot 版本似乎会自动创建并配置此 persistentEntityJackson2Module ,而 3.4.0 版本则不会。

我们尝试实例化 PersistentEntityJackson2Module 类。不幸的是,这个类有太多的依赖项。其中一些需要大量的手动编码才能实现。我们用长而复杂的代码部分地完成了它。有什么简单的方法吗

有谁知道如何在 Spring Boot 3.4.0 中创建和配置 PersistentEntityJackson2Module 吗?

惯用示例:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.PersistentEntityResource;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

@Component
class PersistentEntityObjectMapperProvider {

    @Autowired
    private List<HttpMessageConverter<?>> defaultMessageConverters;

    public ObjectMapper getObjectMapper() {

        return defaultMessageConverters.stream()
                //Able to find with Spring Boot 2.15 and unable with 3.4.0
                .filter(c -> c.canRead(PersistentEntityResource.class, MediaType.APPLICATION_JSON))
                .filter(c -> c instanceof MappingJackson2HttpMessageConverter).filter(Objects::nonNull)
                .map(c -> ((MappingJackson2HttpMessageConverter) c).getObjectMapper())
                .findFirst().orElseThrow(() -> new IllegalArgumentException("Could not find ObjectMapper"));
        //Tried multiple different ways to find object mappers. None of them contains PersistentEntityJackson2Module in spring boot version 3.4.0
    }

}

@Data
@Entity
class Engine {
    @Id
    private Long id;
    // other fields
}

@Data
@Entity
class Car {
    @Id
    private Long id;
    private String model;
    private int year;
    @OneToOne(...)
    private Engine engine;
    //other fields
}

@Service
class CarAssembler {
    @Autowired
    PersistentEntityObjectMapperProvider provider;


    /**
     * Add parts to the car assembly
     *
     * @param car
     * @param partsAsJsonString, e.g.: {"engine": "http://loclahost:8080/engines/123"}
     * @throws IOException
     */
    public void addParts(Car car, String partsAsJsonString) throws IOException {
        ObjectMapper mapper = provider.getObjectMapper();
        ObjectNode requestBodyObjectNode = (ObjectNode) mapper.readTree(partsAsJsonString);
        var objectReader = mapper.readerForUpdating(car);
        var updatedCar = objectReader.readValue(partsAsJsonString, Car.class);
        //save updatedCar
    }
}


    
spring-boot spring-data-rest objectmapper spring-boot-3
1个回答
0
投票
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.webmvc.json.  
 PersistentEntityJackson2Module;

@Configuration
public class JacksonConfig {

    @Bean
    public PersistentEntityJackson2Module persistentEntityJackson2Module() {
        return new PersistentEntityJackson2Module();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.