3.Spring Boot 中Jackson配置,ObjectMapper使用详解

一.前言

1.介绍
  • 上篇文章从spring-boot中引申出了jackson这个杰出的json解析框架,详细的分析了Jackson提供的注解功能,以及它们在controller中的使用,在这篇将介绍Jackson对外提供的API类ObjectMapper,以及Jackson在sping-boot配置文件中的各项配置
2.项目例子
3.进阶文档

二.使用Jackson的ObjectMapper序列化和反序列化Json

  • 注意,Jackson反序列化json为对象的时候,使用的是对象空参构造器,在我们自定义构造器的时候,需要覆写空参构造器
  1. 测试类中所使用的实体

    	public class Apartment {
        private String roommate;
        private String payRentMan;
    
        public Apartment() {
        }
    
        public Apartment(String roommate, String payRentMan) {
            this.roommate = roommate;
            this.payRentMan = payRentMan;
        }
    
        public String getRoommate() {
            return roommate;
        }
    
        public void setRoommate(String roommate) {
            this.roommate = roommate;
        }
    
        public String getPayRentMan() {
            return payRentMan;
        }
    
        public void setPayRentMan(String payRentMan) {
            this.payRentMan = payRentMan;
        }
    }
    
  2. writeValue:对象序列化的时候可以直接将需要序列化的数据,格式化成文件,也可以使用重载方法格式化流输出

     @Test
    public void testWriteValueAsFile() throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        Apartment apartment = new Apartment("Joey", "Chandler");
        objectMapper.writeValue(new File("target/apartment.json"), apartment);
    }
    

    运行返回,在target文件夹下输出了apartment.json文件

  3. writeValueAsStringwriteValueAsBytes,对象可以直接序列化为字符串和字节

     @Test
    public void testWriteValueAsStringAndByte() throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        Apartment apartment = new Apartment("Joey", "Chandler");
        String result = objectMapper.writeValueAsString(apartment);
        System.out.println(result);
        byte[] bytes = objectMapper.writeValueAsBytes(apartment);
        System.out.println(new String(bytes));
        assertEquals(result,new String(bytes));
    }
    

    运行返回

    {"roommate":"Joey","payRentMan":"Chandler"}
    {"roommate":"Joey","payRentMan":"Chandler"}
    
  4. readValue,将json串反序列化为对象

     @Test
    public void testReadValueAsBeanFromJson() throws IOException {
        String json = "{ \"roommate\" : \"Joey\", \"payRentMan\" : \"Chandler\" }";
        Apartment apartment = new ObjectMapper().readValue(json, Apartment.class);
        assertEquals(apartment.getPayRentMan(),"Chandler");
    }
    
  5. readValue,将json串反序列化为对象,可以将file文件作为数据源也可以读取网络URL流中数据

     @Test
    public void testReadValueAsBeanFromFileAndURL() throws IOException {
        Apartment apartment = new ObjectMapper().readValue(new File("target/apartment.json"), Apartment.class);
        //Apartment apartment = new ObjectMapper().readValue(new URL("target/apartment.json"), Apartment.class);
        assertEquals(apartment.getPayRentMan(),"Chandler");
    }
    
  6. readTree,将Json解析为Jackson JsonNode对象,从特定的节点中检索数据

     @Test
    public void testReadTree() throws IOException {
        String json = "{ \"roommate\" : \"Joey\", \"payRentMan\" : \"Chandler\" }";
        JsonNode jsonNode = new ObjectMapper().readTree(json);
        assertEquals(jsonNode.get("payRentMan").asText(),"Chandler");
    }
    
  7. 解析json数组到list中,这里需要注意的是,我们需要创建一个带有泛型的模板类对象传入到readValue中用于类型的识别,从而规避泛型的类型擦除

     @Test
    public void testReadValueAsListBean() throws IOException {
        String jsonApartmentArray =
                "[{ \"roommate\" : \"Joey\", \"payRentMan\" : \"Chandler\" }, { \"roommate\" : \"Rachel\", \"payRentMan\" : \"Monica\" }]";
       List<Apartment>  apartments=  new ObjectMapper().readValue(jsonApartmentArray,new TypeReference<List<Apartment>>(){});
        assertEquals(apartments.size(),2);
    }
    
  8. 将数据映射到Map对象中,同list一样,传入map的类型模板

    @Test
    public void testReadValueAsMap() throws IOException {
        String json = "{ \"roommate\" : \"Joey\", \"payRentMan\" : \"Chandler\" }";
        Map<String, Object> map
                =  new ObjectMapper().readValue(json, new TypeReference<Map<String,Object>>(){});
        assertEquals(map.size(),2);
    }
    
  9. 解决反序列化为bean时json多出字段导致UnrecognizedPropertyException异常
    第一种方式使用readTree反序列化为JsonNode
    第二种方式使用configure方式忽略多余字段

    @Test
    public void testMoreProperty() throws IOException {
        String json = "{ \"roommate\" : \"Joey\", \"animal\" : \"dark\"}";
        JsonNode jsonNode = new ObjectMapper().readTree(json);
        assertEquals(jsonNode.get("animal").asText(),"dark");
        ObjectMapper objectMapper= new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        Apartment apartment = objectMapper.readValue(json, Apartment.class);
        assertEquals(apartment.getRoommate(),"Joey");
    }
    
  10. 处理日期有很多种方式,着重介绍2种
    第一种实体类中使用注解@JsonFormat
    第二种将日期格式化规则写入到ObjectMapper中

    @Test
    public void testDateFormat() throws IOException {
        Request request = new Request();
        Apartment apartment = new Apartment("Joey", "Chandler");
        request.setApartment(apartment);
        request.setBillingDate(new Date());
        ObjectMapper objectMapper = new ObjectMapper();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z");
        objectMapper.setDateFormat(df);
        String string = objectMapper.writeValueAsString(request);
        System.out.println(string);
    }
    
    class Request
    {
        private Apartment apartment;
        private Date billingDate;
    
        public Apartment getApartment() {
            return apartment;
        }
    
        public void setApartment(Apartment apartment) {
            this.apartment = apartment;
        }
    
        public Date getBillingDate() {
            return billingDate;
        }
    
        public void setBillingDate(Date billingDate) {
            this.billingDate = billingDate;
        }
    }
    
  11. 序列化和反序列化嵌套list,如下

    @Test
    public void testDateFormat2() throws IOException {
        ArrayList<RequestList> requestLists = Lists.newArrayList(new RequestList(Lists.newArrayList(new Apartment("Joey", "Chandler")),1), new RequestList(Lists.newArrayList(new Apartment("Joey", "Chandler")),2));
        ObjectMapper objectMapper = new ObjectMapper();
        String string = objectMapper.writeValueAsString(requestLists);
        System.out.println(string);
        List<RequestList> m =  new ObjectMapper().readValue(string, new TypeReference<List<RequestList>>(){});
        assertEquals(m.size(),2);
    }
    
    class RequestList
    {
        private List<Apartment> apartment;
    
        private Integer id;
    
        public RequestList() {
        }
    
        public RequestList(List<Apartment> apartment, Integer id) {
            this.apartment = apartment;
            this.id = id;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public List<Apartment> getApartment() {
            return apartment;
        }
    
        public void setApartment(List<Apartment> apartment) {
            this.apartment = apartment;
        }
    }
    

三.spring boot中Jackson配置详解

  1. spring.jackson.date-format= 配置日期序列化和反序列化格式, yyyy-MM-dd HH:mm:ss.
  2. spring.jackson.default-property-inclusion= 控制序列化期间包含的属性。配置了Jackson的JsonInclude.Include枚举中的一个值,若配置一般配置non_null表示序列化时忽略属性为null的值,always, non_null, non_absent, non_default, non_empty
  3. spring.jackson.deserialization.*= Jackson反序列化的开关,取值true, false
  4. spring.jackson.generator.*= 开启关闭jackson的生成器,取值true, false
  5. spring.jackson.joda-date-time-format= # 配置日期格式序列化为string的格式,不配置默认使用date-format配置
  6. spring.jackson.locale= 本地化配置
  7. spring.jackson.mapper.*= 开启或者关闭jackson,取值true, false
  8. spring.jackson.parser.*= 开启关闭jsonson的解析器 ,取值true, false
  9. spring.jackson.property-naming-strategy=配置json的key值和实体属性名称之间的转换关系,值一般为PropertyNamingStrategy类中常数或者实现PropertyNamingStrategy子类的全限定名
  10. spring.jackson.serialization.*= Jackson序列化的开关,取值true, false
  11. spring.jackson.time-zone= 格式化日期时使用的时区。例如,“America / Los_Angeles”或“GMT + 10”
  12. spring.jackson.visibility.*= 修改实体类属性域的可见性

四.结尾

  • 上篇文章从spring-boot中引申出了jackson这个杰出的json解析框架,详细的分析了Jackson提供的注解功能,以及它们在controller中的使用
  • 这篇文章,介绍了ObjectMapper是如何序列化和反序列化json,以及Jackson在spring boot中的各项配置

上一篇:Spring Boot 中Json的使用,Jackson注解详解

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
配置 JacksonObjectMapper,你可以按照以下步骤进行操作: 1. 首先,确保你已经添加了 Jackson 的依赖到你的项目。在 Maven 项目,可以在 pom.xml 文件添加以下依赖: ```xml <dependencies> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.4</version> </dependency> </dependencies> ``` 2. 创建一个 ObjectMapper 对象,并设置你所需的配置选项。例如,如果你想要忽略未知的属性,你可以通过调用 `configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)` 方法来配置 ObjectMapper。 ```java import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); ``` 3. 如果需要,你还可以注册自定义的序列化器和反序列化器。例如,如果你想要定制某种类型的序列化/反序列化行为,可以通过调用 `registerModule()` 方法来注册一个自定义的模块。 ```java import com.fasterxml.jackson.databind.module.SimpleModule; SimpleModule module = new SimpleModule(); module.addSerializer(MyCustomType.class, new MyCustomSerializer()); module.addDeserializer(MyCustomType.class, new MyCustomDeserializer()); objectMapper.registerModule(module); ``` 以上是基本的配置过程,根据你的需求和具体情况,你可以根据 Jackson 的文档进一步了解并配置 ObjectMapper
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值