JSON——学习笔记(消息转换器等)

编程入门 行业动态 更新时间:2024-10-14 00:25:00

JSON——学习笔记(消息<a href=https://www.elefans.com/category/jswz/34/1759571.html style=转换器等)"/>

JSON——学习笔记(消息转换器等)

JSON——学习笔记(消息转换器等)

  • 一、JSON介绍
    • 1.1 JSON格式规范
      • 1.1.1 对象 的表示
      • 1.1.2 数组 的表示
  • 二、JSON在JavaScript中的使用
    • 2.1 案例
    • 2.2 JSON.parse()和JSON.stringify()
    • 2.3 获取元素值
    • 2.4 添加元素
    • 2.5 元素遍历
  • 三、JSON在Java中的使用
    • 3.1 Fastjson
      • 3.1.1 常见API
      • 3.1.2 序列化&反序列化
      • 3.1.3 JSON字符串和数组互转
      • 3.1.4 取JSON字符串中的属性名或属性值
    • 3.2 Jackson
      • 3.2.1 注意事项
      • 3.2.2 常见API
      • 3.2.3 案例
  • 四、Spring MVC使用JSON
    • 4.1 JSON 依赖和消息转换器
    • 4.2 JSON 内容类型的数据返回
      • 4.2.1 方式1:使用 HttpPServletResponse指定
      • 4.2.2 方式2:使用 @ResponseBody 注解
    • 4.3 JSON 类型的请求参数匹配(@RequestBody)
    • 4.4 LocalDateTime的json格式化解决方案
      • 4.4.1 @JsonFormat 注解(方案一)
      • 4.4.2 全局配置方案(方案二)
    • 4.5 将接收时间戳或时间字符串转为 LocalDateTime

参考/摘录书籍:Spring+Spring MVC+MyBatis整合开发 著○陈学明
参考图片:来自网络/自己提供
说明:本人相关博客仅供学习参考!

一、JSON介绍

  JSON以键值对格式表示数据,它相比XML等格式更为简洁。
  JSON (JavaScript Object Notation)即JavaScript对象图谱,是一种在Web中广泛使用的数据交换格式。
  JSON是轻量级的文本数据交换格式,它独立于语言,更易理解。
  轻量级是指和XML比较,json数据体积更小(节省流量),传输更快,更易解析。
  JSON使用JavaScript语法来描述数据对象,但是JSON仍然独立于语言和平台。 目前非常多的动态编程语言(PHP,JSP,.C#等)都支持JSON。

1.1 JSON格式规范

  JSON格式可以用来表示对象和数组。
  标准JSON格式要求对象中的属性名(key)要使用双引号包起来,每个键值对之间使用逗号进行分隔。属性值可以是数字、字符串、数组或其它json对象。

1.1.1 对象 的表示

  • 使用大括号({ })表示对象;
  • 括号里面使用键值对方式添加属性,字符串的键和值分别使用双引号(")包起来。(在JS代码中,键值的双引号可以不加 【强烈要求按照标准格式书写】
  • 键和值之间使用冒号(:)分隔;
  • 多个属性之间使用逗号(,)分隔;
//JSON对象的表示示例:
{"name":"zhang liang","age":"18"}

1.1.2 数组 的表示

  • 数组用中括号([ ])包装;
  • 数组的元素可以使字符串,也可以是JSON的对象;
  • 多个元素之间也是使用逗号(,)分隔;
//JSON数组的表示示例:
["Jack Ma","Zhang SanFeng"]		//字符串元素的数组
[{"name":"zhang liang","age":"18"},{"name":"zhang liang","age":"18"}]	//JSON对象元素的数组

二、JSON在JavaScript中的使用

2.1 案例

  1. 在JavaScript中,直接以{}[]定义的JSON对象和数组变量的数据类型都是object,使用instanceof可以将二者区分。
	<script>var userObje = {"name":"zhang liang","age":"18"};	//JSON对象变量var userArray = [{"name":"li si","age":"22"},{"name":"wang wu","age":"30"}];	//JSON数组变量console.log(userObje)console.log(userArray)alert(typeof(userObje) == "object")		//true	对象数据类型的字符串alert(typeof(userArray) == "object") 	//true	数组数据类型的字符串,和对象是一样的alert(userObje instanceof Object) 		//true	JSON对象是Object对象的实例alert(userArray instanceof Array) 		//true	JSON对象是Array类型的实例</script>


2. 如果JSON对象和数组的最外层使用单引号或者双引号包起来,则这个变量就变成了一个字符串类型的变量了

	<script>var userObjeStr = '{"name":"zhang liang","age":"18"}';	//JSON对象变量-->字符串类型变量alert(typeof(userObjeStr) == "string")//truevar userArrayStr = '[{"name":"li si","age":"22"}]';		//JSON数组变量alert(typeof(userArrayStr) == "string")//trueconsole.log(userObjeStr)console.log(userArrayStr)</script>

2.2 JSON.parse()和JSON.stringify()

JSON.parse()JSON.stringify()函数实现JSON对象类型和JSON字符串类型的转换。

var userObj = JSON.parse(userObjeStr);		//JSON字符串转换为JSON对象
var userObjStr = JSON.stringify(userObj)	//JSON对象转JSON字符串
console.log(userObj)
console.log(userObjStr)

【注意】JSON.parse方法要求json串是标准json格式,即每个属性名都要用双引号包住。

2.3 获取元素值

  获取JSON对象中的属性值的两种方式:

  1. 格式对象.属性名。【如果属性包含空格的话,这种方式就不适用!】
  2. 格式对象["属性名"]。【可以处理属性包含空格的情况!】
var userObje1 = {"name":"zhang liang","age":"18"};
var userName = userObje1.name;	//属性名没有空格使用 ".属性名" 访问属性值
console.log(userName);var userObje2 = {"user name":"zhang liang","age":"18"};
var userName2 = userObje2["user name"]; //属性名有空格使用 "对象["属性名"]" 访问属性值
console.log(userName2);

  获取JSON数组中的元素的方式:

//JSON字符串元素的数组
var userArray1 = ["zhang san","li si","wang wu"];
var userName1_0 = userArray1[0];
console.log(userName1_0);	//zhang san//JSON对象元素的数组
var userArray2 = [{"name":"li si","age":"22"},{"name":"wang wu","age":"30"}];
var userName2_0 = userArray2[0].name;
var userAge2_0 = userArray2[0].age;
console.log(userName2_0);	//li si
console.log(userAge2_0);	//22

2.4 添加元素

<script>var userObj = {"name":"zhang san","age":"18"};userObj.name = "Li Si";				//修改旧的属性值userObj.birthDay = "2021-09-18";	//添加新的属性并赋值console.log(userObj);var userArray = [{"name":"Zhang San","age":"22"}];var userObj2 = {"name":"Wang Wu","age":"32"};userArray.push(userObj2);	//添加数组元素console.log(userArray);
</script>

2.5 元素遍历

【扩展】in 关键字的使用和for in 循环遍历对象的属性:

in关键字的使用

  • 作用:判断某个属性是否属于对象;
  • 格式:属性名称 in 对象名称 ;
  • 返回值:如果返回的结果为true,则表示该对象有这个属性,否则没有;

for in 循环遍历对象的属性

<script>var userObj = {"name":"zhang san","age":"18"};for(var attr in userObj){//此时attr表示对象的属性console.log(attr+'----'+userObj[attr]);}
</script>


数组对象的length 属性可以获得数组的元素个数。

var userArray = [{"name":"Zhang San","age":"22"},{"name":"Wang Wu","age":"32"}];
for (var i = 0; i < userArray.length; i++) {console.log(userArray[i]);console.log(userArray[i].name+"---"+userArray[i].age);
}

三、JSON在Java中的使用

常见JSON工具包:FastJson、Jackson

  • 序列化:就是把javaBean对象或集合转换为json字符串。
  • 反序列化:就是把json字符串转换为javaBean对象或集合。

3.1 Fastjson

  Fastjson是阿里巴巴开发的一套Java JSON库,Fastjson在所有的JavaJSON库中速度最快。使用时Maven导入配置如下:

<!-- 引入Fastjson依赖 -->
<dependency><groupId>com.alibaba</groupId>      <!-- 组名 --><artifactId>fastjson</artifactId>   <!-- 组件名 --><version>1.2.78</version>           <!-- 版本 -->
</dependency>

3.1.1 常见API

方法描述
public static final Object parse(String text)把JSON文本parse为JSONObject或者JSONArray
public static final JSONObject parseObject(String text)把JSON文本parse成JSONObject
public static final T parseObject(String text, Class<T> clazz)把JSON文本parse为JavaBean(反序列化)
public static final JSONArray parseArray(String text)把JSON文本parse成JSONArray
public static final List parseArray(String text, Class<T> clazz)把JSON文本parse成JavaBean集合
public static final Object toJSON(Object javaObject)将JavaBean转换为JSONObject或者JSONArray
public static final String toJSONString(Object object)将JavaBean序列化为JSON文本(序列化)
public static final String toJSONString(Object object, boolean prettyFormat)将JavaBean序列化为带格式的JSON文本

3.1.2 序列化&反序列化

//序列化//toJSONString(Object object):将JavaBean对象或集合序列化为JSON文本//toJSONString(Object object, boolean prettyFormat):将JavaBean对象或集合序列化为带格式的JSON文本@Testpublic void test1(){User u1 = new User(1001,"许褚","上海浦东新区");User u2 = new User(1002,"小红","安徽省合肥市");List<User> userList = Arrays.asList(u1, u2);String u1Str = JSON.toJSONString(u1);String uListStr = JSON.toJSONString(userList);System.out.println("u1Str:"+u1Str);System.out.println("uListStr:"+uListStr);//带格式的JSON文本String u1StrFormat = JSON.toJSONString(u1, true);String uListStrFormat = JSON.toJSONString(userList, true);System.out.println(u1StrFormat);System.out.println(uListStrFormat);}

//反序列化//parseObject(String text, Class<T> clazz); // 把JSON文本转换为JavaBean对象//parseArray(String text, Class<T> clazz); //把JSON文本转换成JavaBean的集合//不要求Json串里是标准的json格式【注意!!】@Testpublic void test2(){String jsonStr = "{\"address\":\"上海浦东新区\",\"id\":1001,\"name\":\"许褚\"}";String jsonListStr = "[{\"address\":\"上海浦东新区\",\"id\":1001,\"name\":\"许褚\"},{\"address\":\"安徽省合肥市\",\"id\":1002,\"name\":\"小红\"}]";//JSON文本 --> JavaBean对象User user = JSON.parseObject(jsonStr, User.class);System.out.println("user:"+user);//JSON文本 --> JavaBean集合List<User> userList = JSON.parseArray(jsonListStr,User.class);System.out.println("userList:"+userList);}

3.1.3 JSON字符串和数组互转

@Test
public void test0(){int[] ints = {1,2,3,4,5};//整型数组转换为JSON数组字符串String arrayJsonStr = JSON.toJSONString(ints);System.out.println(arrayJsonStr);//[1,2,3,4,5]//数组字符串转换为整型数组int[] intsNew = JSON.parseObject(arrayJsonStr,ints.getClass());System.out.println(intsNew);//[I@262b2c86
}

3.1.4 取JSON字符串中的属性名或属性值

@Test
void test2(){String str = "";String keyProps = "{\"颜色\":\"玛莎拉蒂红\",\"配置\":\"(经典版,前碟后鼓,60/72V通用,裸车)\"}";HashMap map = JSON.parseObject(keyProps, LinkedHashMap.class);for (Object o : map.keySet()) {str += map.get(o);}System.out.println(str);
}

运行结果

3.2 Jackson

  Jackson可以将Java对象转换成JSON对象和XML文档,同样也可以价格JSON对象和XML文档转换为Java对象。其三个依赖包为:

  • jackson-core :核心包
  • jackson-annotations :注解功能包
  • jackson-databind :数据绑定包

使用时Maven导入配置如下:

<!-- 引入jackson依赖(提供转换器,把bean或集合转换为json串) -->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.0</version>
</dependency>

3.2.1 注意事项

  • 默认情况下,ObjectMapper 在序列化对象时,将实体所有的字段一 一序列化,无论这些字段是否有值,是否为 null。
  • 如果实体中的某个字段没有提供 getter 方法,则该字段不会被序列化。
  • 操作JSON:databind(数据绑定) - ObjectMapper实例 读/写 JSON 是 POJO 序列化与反序列化 json 最方便的方式。(还有额外两种方式)

  Jackson使用对象封装器类(ObjectMapper)实例对对象和数组类型进行转换;writeValueAsString()将Java对象、数组和集合类型对象转换为JSON对象和数组字符串;readValue使用JSON格式字符串转换成Java对象。【ObjectMapper 主要用于对 Java 对象(例如 POJO、List、Set、Map 等)进行序列化与反序列化】

3.2.2 常见API

方法描述
void writeValue(File resultFile, Object value)将 java 对象序列化并写入指定文件中
String writeValueAsString(Object value)1. 将Java对象、数组、集合转换为JSON对象和数组字符串;
2. 如果 value 为 null,返回序列化的结果也返回 null;
T readValue(String jsonStr, Class<T> valueType)1. 从给定的 JSON 字符串反序列化为 Java 对象;
2. 如果jsonStr为空或者null,都会报错;
3. valueType 表示反序列化的结果对象,可以是任何 java 对象(POJO、Array、List、Set、Map 等)
T readValue(File src, Class<T> valueType)将本地 json 内容的文件反序列化为 java 对象

3.2.3 案例

//序列化【把JavaBean对象或集合转换为json字符串】@Testpublic void test1(){User u1 = new User(1001,"许褚","上海浦东新区");User u2 = new User(1002,"小红","安徽省合肥市");List<User> userList = Arrays.asList(u1, u2);//对象封装器类ObjectMapper objectMapper = new ObjectMapper();try {//javabean对象转序列化【调用:objectMapper.writeValueAsString(beanObj或者listObj)】String u1Str = objectMapper.writeValueAsString(u1);//集合序列化String uListStr = objectMapper.writeValueAsString(userList);System.out.println("u1Str: "+u1Str);System.out.println("uListStr: "+uListStr);} catch (JsonProcessingException e) {e.printStackTrace();}}

//反序列化就是把json字符串转换为javaBean对象或集合。@Testpublic void test2(){//readValue(String jsonStr, Class<T>  cls):转换为javaBean对象//【要求】Json串里是标准的json格式("属性名")String jsonStr = "{\"id\":1001,\"name\":\"许褚\",\"address\":\"上海浦东新区\"}";//对象封装器类ObjectMapper objectMapper = new ObjectMapper();try {User user = objectMapper.readValue(jsonStr,User.class);System.out.println("user:"+user);} catch (IOException e) {e.printStackTrace();}//readValue(String jsonStr, JavaType javaType):转换为集合//【要求】Json串里是标准的json格式("属性名")String jsonList = "[{\"id\":1001,\"name\":\"许褚\",\"address\":\"上海浦东新区\"},{\"id\":1002,\"name\":\"小红\",\"address\":\"安徽省合肥市\"}]";JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class,User.class);try {List<User> userList = objectMapper.readValue(jsonList,javaType);for (User user : userList) {System.out.println("userList中的user:"+user);}} catch (IOException e) {e.printStackTrace();}}

详细可参考:Jackson API详细汇总

四、Spring MVC使用JSON

  浏览器页面局部以Ajax返回 application/json 内容类型的JSON数据响应,前端结合数据更新来刷新页面局部;
  Spring MVC 支持不同内容类型的处理请求;使用 HTTP 消息转换器(HttpMessageConverter)对前端请求内容和响应进行转换。spring-web 模块中提供了 JSON 类型的 HTTP 消息转换器子类,底层使用 Jackson 或 Gson 库进行 JSON 类型和 Java 对象类型的转换,对应的消息转换器类分别为:MappingJackson2HttpMessageConverterGsonHttpMessageConverter 。使用不同的 JSON 消息转换器需要导入对应的 JSON 依赖包。

4.1 JSON 依赖和消息转换器

  Spring Boot默认使用JSON作为响应格式,自带Jackson库进行转换。
  Spring MVC没有自带JSON数据转换包,但提供了Jackson的HTTP消息转换器,需要导入Jackson依赖。Jackson消息转换器一般不需要配置,自定义设置的话可以通过<mvc:annotation-driven>的<mvc:message-converters>子标签进行配置。

<!-- 注解驱动(会自动注册映射处理器和处理器适配器和参数转换注解) -->
<mvc:annotation-driven><!-- MVC 消息转换器配置,配置不同的消息转换器类的 Bean --><mvc:message-converters><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /><bean class="org.springframework.http.converter.json.GsonHttpMessageConverter" /></mvc:message-converters>
</mvc:annotation-driven>

  也可以使用 FastJson 作为 Spring MVC 的 HTTP 消息转换器。Spring MVC 默认没有提供其对应的消息转换器,但 FastJson 提供了 Spring 使用转换器类,所以除了导入依赖包之外,还需要配置相应的转换器 Bean。如下:

<!-- 注解驱动(会自动注册映射处理器和处理器适配器和参数转换注解) -->
<mvc:annotation-driven><!-- MVC 消息转换器配置,配置不同的消息转换器类的 Bean --><mvc:message-converters><!-- FastJson 消息转换器 Bean --><bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter" ><!-- 支持的内容类型 --><property name="supportedMediaTypes" ><list><value>text/html;charset=UTF-8</value><!-- JSON格式的数据类型 --><value>application/json;charset=UTF-8</value></list></property></bean></mvc:message-converters>
</mvc:annotation-driven>

备注:Java版的配置只需要在配置类(@Configuration,@Component等注解标注的类)添加该消息转换器的Bean组件即可。如下:

@Configuration
public class SpringApplicationConfig {/*** 将Message的有效负载从序列化形式转换为类型化对象的转换器,反之亦然。* @return 指定的消息转换器的实现类*/@Beanpublic MessageConverter messageConverter(){return new MappingJackson2MessageConverter();}}

4.2 JSON 内容类型的数据返回

  导入 JSON 依赖包,并将 Java 对象转换为 JSON 字符串后,就可以使用 response 对象返回 application/json 内容类型的 JSON 字符串。结合消息转换器,可以在控制器类和映射方法中使用 @ResponseBody 注解,由容器自动处理 Java 对象的转换并返回。

4.2.1 方式1:使用 HttpPServletResponse指定

  通过 HttpServletResponse 指定返回的内容类型为 application/json 的字符串。使用 response.getWriter().wirite()response.getOutputStream().print() 都可以将 Json字符串响应到前端。

@GetMapping("getJsonData")
public void jsonResponse(HttpServletResponse resp,HttpServletRequest req) throws Exception{//将发送到客户端的响应的字符编码(MIME 字符集)设置为 UTF-8resp.setCharacterEncoding("UTF-8");//设置发送到客户端的响应的内容类型resp.setContentType("application/json");User user = new User(1001,"Li Hua",18);//将 Jackson 的 ObjectMapper 转换实例ObjectMapper mapper = new ObjectMapper();//将 Java 对象转换为 JSON 字符串String userJsonStr = mapper.writeValueAsString(user);//从 response 对象获取 PrintWriter 输出流对象PrintWriter out = resp.getWriter();//往对象中写入一个字符串out.write(userJsonStr);//将缓冲输出到页面out.flush();
}
@GetMapping("getJsonData")
public void jsonResponse(HttpServletResponse resp,HttpServletRequest req) throws Exception{//将发送到客户端的响应的字符编码(MIME 字符集)设置为 UTF-8resp.setCharacterEncoding("UTF-8");//设置发送到客户端的响应的内容类型resp.setContentType("application/json");User user = new User(1001,"Li Hua",18);//将 Jackson 的 ObjectMapper 转换实例ObjectMapper mapper = new ObjectMapper();//将 Java 对象转换为 JSON 字符串String userJsonStr = mapper.writeValueAsString(user);//从 response 对象获取 PrintWriter 输出流对象PrintWriter out = resp.getWriter();//通过输出流 OutPutStream 对象输出字符串resp.getOutputStream().print(userJsonStr);//将缓冲输出到页面resp.getOutputStream.flush();
}

4.2.2 方式2:使用 @ResponseBody 注解

  @ResponseBody 可以使用在映射注解的方法上,容器内部通过 HttpMessageConverter 将方法返回的 Java 对象转化为 JSON 字符串后写入 Response 对象的 body 数据体中。

@ResponseBody
@GetMapping("getJsonDataAnnotation")
public User respUserJsonStr(){return new User(2002,"Li Bai",500);
}

【拓展】

  1. @ResponseBody 使用在控制器类中是,则该控制器所有的请求映射方法都是 JSON 类型的返回。
  2. @RestController 注解= @Controller 注解+@ResponseBody 注解的组合。

4.3 JSON 类型的请求参数匹配(@RequestBody)

  在 Spring MVC 的请求映射方法参数中,使用 @RequestParam 注解或不使用注解,Spring MVC 容器会自动进行参数的匹配并组装成对应的方法参数定义的类对象。
  默认情况下请求参数传递的内容类型是 application/x-www-form-urlencode,参数以键值对的方式传递(如:id=“1001”&name=“zhagnsan”)。如果需要传递 JSON 类型的请求参数,需要设定请求头的 ContentType : "application/json" ,后端方法参数使用 @RequestBody 注解进行匹配。

浏览器端

<script>//标准 json 字符串格式var loginUser = {"loginId":10001,"loginName":"zhang san"}$.ajax({url : "login",  //请求的 URL 地址type : "post",  //请求方法async : true,   //异步设置contentType : "application/json",   //设置发送到客户端的响应的内容类型data : JSON.stringify(loginUser),   //JSON对象转JSON字符串(发送到服务器的数据)dataType : 'json',  //从服务器返回的数据类型success : function(data){//请求成功后的回调方法,data就是返回的数据}})
</script>

服务端

/*** 此时该注解将请求体中的json绑定到对象的属性上*/
@GetMapping("login")
public User getUserWithJson(@RequestBody User user){return user;
}

4.4 LocalDateTime的json格式化解决方案

如果想要让返回的json数据中,LocalDateTime类型是按照 yyyy-MM-dd HH:mm:ss 格式显示,有两种方案:

4.4.1 @JsonFormat 注解(方案一)

该方案局部生效

//如果时区显示不正确的话,可以添加timezone属性,如下:
//timezone = "GMT+8" 或 timezone = "Asiz/Shanghai"
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private LocalDateTime createTime;

4.4.2 全局配置方案(方案二)

该方案使用一个配置类,全局生效

1)在全局配置文件中配置(application.yml):

spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: Asia/Shanghai #或 GMT+8

2)写一个配置类:

@Configuration
public class LocalDateTimeSerializerConfig {@Value("${spring.jackson.date-format}")private String pattern;public LocalDateTimeSerializer localDateTimeSerializer(){return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));}@Beanpublic Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer(){//serializerByType:为给定类型配置自定义序列化程序。return builder -> builder.serializerByType(LocalDateTime.class,localDateTimeSerializer());}}

4.5 将接收时间戳或时间字符串转为 LocalDateTime

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime frontImageTime;

备注:

  • @JsonFormat:主要是后台到前台的时间格式的转换;
  • @DataFormat:主要是前后到后台的时间格式的转换;

更多推荐

JSON——学习笔记(消息转换器等)

本文发布于:2024-03-23 20:26:58,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1742464.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:转换器   学习笔记   消息   JSON

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!