【SpringMVC】学习笔记06-JSON
前后端分离时代:
后端是部署后端,提供接口;提供数据
前端独立部署,负责渲染后端的数据
什么是JSON?
- JSON(JavaScript Object Natation JS 对象标记)是一种轻量级的数据交换格式,目前使用特别广泛。
- 采用完全独立于编程语言的文本格式来存储和表示数据。
- 易于人阅读和编写,同时也易于机器解析和生成,并有效地提高网络传输效率。
在JavaScript语言中,一切都是对象。因此,任何JavaScript支持的类型都可以通过JSON来表示,例如:字符串,数字,对象,数组等。看看他的要求和语法格式:
- 对象表示为键值对,数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
JSON键值对 是用来保存JavaScript对象的一种方式,和JavaScript对象的写法也大同小异,键/值对组合中的键名写在前面并用双引号“”包裹,使用冒号:分隔,然后紧跟着值。
{“name”:"wangguangyuan1"}
{"age":"3"}
{"sex":"男"}
很多人搞不懂JSON和JavaScript对象的关系,甚至连谁和谁是谁都搞不清楚.其实,可以这么理解:
JSON是JavaScript对象的字符表示法,它使用文本表示一个JS对象的信息,本质上是一个字符串。
var obj={a:'Hello',b:'World'};//这是一个对象,注意键名也是可以使用引号包裹的
var json='{"a":"Hello","b":"World"}';//这是一个JSON字符串,本质上是一个字符串
JSON和JavaScript对象互转
要实现从JSON字符串转换为JavaScript对象,使用JSON.parse()方法。
var obj=JSON.parse('{"a":"Hello","b":"World"}'); //结果为{a:'Hello',b:'World'}
要实现JavaScript对象转换为JSON字符串,使用JSON.stringify()方法:
var json=JSON.stringify({a:'Hello',b:'World'}) //结果是'{"a":"Hello","b":"World"}'
Controller返回JSON数据
Jackson
Jackson应该是目前比较好的json解析工具了
当然工具不止一个,比如还有阿里巴巴的fastjson等等
这里我们使用Jackson,使用它需要导入它的jar包
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency>
相应web,xml和springmvc-content.xml配置
web,xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:Springmvc-content.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
springmvc-content.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:mbv="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理--> <context:component-scan base-package="com.wang.Controller"/> <!-- 让SpringMVC不处理静态资源 .css .js .html .mp3 .mp4--> <mvc:default-servlet-handler/> <!-- 支持mvc注解驱动 在spring中一般采用@ReuqestMapping注解来完成映射 要想使@RequestMapping注解完成映射关系 必须向上下文中注册 DefaultAnnotationHandlerMapping 和一个AnnotationMethodHandlerAdapter实例 这里个实例分别在类级别和方法级别处理。 而annotation-dirven配置 帮助我们自动完成上述两个实例的注入 --> <mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> </bean> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper"> <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"> <property name="failOnEmptyBeans" value="false"/> </bean> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
User实体类
package com.wang.pojo; public class User { private String name; private int age; private String sex; public User() { } public User(String name, int age, String sex) { this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", sex='" + sex + '\'' + '}'; } }
这里我们引入了两个新知识----@RequestBody 和 ObjectMapper对象
当@RequestBody标注在Controller之上,那么这个Controller下的所有方法都不会经过视图解析器,而是直接返回
当@RequestBody标注在Controller中的某一个方法上,那么该方法的返回值就不会经过视图解析器,而是直接返回
@RequestMapping("/j2")
@ResponseBody
public String test2(Model model) throws JsonProcessingException {
System.out.println("json_j2");
List<User> list=new ArrayList<>();
list.add(new User("汪汪1",121,"男"));
list.add(new User("汪汪2",122,"男"));
list.add(new User("汪汪3",123,"男"));
//创建一个JackSon对象映射器,用来解析数据
//将List对象解析成为json格式
return new ObjectMapper().writeValueAsString(list);
//由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
}
SpringMVC解决Json格式数据乱码问题
在springmvc的配置文件中添加一段消息SpringHttpMessageConverter转换配置!
<mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> </bean> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper"> <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"> <property name="failOnEmptyBeans" value="false"/> </bean> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
返回JSON字符串统一解决
在类上直接使用@RestController,这样子,里面的所有的方法都只会返回json字符串了,不用再每一个都添加@ResponseBody,我们在
前后端分离开发中,一般都是用@RestController,十分方便!
@RestController public class UserController { //produces:指定响应体返回类型和编码 @RequestMapping(value = "/json1") public String json1() throws JsonProcessingException { //创建一个jackson的对象映射器,用来解析数据 ObjectMapper mapper = new ObjectMapper(); //创建一个对象 User user = new User("王广元", 3, "男"); //将我们的对象解析成为json格式 String str = mapper.writeValueAsString(user); //由于@ResponseBody注解,这里会将str转成json格式返回;十分方便 return str; } }
输出时间对象
默认ObjectMapper返回的是一个时间戳(距1970年1月1日有多少秒)
我们可以将它设置为我们常见的“yyyy-MM-dd:HH:mm:ss”
@RequestMapping("/j3") @ResponseBody public String test3(Model model) throws JsonProcessingException { //ObjectMapper,时间解析后的默认格式为:Timestamp ObjectMapper mapper=new ObjectMapper(); //关闭mapper的时间戳显示 mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false); //自定义日期格式 SimpleDateFormat simpleDateFormat=new SimpleDateFormat("YYYY-mm-dd:HH:mm:ss"); mapper.setDateFormat(simpleDateFormat); return new ObjectMapper().writeValueAsString(mapper.writeValueAsString(new Date())); }
如果我们经常使用其他格式的时间格式,我们可以将上述代码封装成一个工具类
package com.wang.util; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import java.text.SimpleDateFormat; public class JsonUtils { public static String getObjectMapper(Object value) throws JsonProcessingException { return getObjectMapper(value,""); } public static String getObjectMapper(Object value,String dataFormat) throws JsonProcessingException { ObjectMapper obj=new ObjectMapper(); obj.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false); SimpleDateFormat sdf=new SimpleDateFormat(dataFormat); obj.setDateFormat(sdf); return obj.writeValueAsString(value); } }
测试接口
@RequestMapping("/j4") @ResponseBody public String test4(Model model){ String rst=""; try { rst= JsonUtils.getObjectMapper(new Date(),"yyyy-MM-dd:HH:mm:ss"); } catch (JsonProcessingException e) { e.printStackTrace(); }finally { return rst; } }
FastJson
fastjson.jar是阿里开发的一款专门用于Java开发的包,可以方便的实现json对象与JavaBean对象的转换,实现JavaBean对象与json字符串的转换,
实现json对象与json字符串的转换。实现json的转换方法很多,最后的实现结果都是一样的。
fastjson 的 pom依赖!
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.9</version> </dependency>
fastjson 三个主要的类:
JSONObject 代表 json 对象
-
JSONObject实现了Map接口, 猜想 JSONObject底层操作是由Map实现的。
-
JSONObject对应json对象,通过各种形式的get()方法可以获取json对象中的数据,也可利用诸如size(),isEmpty()等方法获取"键:值"对的个数和判断是否为空。其本质是通过实现Map接口并调用接口中的方法完成的。
JSONArray 代表 json 对象数组
-
内部是有List接口中的方法来完成操作的。
JSON代表 JSONObject和JSONArray的转化
-
JSON类源码分析与使用
-
仔细观察这些方法,主要是实现json对象,json对象数组,javabean对象,json字符串之间的相互转化。
public static void main(String[] args) { //创建一个对象 User user1 = new User("wgy1", 3, "男"); User user2 = new User("wgy2", 4, "男"); User user3 = new User("wgy3", 5, "男"); User user4 = new User("wgy4", 6, "男"); List<User> list = new ArrayList<User>(); list.add(user1); list.add(user2); list.add(user3); list.add(user4); System.out.println("*******Java对象 转 JSON字符串*******"); String str1 = JSON.toJSONString(list); System.out.println("JSON.toJSONString(list)==>"+str1); String str2 = JSON.toJSONString(user1); System.out.println("JSON.toJSONString(user1)==>"+str2); System.out.println("\n****** JSON字符串 转 Java对象*******"); User jp_user1=JSON.parseObject(str2,User.class); System.out.println("JSON.parseObject(str2,User.class)==>"+jp_user1); System.out.println("\n****** Java对象 转 JSON对象 ******"); JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2); System.out.println("(JSONObject) JSON.toJSON(user2)==>"+jsonObject1.getString("name")); System.out.println("\n****** JSON对象 转 Java对象 ******"); User to_java_user = JSON.toJavaObject(jsonObject1, User.class); System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>"+to_java_user); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现