自定义对象映射器在 springboot docker 容器中不起作用

问题描述

这是我用来构建 springboot 镜像的 Dockerfile。

FROM adoptopenjdk/openjdk11
VOLUME /tmp
ARG JAR_FILE
EXPOSE 8080
copY $JAR_FILE app-nikki.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-cp","/app:/app/lib/*","-jar","/app-nikki.jar"]

基于这个镜像,我通过docker-compose.yml制作了一个docker容器

version: '3'
services:
  #batch
  app-nikki:
    container_name: app-nikki
    image: app-nikki:latest
    build:
      context: .
      args:
        JAR_FILE: ./build/Tifscore-0.1.1.jar
    environment:
      - "SPRING_PROFILES_ACTIVE=app-dev"
      - "TZ=Asia/SEOul"
    expose:
      - 8080
    volumes:
      - /etc/localtime:/etc/localtime
      - /usr/share/zoneinfo/Asia/SEOul:/etc/timezone
      - /home/data/logs/DEV/:/Logs
      - /home/data/configFiles:/config

networks:
  default:
    external:
      name: dev-nikki

为了将数据从客户端发送到应用程序服务器(docker 容器),我使用 json 格式,所以我添加一个如下所示的自定义对象映射器。

@Configuration
public class JsonConfig {

    @Primary
    @Bean(name = "objectMapper")
    public ObjectMapper objectMapper(){

        Map<Class<?>,JsonSerializer<?>> serializerMap = new HashMap<>();
        serializerMap.put(BigDecimal.class,new BigDecimalSerializer());
        serializerMap.put(Object.class,new NullSerializer());

        return Jackson2ObjectMapperBuilder
                .json()
                .deserializerByType(Integer.class,new JsonDeserializer<Integer>() {
                    @Override
                    public Integer deserialize(JsonParser p,DeserializationContext ctxt) throws IOException,JsonProcessingException {
                        if( StringUtils.isBlank(p.getValueAsstring()) )
                        {return 0;                            }
                        else
                        { return Integer.parseInt(p.getValueAsstring());}
                    }
                })
                .deserializerByType(Long.class,new JsonDeserializer<Long>() {
                    @Override
                    public Long deserialize(JsonParser p,DeserializationContext ctxt) throws IOException {
                        if( StringUtils.isBlank(p.getValueAsstring()) )
                        { return 0L;}
                        else{ return Long.parseLong(p.getValueAsstring());}
                    }
                })
                .serializersByType(serializerMap)
                .modules(new JavaTimeModule())
                .build()
                .enable(  DeserializationFeature.FAIL_ON_UNKNowN_PROPERTIES,DeserializationFeature.READ_UNKNowN_ENUM_VALUES_AS_NULL,DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY,DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT,DeserializationFeature.READ_ENUMS_USING_TO_STRING,DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)
                .configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING,true)
                .configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN,true)
                .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false)
                .disable(DeserializationFeature.FAIL_ON_UNKNowN_PROPERTIES)
                .setVisibility(PropertyAccessor.FIELD,JsonAutoDetect.Visibility.ANY)
                ;
    }
}

为了激活我的自定义对象映射器,我在扩展 WebMvcConfigurationSupport 的 MessageConverter 上注册了它。

@Configuration
public class MessageConvertor extends WebMvcConfigurationSupport {
    
    @Bean
    public MappingJackson2HttpMessageConverter jsonConverter()
    {
        MappingJackson2HttpMessageConverter jmc = new MappingJackson2HttpMessageConverter();
        List<MediaType> supportedMediaTypes = new ArrayList<>();

        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
        jmc.setSupportedMediaTypes(supportedMediaTypes);
        ObjectMapper objectMapper = (ObjectMapper) BeanUtils.getBean("objectMapper");
        jmc.setobjectMapper(objectMapper);

        return jmc;
    }   

    @Override
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(byteArrayHttpMessageConverter());
        converters.add(jsonConverter());
        super.configureMessageConverters(converters);
    }    
}

我使用 BeansUtils.getBean 的原因是即使我使用了 @Configuration 上的 CustomObjectMapper@Autowired 不起作用 正确,它总是转到 NullPointerException


这里是docker容器发生错误的日​​志。

com.tifscore.core.interceptor.ControllerInterceptor :    88| Setting MDC = PATATE
com.tifscore.biz.RC.RcController                   :    90| #### /RCO1000A.SVC start ####[RCO1000AInput(trscDvCd=READ,curCd=IDR,depoBnkCd=2002,atulShdwDvCd=,trscDt=2021-05-03,procSeqNo=null,grid01=[])]
com.tifscore.core.aop.AopService                   :   102| ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
com.tifscore.core.aop.AopService                   :   103| ## START RCO1000ASVC execute ##
com.tifscore.core.aop.AopService                   :   106| ## input {trscDt=2021-05-03,depoBnkNm=BANK KEB HANA INDOnesIA,trscDvCd=2,procSeqNo=}

如果我在 VO (procSeqNo) 上发送 nullLong 值,它会自动在本地 PC 上的 RcController 上转换 0,如下所示。

com.tifscore.core.interceptor.ControllerInterceptor :    88| Setting MDC = PATATE
com.tifscore.biz.RC.RcController                   :    90| #### /RCO1000A.SVC start ####[RCO1000AInput(trscDvCd=READ,procSeqNo=0,procSeqNo=}

为什么我的自定义对象映射器在 docker 容器上不起作用,但在本地 PC 上正常工作?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)