2.Spring Boot 中Json的使用,Jackson注解详解

一.前言

1.介绍
  • 我们常在项目中使用的Json转换工具是fastjson,事实上spring本身集成了非常优秀的json工具,分别为JacksonGsonJSON-B,但是官方项目中默认推荐使用Jackson,所以本文着重介绍使用Jackson进行json的转换以及Jackson的注解使用
2.项目例子
3.进阶文档

二.Jackson在Controller中的应用

1.基本介绍
  • 在Controller中使用@RestController,默认方法接口返回json,在返回前使用Jackson将对象序列化为json,返回方法中可以省略@ResponseBody;当在形参中使用@RequestBody,默认使用Jackson将json反序列化为对象。
2.范例
  • 创建对象
    class  User  {
         
    private String userAccount;
    private String password;
    private int age;
    private Date birthday;
    ...省略Getter和Setter
    }
    
  • 创建Controller
    @RestController
    public class SpringBootJsonController {
         
        @PostMapping("testJson")
        public  User  testJson(@RequestBody  User user){
         
            return user;
        }
    }
    
    • @RestController:标定使用Rest风格,此注解包含了@Controller@ResponseBody,所有类中所有接口都不需要再标注@ResponseBody
    • @RequestBody:表示使用Jackson将接收到的json字符串反序列化为对象
    • 在此方法中我们将接收的对象原样返回
  • 在测试类中进行测试
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureMockMvc
    public class SpringBootJsonControllerTest {
         
        @Autowired
        private MockMvc mvc;
        @Autowired
        private ObjectMapper objectMapper;
        @Test
        public void testJson() throws Exception {
         
            User user = new User();
            user.setAge(12);
            user.setBirthday(new Date());
            user.setUserAccount("Joey");
            user.setPassword("Joey's password");
            String s = objectMapper.writeValueAsString(user);
            this.mvc.perform(post("/testJson").content(s.getBytes()).contentType(MediaType.APPLICATION_JSON_VALUE)).andExpect(status().isOk()).andExpect(content().string(containsString("Joey's password"))).andDo(print());
        }
    }
    
    • @RunWith(SpringRunner.class)@RunWith是一个JUnit4的注解,表明测试运行器
    • @SpringBootTest:加载Web ApplicationContext并提供模拟Web环境
    • 在测试类上添加@AutoConfigureMockMvc标定自动装配MockMvc,代码中注入MockMvc,模拟外部请求
    • 注入ObjectMapper是Jackson对外工具类,提供了Jackson序列化和反序列化json的全套服务
    • 注意一点,在模拟请求的时候添加contentType(MediaType.APPLICATION_JSON_VALUE),此方法会在请求头中添加如下健值Content-Type:"application/json;charset=UTF-8",用来想接口表明请求主题类型为json
    • 关于测试更多的详情,可见Spring Boot中单元测试详解
  • 运行测试类,可见如下详情
    MockHttpServletRequest:
         HTTP Method = POST
         Request URI = /testJson
          Parameters = {
         }
             Headers = [Content-Type:"application/json;charset=UTF-8"]
                Body = {
         "userAccount":"Joey","password":"Joey's password","age":12,"birthday":"2019-08-05T07:43:48.666+0000"}
       Session Attrs = {
         }
    
    Handler:
                Type = com.friends.springbootjson.SpringBootJsonController
              Method = public com.friends.springbootjson.User com.friends.springbootjson.SpringBootJsonController.testJson(com.friends.springbootjson.User)
    
    Async:
       Async started = false
        Async result = null
    
    Resolved Exception:
                Type = null
    
    ModelAndView:
           View name = null
                View = null
               Model = null
    
    FlashMap:
          Attributes = null
    
    MockHttpServletResponse:
              Status = 200
       Error message = null
             Headers = [Content-Type:"application/json;charset=UTF-8"]
        Content type = application/json;charset=UTF-8
                Body = {
         "userAccount":"Joey","password":"Joey's password","age":12,"birthday":"2019-08-05T07:43:48.666+0000"}
       Forwarded URL = null
      Redirected URL = null
             Cookies = []
    

三.Jackson注解:与序列化有关的注解

  1. @JsonAnyGetter注解,将拓展的map映射到实体类上
    实体类
      class  UserJsonAnyGetter  {
         
        private String userName;
        private Map<String, String> properties;
        @JsonAnyGetter
        public Map<String, String> getProperties() {
         
            return properties;
        }
    
    我们的测试类
     @Test
    public void testJsonAnyGetter() throws Exception {
         
        UserJsonAnyGetter ujg = new UserJsonAnyGetter();
        ujg.setUserName("Rose");
        Map<String, String> properties = new HashMap<>();
        properties.put("character1","geeky brother");
        properties.put("character2","biologist");
        ujg.setProperties(properties);
        String result = new ObjectMapper().writeValueAsString(ujg);
        System.out.println(result);
        assertThat(result,containsString("character1"));
        assertThat(result,containsString("character2"));
    }
    
    运行返回,可见map中的key和value都映射到了实体类中
    {
         "userName":"Rose","character2":"biologist","character1":"geeky brother"}
    
  2. @JsonGetter注解,此注解在getter方法中可替代@JsonProperty注释,替换json的key值,@JsonProperty后文有讲解
    实体类
      class  UserJsonGetter  {
         
        private String userName;
        private Integer id;
        @JsonGetter("name")
        public String getUserName() {
         
            return userName;
        }
        public void setUserName(String userName) {
         
            this.userName = userName;
        }
    
    我们的测试类
      @Test
    public void testUserJsonGetter() throws JsonProcessingException {
         
        final UserJsonGetter ujg = new UserJsonGetter("Joey",1);
        final String result = new ObjectMapper().writeValueAsString(ujg);
        System.out.println(result);
        assertThat(result, containsString("Joey"));
        assertThat(result, containsString("1"));
    }
    
    运行返回,可见userName使用了我们自定义的name
    {
         "id":1,"name":"Joey"}
    
  3. @JsonPropertyOrder注解,此注解可以指定序列化的顺序
    实体类
    @JsonPropertyOrder({
           "id","userName" })
    class  UserJsonPropertyOrder  {
         
        private String userName;
        private Integer id;
    
    我们的测试类
      @Test
    public void testUserJsonPropertyOrder() throws JsonProcessingException {
         
        final UserJsonPropertyOrder ujg = new UserJsonPropertyOrder("Joey",1
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值