SpringMVC-05-Json

打印 上一主题 下一主题

主题 923|帖子 923|积分 2773

1、什么是JSON?

JSON: JavaScript Object Notation(JS 对象描述法)。
JSON 是一种存储和交换数据的语法。
JSON 是通过 JS对象描述法书写的文本,用字面文本的形式来表示一个JS对象
2、为什么要使用JSON?


  • JSON 是一种轻量级的数据交换格式,伴随着JavaScript语言的火爆,现在使用特别广泛
  • 采用完全独立于编程语言的文本格式来存储和表示数据。
  • 简洁和清楚的层次结构使得 JSON 成为理想的数据交换语言。
  • 易于人阅读和编写,同时也易于机器剖析和生成,并有效地提升网络传输服从
3、如何使用JSON?

在 JavaScript 语言中,一切都是对象。因此,任何JavaScript 支持的范例都可以通过 JSON 来表示,比方字符串、数字、对象、数组等。看看它的要求和语法格式:

  • 花括号表示对象
    1. {"name": "MoonDream"}
    复制代码
  • 方括号表示数组
    1. [{"name": "MoonDream"},{"age": 20},{"sex": "男"}]
    复制代码
  • 对象的属性用键值对来表示,多个属性间用逗号分隔
    1. {"name": "MoonDream","age": 20,"sex": "男"}
    复制代码
JSON 和 JavaScript 对象的关系
  1. var obj = {a: 'Hello', b: 'World'}; //这是一个js对象,使用json语法构造,注意键名也是可以使用引号包裹的
  2. var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON字符串,符合json语法规则,本质是一个字符串
复制代码
JSON 和 JavaScript 对象互转

  • JSON字符串 -> JavaScript 对象
    1. var obj = JSON.parse('{"a": "Hello", "b": "World"}');
    2. //结果是 {a: 'Hello', b: 'World'}
    复制代码
  • JavaScript 对象 -> JSON字符串
    1. var json = JSON.stringify({a: 'Hello', b: 'World'});
    2. //结果是 '{"a": "Hello", "b": "World"}'
    复制代码
代码测试

  • 新建一个module ,SpringMVC-05-Json , 添加web的支持
  • 在web目次下新建一个 json-1.html , 编写测试内容
    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4.     <meta charset="UTF-8">
    5.     <title>JSON-Test</title>
    6. </head>
    7. <body>
    8. </body>
    9. </html>
    复制代码
    在IDEA中使用欣赏器打开,检察控制台输出!

    以上只是JSON的简略用法,详细请看 JSON  (w3school.com.cn)
4、在SpringMVC中使用JSON

这里我们主要使用两个第三方工具库:Jackson 与 FastJson
Jackson

底子使用


  • 导入jar包
    1. <dependency>
    2.     <groupId>com.fasterxml.jackson.core</groupId>
    3.     <artifactId>jackson-databind</artifactId>
    4.     <version>2.9.8</version>
    5. </dependency>
    复制代码
  • 配置SpringMVC所需配置
    web.xml
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4.          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5.          version="4.0">
    6.     <servlet>
    7.         <servlet-name>DispatcherServlet</servlet-name>
    8.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    9.         <init-param>
    10.             <param-name>contextConfigLocation</param-name>
    11.             <param-value>classpath:spring-mvc.xml</param-value>
    12.         </init-param>
    13.         <load-on-startup>1</load-on-startup>
    14.     </servlet>
    15.     <servlet-mapping>
    16.         <servlet-name>DispatcherServlet</servlet-name>
    17.         <url-pattern>/</url-pattern>
    18.     </servlet-mapping>
    19.     <filter>
    20.         <filter-name>Encoding</filter-name>
    21.         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    22.         <init-param>
    23.             <param-name>encoding</param-name>
    24.             <param-value>utf-8</param-value>
    25.         </init-param>
    26.     </filter>
    27.     <filter-mapping>
    28.         <filter-name>Encoding</filter-name>
    29.         <servlet-name>DispatcherServlet</servlet-name>
    30.     </filter-mapping>
    31. </web-app>
    复制代码
    spring-mvc.xml
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4.        xmlns:context="http://www.springframework.org/schema/context"
    5.        xmlns:mvc="http://www.springframework.org/schema/mvc"
    6.        xsi:schemaLocation="
    7.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    8.        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
    9.        http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
    10. ">
    11.     <context:component-scan base-package="com.moondream.controller"/>
    12.     <bean >
    13.         <property name="prefix" value="/WEB-INF/jsp"/>
    14.         <property name="suffix" value=".jsp"/>
    15.     </bean>
    16. </beans>
    复制代码
  • 编写User实体类,用于测试
    1. package com.moondream.pojo;
    2. import lombok.AllArgsConstructor;
    3. import lombok.Data;
    4. import lombok.NoArgsConstructor;
    5. //需要导入lombok
    6. @NoArgsConstructor
    7. @AllArgsConstructor
    8. @Data
    9. public class User {
    10.     private String name;
    11.     private Integer age;
    12.     private String sex;
    13. }
    复制代码
  • 编写Controller,使用Jackson
    1. @Controller
    2. public class UserController {
    3.     @ResponseBody
    4.     @RequestMapping(value = "/json1")
    5.     public String json1() throws JsonProcessingException {
    6.         //创建一个jackson的对象映射器,用来解析数据
    7.         ObjectMapper mapper = new ObjectMapper();
    8.         //创建一个对象
    9.         User user = new User("用户1号", 3, "男");
    10.         //将我们的对象解析成为json格式字符串
    11.         String str = mapper.writeValueAsString(user);
    12.         System.out.println(str);
    13.         return str;
    14.     }
    15. }
    复制代码
  • 配置Tomcat,启动测试
    http://localhost:8080/spring05/json1


  • 出现乱码问题,很显着可以看出是发送响应时,编码出现问题。
    可以通过@RequestMapping 的 produces 属性 指定该 Handler 响应的内容范例,
    详见RequestMapping 中produces 和 consumes
    1. //produces:指定响应的内容类型
    2. @RequestMapping(value = "/json1",produces = "application/json;charset=utf-8")
    复制代码
  • 再次测试, http://localhost:8080/spring05/json1 , 乱码问题OK!

代码优化


  • 乱码问题
    其上使用@RequestMapping 的 produces 属性的方法比较贫苦,如果项目中有很多请求则每一个都要添加。
    我们可以在类上也标注一个@RequestMapping,作为方法上@RequestMapping的前置注解。
    这样,在这个类中,就不用每次都去处理了。
    1. @Controller
    2. @RequestMapping(produces = "application/json;charset=utf-8")
    3. public class UserController {
    4.     @ResponseBody
    5.     @RequestMapping(value = "/json1")
    6.     public String json1() throws JsonProcessingException {
    7.         //创建一个jackson的对象映射器,用来解析数据
    8.         ObjectMapper mapper = new ObjectMapper();
    9.         //创建一个对象
    10.         User user = new User("用户1号", 3, "男");
    11.         //将我们的对象解析成为json格式字符串
    12.         String str = mapper.writeValueAsString(user);
    13.         System.out.println(str);
    14.         return str;
    15.     }
    16. }
    复制代码
  • @ResponseBody重复编写问题
    与乱码问题解决类似,也是在类上标注@ResponseBody注解,提升作用域。
    然后,类上的 @ResponseBody 与 @Controller 可以构成组合注解 @RestController
    类被标注了 @RestController ,就相当于被标注了 @ResponseBody 与 @Controller。
    1. @RestController
    2. @RequestMapping(produces = "application/json;charset=utf-8")
    3. public class UserController {
    4.     @RequestMapping(value = "/json1")
    5.     public String json1() throws JsonProcessingException {
    6.         //创建一个jackson的对象映射器,用来解析数据
    7.         ObjectMapper mapper = new ObjectMapper();
    8.         //创建一个对象
    9.         User user = new User("用户1号", 3, "男");
    10.         //将我们的对象解析成为json格式字符串
    11.         String str = mapper.writeValueAsString(user);
    12.         System.out.println(str);
    13.         return str;
    14.     }
    15. }
    复制代码
启动tomcat测试,结果都正常输出!
测试集合输出

增加一个新的方法
  1.     @RequestMapping(value = "/json2")
  2.     public String json2() throws JsonProcessingException {
  3.         //创建一个jackson的对象映射器,用来解析数据
  4.         ObjectMapper mapper = new ObjectMapper();
  5.         //创建一个对象
  6.         User user1 = new User("用户1号", 4, "男");
  7.         User user2 = new User("用户2号", 3, "女");
  8.         User user3 = new User("用户3号", 2, "武装直升机");
  9.         User user4 = new User("用户4号", 1, "沃尔玛购物袋");
  10.         List<User> list = new ArrayList<>();
  11.         list.add(user1);
  12.         list.add(user2);
  13.         list.add(user3);
  14.         list.add(user4);
  15.         //将我们的对象解析成为json格式
  16.         String str = mapper.writeValueAsString(list);
  17.         System.out.println(str);
  18.         return str;
  19.     }
复制代码
运行结果 : 十分完美,没有任何问题!

输出时间对象

增加一个新的方法
  1.     @RequestMapping("/json3")
  2.     public String json3() throws JsonProcessingException {
  3.         //创建一个jackson的对象映射器,用来解析数据
  4.         ObjectMapper mapper = new ObjectMapper();
  5.         //创建时间一个对象,java.util.Date
  6.         Date date = new Date();
  7.         //将我们的对象解析成为json格式
  8.         String str = mapper.writeValueAsString(date);
  9.         System.out.println(str);
  10.         return str;
  11.     }
复制代码
运行结果 :


  • 默认日期格式会变成一个数字,是1970年1月1日到当前日期的毫秒数!
  • Jackson 默认是会把时间转成timestamps形式
解决方案:取消timestamps形式 , 自界说时间格式
  1.     @RequestMapping("/json4")
  2.     public String json4() throws JsonProcessingException {
  3.         ObjectMapper mapper = new ObjectMapper();
  4.         //不使用时间戳的方式
  5.         mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
  6.         //自定义日期格式对象
  7.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  8.         //指定日期格式
  9.         mapper.setDateFormat(sdf);
  10.         Date date = new Date();
  11.         String str = mapper.writeValueAsString(date);
  12.         System.out.println(str);
  13.         return str;
  14.     }
复制代码
运行结果 : 成功的输出了相应的格式化时间!

抽取为工具类

如果要经常使用的话,这样是比较贫苦的,我们可以将这些代码封装到一个工具类中;我们去编写下
  1. package com.moondream.util;
  2. import com.fasterxml.jackson.core.JsonProcessingException;
  3. import com.fasterxml.jackson.databind.ObjectMapper;
  4. import com.fasterxml.jackson.databind.SerializationFeature;
  5. import java.text.SimpleDateFormat;
  6. import java.util.Date;
  7. public class JsonUtils {
  8.     public static String getCommonJson(Object object) throws JsonProcessingException {
  9.         ObjectMapper objectMapper = new ObjectMapper();
  10.         return objectMapper.writeValueAsString(object);
  11.     }
  12.     public static String getDateJson(Date date) throws JsonProcessingException {
  13.         return getDateJson(date, "yyyy-MM-dd HH:mm:ss");
  14.     }
  15.     public static String getDateJson(Date date, String dateFormat) throws JsonProcessingException {
  16.         ObjectMapper objectMapper = new ObjectMapper();
  17.         objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
  18.         objectMapper.setDateFormat(new SimpleDateFormat(dateFormat));
  19.         return objectMapper.writeValueAsString(date);
  20.     }
  21. }
复制代码
我们使用工具类,代码就更加简洁了!
  1.     @RequestMapping("/json5")
  2.     public String json5() throws JsonProcessingException {
  3.         Date date = new Date();
  4.         String json = JsonUtils.getDateJson(date);
  5.         System.out.println(json);
  6.         return json;
  7.     }
复制代码
高级使用

我们解决乱码问题和使用 Jackson 也可以在Spring体系内进行。
在 spring-mvc.xml 中,添加配置:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xmlns:context="http://www.springframework.org/schema/context"
  5.        xmlns:mvc="http://www.springframework.org/schema/mvc"
  6.        xsi:schemaLocation="
  7.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  8.        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
  9.        http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
  10. ">
  11.     <context:component-scan base-package="com.moondream.controller"/>
  12.     <bean >
  13.         <property name="prefix" value="/WEB-INF/jsp"/>
  14.         <property name="suffix" value=".jsp"/>
  15.     </bean>
  16. </beans><?xml version="1.0" encoding="UTF-8"?>
  17. <beans xmlns="http://www.springframework.org/schema/beans"
  18.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  19.        xmlns:context="http://www.springframework.org/schema/context"
  20.        xmlns:mvc="http://www.springframework.org/schema/mvc"
  21.        xsi:schemaLocation="
  22.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  23.        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
  24.        http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
  25. ">
  26.     <context:component-scan base-package="com.moondream.controller"/>
  27.     <bean >
  28.         <property name="prefix" value="/WEB-INF/jsp"/>
  29.         <property name="suffix" value=".jsp"/>
  30.     </bean>
  31. </beans><?xml version="1.0" encoding="UTF-8"?>
  32. <beans xmlns="http://www.springframework.org/schema/beans"
  33.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  34.        xmlns:context="http://www.springframework.org/schema/context"
  35.        xmlns:mvc="http://www.springframework.org/schema/mvc"
  36.        xsi:schemaLocation="
  37.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  38.        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
  39.        http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
  40. ">
  41.     <context:component-scan base-package="com.moondream.controller"/>
  42.     <bean >
  43.         <property name="prefix" value="/WEB-INF/jsp"/>
  44.         <property name="suffix" value=".jsp"/>
  45.     </bean>
  46. </beans><?xml version="1.0" encoding="UTF-8"?>
  47. <beans xmlns="http://www.springframework.org/schema/beans"
  48.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  49.        xmlns:context="http://www.springframework.org/schema/context"
  50.        xmlns:mvc="http://www.springframework.org/schema/mvc"
  51.        xsi:schemaLocation="
  52.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  53.        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
  54.        http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
  55. ">
  56.     <context:component-scan base-package="com.moondream.controller"/>
  57.     <bean >
  58.         <property name="prefix" value="/WEB-INF/jsp"/>
  59.         <property name="suffix" value=".jsp"/>
  60.     </bean>
  61. </beans><?xml version="1.0" encoding="UTF-8"?>
  62. <beans xmlns="http://www.springframework.org/schema/beans"
  63.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  64.        xmlns:context="http://www.springframework.org/schema/context"
  65.        xmlns:mvc="http://www.springframework.org/schema/mvc"
  66.        xsi:schemaLocation="
  67.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  68.        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
  69.        http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
  70. ">
  71.     <context:component-scan base-package="com.moondream.controller"/>
  72.     <bean >
  73.         <property name="prefix" value="/WEB-INF/jsp"/>
  74.         <property name="suffix" value=".jsp"/>
  75.     </bean>
  76. </beans><?xml version="1.0" encoding="UTF-8"?>
  77. <beans xmlns="http://www.springframework.org/schema/beans"
  78.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  79.        xmlns:context="http://www.springframework.org/schema/context"
  80.        xmlns:mvc="http://www.springframework.org/schema/mvc"
  81.        xsi:schemaLocation="
  82.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  83.        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
  84.        http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
  85. ">
  86.     <context:component-scan base-package="com.moondream.controller"/>
  87.     <bean >
  88.         <property name="prefix" value="/WEB-INF/jsp"/>
  89.         <property name="suffix" value=".jsp"/>
  90.     </bean>
  91. </beans>               
复制代码
配置阐明:

  • :配置一个或多个消息转换器,用于转换@RequestBody方法参数和@ResponseBody方法返回值。
    此处提供的消息转换器注册将优先于默认注册的消息转换器。如果要完全关闭默认注册,请参阅register-defaults属性。
  • StringHttpMessageConverter:用于String值的消息转换器,用来转换字符串编码。
  • MappingJackson2HttpMessageConverter:Jackson集成的消息转换器,用来将支持的范例(如:实体类、日期、各种集合……)和 JSON字符串 互转。
注意:Spring每次需要使用消息转换器时,只会从消息转换列表中,挑选一个合适的消息转换器执行,多个消息转换器合适,则使用先注册的。
测试:
  1.     @RequestMapping("/json6")
  2.     public String json6() {
  3.         return "中文乱码测试";
  4.     }
  5.     @RequestMapping("/json7")
  6.     public User json7() {
  7.         User user = new User("用户1号", 3, "男");
  8.         return user;
  9.     }
  10.     @RequestMapping("/json8")
  11.     public Date json8() {
  12.         Date date = new Date();
  13.         return date;
  14.     }
复制代码
运行结果:完美无误!



看结果显而易见,
json6处 使用的消息转换器是StringHttpMessageConverter,
因为其最先注册,
而且MappingJackson2HttpMessageConverter仅对响应内容范例为 application/json 的响应体字符串 适配,
此处并不适用;
json7、json8处 使用的消息转换器是MappingJackson2HttpMessageConverter,
本来@ResponseBody方法仅支持寥寥几个范例(即 void、String、ResponseEntity……)作为返回值,
但使用了MappingJackson2HttpMessageConverter之后,可以支持更多的范例作为返回值,
因为MappingJackson2HttpMessageConverter会将返回值都转换成JSON字符串,即String范例,
转换后使用的编码默以为UTF-8
参考详见:
消息转换器 :: Spring 框架 - Spring 中文 (springframework.org.cn)
HTTP消息转换器MappingJackson2HttpMessageConverter生效的几种方式。- 掘金 (juejin.cn)
FastJson

fastjson.jar是阿里开辟的一款专门用于Java开辟的包,可以方便的实现

  • JSON对象与JavaBean对象的转换,
  • JavaBean对象与json字符串的转换,
  • JSON对象与json字符串的转换。
实现json的转换方法很多,最后的实现结果都是一样的。
pom依靠
  1. <dependency>
  2.     <groupId>com.alibaba</groupId>
  3.     <artifactId>fastjson</artifactId>
  4.     <version>1.2.4</version>
  5. </dependency>
复制代码
三个主要的类


  • 【JSONObject】json对象的类界说化

    • 实现了Map接口,具备Map特性,底层操作由Map实现。
    • 对应json对象,通过各种形式的get()方法可以获取json对象中的数据,也可利用诸如size(),isEmpty()等方法获取”键:值”对的个数和判断是否为空。其本质是通过实现Map接口并调用接口中的方法完成的。

  • 【JSONArray】json对象数组的类界说化

    • 实现了List接口,通过List接口中的方法来完成操作。

  • 【JSON】FastJson中的工具类和各种类的超类

    • 常用于调用各种功能方法,实现转换操作。

代码测试

新建一个FastJsonDemo 类
  1. package com.moondream;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.moondream.pojo.User;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. public class FastJsonDemo {
  8.     public static void main(String[] args) {
  9.         //创建一个对象
  10.         User user1 = new User("用户1号", 4, "男");
  11.         User user2 = new User("用户2号", 3, "女");
  12.         User user3 = new User("用户3号", 2, "武装直升机");
  13.         User user4 = new User("用户4号", 1, "沃尔玛购物袋");
  14.         List<User> list = new ArrayList<>();
  15.         list.add(user1);
  16.         list.add(user2);
  17.         list.add(user3);
  18.         list.add(user4);
  19.         System.out.println("*******Java对象 转 JSON字符串*******");
  20.         String str1 = JSON.toJSONString(list);
  21.         System.out.println(str1);
  22.         String str2 = JSON.toJSONString(user1);
  23.         System.out.println(str2);
  24.         System.out.println("\n****** JSON字符串 转 Java对象*******");
  25.         User jp_user1 = JSON.parseObject(str2, User.class);
  26.         System.out.println(jp_user1);
  27.         System.out.println("\n****** Java对象 转 JSON对象 ******");
  28.         JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
  29.         System.out.println(jsonObject1.getString("name"));
  30.         System.out.println("\n****** JSON对象 转 Java对象 ******");
  31.         User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
  32.         System.out.println(to_java_user);
  33.     }
  34. }
复制代码
运行结果:

这种工具类,我们只需要把握使用就好了,在使用的时候在根据详细的业务去找对应的实现。和以前的commons-io那种工具包一样,拿来用就好了!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王國慶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表