SpringBoot jackson传入List引起的坑

一、jackson无法解析value为[]的json

    当入参为{xxxx1:[1,2,3],xxxx2:[obj1,obj2,obj3]}时,springmvn controller接收入参写为Long[] xxxx1,无法解析,报错

    解决方案:

1.@RequestBody只能使用一次

2.使用map接收,再用get获取

二、如上,当数组为POJO时,通过直接map.get然后强制转换,不能成功,使用的时候还是LinkedHashMap

解决方案:

1.先将LinkedHashMap转为json,再讲json转为对象,如下JsonUtils的convertObject方法,转换List使用convertObjectList方法

package com.performancetest.common.utils;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class JsonUtils {

    /**
     * <p>
     * 对象转JSON字符串
     * </p>
     */
    public static String object2Json(Object obj) {
        String result = null;
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            result = objectMapper.writeValueAsString(obj);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    public static Map object2Map(Object obj) {
        String object2Json = object2Json(obj);
        Map<?, ?> result = jsonToMap(object2Json);
        return result;
    }

    /**
     * <p>
     * JSON字符串转Map对象
     * </p>
     */
    public static Map<?, ?> jsonToMap(String json) {
        return json2Object(json, Map.class);
    }

    /**
     * <p>
     * JSON转Object对象
     * </p>
     *
     */
    public static <T> T json2Object(String json, Class<T> cls) {
        T result = null;
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            result = objectMapper.readValue(json, cls);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }


    public static <T> T convertObject(Object srcObject, Class<T> destObjectType) {
        String jsonContent = object2Json(srcObject);
        return json2Object(jsonContent, destObjectType);
    }

    public static <T> List  convertObjectList(List<LinkedHashMap> list, Class<T> destObjectType){
        List result =new ArrayList<>();
        list.stream().forEach(x->{
            result.add(convertObject(x,destObjectType));
        });
        return result;
    }

}

三、如上转换时,报出错,jackson转换DateFormat类型时,不支持yyyy-MM-DD HH-mm-ss格式的日期,报错

解决方案:

方案1.在Date类型上加@JsonFormat( pattern="yyyy-MM-dd HH:mm:ss"),如下

(弊端:每个字段都得加,麻烦,没从根本上解决问题,不推荐,推荐方案2)

@JsonFormat( pattern="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;

方案2.

1.重写DateFormat子类,解析的实收优先用yyyy-MM-dd HH:mm:ss类型解析,不行再用父类

(这里遇到一个坑,启动时报calendar空指针异常,所以在构造函数里加了

this.calendar = dateFormat.getCalendar(); )
package com.performancetest.config;


import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MyDateFormat extends DateFormat {

    private DateFormat dateFormat;

    private SimpleDateFormat format1 = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");

    public MyDateFormat(DateFormat dateFormat) {
        this.dateFormat = dateFormat;
        //要添加父类的calendar属性,否则会报空指针异常
        this.calendar = dateFormat.getCalendar();
    }

    @Override
    public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
        return dateFormat.format(date, toAppendTo, fieldPosition);
    }

    @Override
    public Date parse(String source, ParsePosition pos) {

        Date date = null;

        try {

            date = format1.parse(source, pos);
        } catch (Exception e) {

            date = dateFormat.parse(source, pos);
        }

        return date;
    }

    // 主要还是装饰这个方法
    @Override
    public Date parse(String source) throws ParseException {

        Date date = null;

        try {

            // 先按我的规则来
            date = format1.parse(source);
        } catch (Exception e) {

            // 不行,那就按原先的规则吧
            date = dateFormat.parse(source);
        }

        return date;
    }

    // 这里装饰clone方法的原因是因为clone方法在jackson中也有用到
    @Override
    public Object clone() {
        Object format = dateFormat.clone();
        return new MyDateFormat((DateFormat) format);
    }
}
View Code

2.将新写的子类关联到WebConfig中的MappingJackson2HttpMessageConverter Bean,如下代码

package com.performancetest.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.text.DateFormat;

@Configuration
public class WebConfig {

    @Autowired
    private Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder;

    @Bean
    public MappingJackson2HttpMessageConverter MappingJsonpHttpMessageConverter() {

        ObjectMapper mapper = jackson2ObjectMapperBuilder.build();

        //MyDateFormate解决jackson反序列formdate不支持YYYY-MM-DD HH-mm-ss的格式
        // ObjectMapper为了保障线程安全性,里面的配置类都是一个不可变的对象
        // 所以这里的setDateFormat的内部原理其实是创建了一个新的配置类
        DateFormat dateFormat = mapper.getDateFormat();
        MyDateFormat myDateFormat = new MyDateFormat(dateFormat);
        mapper.setDateFormat(myDateFormat);

        MappingJackson2HttpMessageConverter mappingJsonpHttpMessageConverter = new MappingJackson2HttpMessageConverter(
                mapper);
        return mappingJsonpHttpMessageConverter;
    }
}
View Code

 

转载于:https://www.cnblogs.com/zipon/p/9915412.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot Jackson是Spring Boot框架中的一个模块,它提供了Jackson库的集成和配置。Jackson是一个流行的Java库,用于将Java对象序列化为JSON格式,或将JSON格式反序列化为Java对象。在Spring Boot中,Jackson可以用于处理HTTP请求和响应中的JSON数据,以及在应用程序中处理JSON格式的数据。Spring Boot Jackson还提供了一些配置选项,例如日期格式化、空值处理等,以便更好地控制JSON序列化和反序列化的行为。 ### 回答2: Spring Boot是一个流行的Java开发框架,它提供了一个快速、免费、简单的方式来创建和配置基于Spring的应用程序。Spring Boot包含大量的基础组件,使用这些组件可以快速地构建Web应用程序,并且可以快速集成到现有的Spring应用程序中。Jackson是一个流行的Java JSON库,它提供了一个功能强大的API,可以轻松地将Java对象序列化为JSON格式。 在Spring Boot中使用Jackson是非常方便的,只需要将Jackson作为依赖项添加到你的项目中即可。Spring Boot会自动配置Jackson,以便可以轻松地使用它来序列化和反序列化JSON数据。使用Jackson可以将Java对象序列化为JSON字符串,或将JSON字符串反序列化为Java对象。通过Jackson的注解,可以自定义Java对象在序列化为JSON时的编组方式。Jackson还可以处理复杂的Java对象图,包括嵌套对象和对象集合。 Spring Boot使用Jackson的主要好处是它的简单性和灵活性。Jackson与Spring Boot完美地结合,使数据序列化和反序列化变得非常简单。同时,Jackson具有丰富的功能和灵活的配置选项,可以满足各种需求。此外,Jackson灵活的注解可以让开发人员自定义序列化和反序列化过程,使得开发人员可以按照自己的需求来处理数据。因此,Spring Boot和Jackson在做Web应用程序开发时能够快速准确地向前端交互数据。 ### 回答3: Spring Boot是一个快速开发框架,它提供了许多便利的工具和插件,用于快速构建基于Spring的应用程序。其中一个非常重要的模块是Jackson,它提供了一个强大的JSON序列化和反序列化框架。 Jackson的优点在于其高效性和灵活性。它可以轻松地将Java对象换为JSON格式,也可以将JSON格式换为Java对象。此外,它还提供了许多高级功能,如自定义序列化和反序列化器、支持注释和混合类型等。 Spring Boot集成了Jackson,因此使用Jackson在Spring Boot应用程序中对数据进行序列化和反序列化是非常简单和方便的。只需通过注释或配置来自定义序列化和反序列化行为,就可以轻松地处理复杂的数据类型和嵌套结构。 总之,Spring Boot和Jackson的集成为Java开发人员提供了一种强大且易于使用的方法来处理JSON数据。这使得开发人员可以更快地构建高效、可靠的应用程序,同时保持应用程序的可读性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值