相关文章推荐
风度翩翩的排球  ·  vue - 掘金·  2 年前    · 
安静的吐司  ·  New-AzureADMSAdministr ...·  2 年前    · 

基于Spring或SpringBoot框架

  • 在后端返回给前端json数据时,会出现字段对应的值为null,返回数据以后该字段也不存在了,在对框架不了解的情况下,初学者不是很好去定位问题出现在那里,下面我就解释一下为什么出现这种情况
  • VO:这边定义了不同的类型,以对应不同的类型去进行序列化设置

    public class RespVO {
        private String str;
        private Integer num;
        private Long longNun;
        private List list;
    

    请求返回值,可以查看到当字段为null时也会正常返回字段,如果字段类型为List则会返回空数组

    "success": true, "code": 200, "message": "成功", "data": { "str": "", "num": 1, "longNun": "", "list": []

    这都是因为全局序列化设置导致,下面就贴出配置的代码,可以自行根据实际需求进行修改,以达到需求的目的

    ps:此处使用的时 jackson序列化 如果是已经上线的项目,谨慎修改全局序列化

    @Configuration
    public class R3WebMvcConfig {
        private final static Logger logger = LoggerFactory.getLogger(R3WebMvcConfig.class);
         * 自定义全局 http请求序列化方式
         * @return
        @Bean
        public HttpMessageConverters httpMessageConverters() {
            MappingJackson2HttpMessageConverter httpMessageConverter = new MappingJackson2HttpMessageConverter();
            ObjectMapper objectMapper = httpMessageConverter.getObjectMapper();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleModule simpleModule = new SimpleModule();
            //序列化日期格式
            simpleModule.addSerializer(Date.class, new DateSerializer(false, simpleDateFormat));
            //Long序列化为String
            simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
            simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
            //字符串转String
            simpleModule.addDeserializer(Date.class, new JsonDeserializer<Date>() {
                @Override
                public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
                    String date = jsonParser.getText();
                    try {
                        return simpleDateFormat.parse(date);
                    } catch (ParseException e) {
                        logger.error("自定义全局序列化String2Date异常:{}",e.getMessage());
                        throw new RuntimeException(e);
            //反序列化日期格式
            objectMapper.registerModule(simpleModule);
            //序列化多余字段不报错
            objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
            //序列化地区
            objectMapper.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
            //如果值为null时字段key还是否输出:ALWAYS(总是输出),NON_NULL(为null的不输出)
            objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
            objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
                @Override
                public void serialize(Object o, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
                    String fieldName = gen.getOutputContext().getCurrentName();
                    try {
                        //反射获取字段类型
                        Field field = gen.getCurrentValue().getClass().getDeclaredField(fieldName);
                        if (Objects.equals(field.getType(), String.class)) {
                            //字符串型空值""
                            gen.writeString("");
                            return;
                        } else if (Objects.equals(field.getType(), List.class)) {
                            //列表型空值返回[]
                            gen.writeStartArray();
                            gen.writeEndArray();
                            return;
                        } else if (Objects.equals(field.getType(), Map.class)) {
                            //map型空值返回{}
                            gen.writeStartObject();
                            gen.writeEndObject();
                            return;
                    } catch (NoSuchFieldException e) {
                    //默认返回""
                    gen.writeString("");
            return new HttpMessageConverters(httpMessageConverter);
    

    基本原理就是这样,代码注释已经很详细,如有不理解或需求帮助请留言。

    分类:
    后端
    标签: