【学习笔记】关于JSON
什么是JSON
由于前后端分离的时代,后端只负责提供接口,提供数据,前端负责渲染后端的数据。所以前后端约定了一种格式,后端通过提供json格式,前端通过json格式去解析,那么它们就可以很好地配合。
JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式。它采用纯文本格式来存储和交换数据,实际就是字符串。
JSON和JavaScript对象的写法大同小异,都是通过键值对的方式
-
JSON : '{"name":"张三"}'
-
JavaScript: {"name":"张三"}
JSON是JavaScript对象的字符串表示形式
JSON和JavaScript对象的互相转换
-
JavaScript对象----> json,调用JSON.stringify() 方法
//编写一个JavaScript对象 var user = { name:"张三", age:18, sex:"男" } var json = JSON.stringify(user)
-
json----> JavaScript对象,调用JSON.parse()方法
var obj = JSON.parse(json)
那么Java如何生成json对象,返回给前端呢?
目前有两个工具可以实现:Jackson、fastjson
Jackson的使用
-
导入Jackson的依赖
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.14.2</version> </dependency>
-
完成springmvc需要的配置
-
web.xml中的DispatcherServlet的注册和映射、关联spring的配置文件
-
spring配置文件中自动扫描包下的注解、让springmvc不处理静态资源、自动注入处理器适配器和处理器映射器、视图解析器
-
-
实体类
@Data @AllArgsConstructor @NoArgsConstructor public class User { private String name; private int age; private String sex; }
-
写Controller
前情提要:之前我们都是返回字符串走视图解析器,然后通过视图解析器去匹配某一个具体的jsp页面,现在我们不走视图解析器,而是直接返回一个字符串去前端,这就用到了一个注解
@ResponseBody,这个注解是用在方法上的,还有一个用在类上的 @RestController,标注这个类下的所有方法都不走视图解析器,它可以代替@Controller
正文:
我们想要把一个实体类对象变成JSON,需要用到jackson包下的一个对象叫做ObjectMapper,然后调用ObjectMapper对象的writeValueAsSrtring()方法。
@Controller public class UserController { @RequestMapping("/j1") @ResponseBody public String json1() throws JsonProcessingException { User user = new User("张三", 18, "男"); ObjectMapper mapper = new ObjectMapper(); String str = mapper.writeValueAsString(user); return str; } }
从结果可以看出,是json的格式展示在前端的,但是出现了中文乱码的情况,下面来着重解决这个问题
解决乱码问题
-
方式一:在@RequestMapping注解中有一个参数叫做produces,它可以设置文本的类型,以及编码方式为utf-8
@RequestMapping(value="/j1",produces = "application/json;charset=utf-8")
已解决,但是spring为我们提供了解决乱码问题的方法,不需要我们手动去设置
-
方式二:在mvc:annotation-driven中去配置
<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>
测试把集合输出到前端
@RequestMapping("/j2")
//@ResponseBody
public String json2() throws JsonProcessingException {
User user1 = new User("张三1", 18, "男");
User user2 = new User("张三2", 18, "男");
User user3 = new User("张三3", 18, "男");
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
userList.add(user3);
ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(userList);
return str;
}
返回时间字符串
@RequestMapping("/j3")
//@ResponseBody
public String json3() throws JsonProcessingException {
Date date = new Date();
ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(date);
return str;
}
这样返回的字符串是时间戳的形式,把它转换成我们常见的格式有两种方式
-
第一种方式就是通过java的方式
@RequestMapping("/j3") //@ResponseBody public String json3() throws JsonProcessingException { Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String format = simpleDateFormat.format(date); ObjectMapper mapper = new ObjectMapper(); String str = mapper.writeValueAsString(format); return str; }
-
第二种方式使用ObjectMapper来格式化输出
调用configure()方法关闭时间戳的方式,然后调用setDateFormat()方法,自定义时间展示方式
@RequestMapping("/j3") //@ResponseBody public String json3() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String format = simpleDateFormat.format(date); //关闭时间戳 mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false); //将自定义的方式设置进去 mapper.setDateFormat(simpleDateFormat); String str = mapper.writeValueAsString(date); return str; }
提取公共类
在上面三个例子中,我们发现有一些重复的代码,我们可以把它们提取出来作为工具类
public class JsonUtils {
public static String getUtil(Object object,String sif) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(sif);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
mapper.setDateFormat(simpleDateFormat);
return mapper.writeValueAsString(object);
}
}
如果我们想要使用工具类去完成第二个例子,那么就需要getUtil() 方法的重载,这里需要注意的是在重载的方法中,我们没有必要再去按部就班地把每一步都写出来,只需要调用第一次的getUtil()方法就行了,这也是一个很重要的编程思想。
Fastjson的使用
Fastjson是Alibaba人员写的一个关于json的工具,和我们自己写的工具类有异曲同工之妙。
主要有以下方法:
-
Java对象转JSON字符串
JSON.toJSONString()
-
JSON字符串转Java对象
JSON.parseObject()
-
Java对象转JSON对象
JSONObject jsonObject = JSON.toJSON(user)
这里的json对象就是字符串
可以通过jsonobject对象调用getString()获得具体的值,需要传入的是键值对的键
-
JSON对象转Java对象
JSON.toJavaObject()