很多时候前端都需要调用后台服务实现交互功能,常见的数据交换格式多是JSON或XML,这里主要讲解Spring MVC为前端提供JSON格式的数据并实现与前台交互。
一、概要
JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
在 JS 语言中,一切都是对象。因此,任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。但是对象和数组是比较特殊且常用的两种类型。
(1)要实现从对象转换为 JSON 字符串,使用 JSON.stringify() 方法:
var json = JSON.stringify({a: 'Hello', b: 'World'}); //结果是 '{"a": "Hello", "b": "World"}'
(2)要实现从 JSON 转换为对象,使用 JSON.parse() 方法:
var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //结果是 {a: 'Hello', b: 'World'}
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<!--[if lte IE 8]>
<script type="text/javascript" src="//res.wx.qq.com/a/wx_fed/webwx/res/json3.min.js"></script>
<![endif]-->
</head>
<body>
<script type="text/javascript">
//js对象
var user = {
"name": "张学友",
"address": "中国香港"
};
//将对象转换成字符
var str = JSON.stringify(user);
alert(str);
//将字符串转换成json对象
var zxy = JSON.parse(str);
alert(zxy.name + "," + zxy.address);
</script>
</body>
</html>
View Code
运行结果:
二、使用ModelAndView
pom.xml添加对jackson的依赖
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.2</version>
</dependency>
View Code
在user控制器中添加一个action
@RequestMapping(value = "/users")
public ModelAndView users(){
ModelAndView mav=new ModelAndView(new MappingJackson2JsonView());
mav.addObject(userService.queryAllUsers());
return mav;
}
View Code
运行结果:
三、使用@ResponseBody与Jackson
修改pom.xml添加对jackson的依赖
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.2</version>
</dependency>
View Code
添加一个action,使用注解@ResponseBody,响应主体而不是路径
@RequestMapping(value = "/userJson",produces = "application/json;charset=utf-8")
@ResponseBody
public String userJson(){
ObjectMapper mapper=new ObjectMapper();
try {
return mapper.writeValueAsString(userService.queryAllUsers());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
View Code
运行结果:
四、乱码问题
(1)方法一:在action上声明编码格式
@RequestMapping(path="/json",produces = "application/json;charset=UTF-8")
View Code
(2)方法二:修改spring配置文件
上一种方法比较麻烦,如果项目中有许多action则每一个都要添加,可以通过Spring配置统一指定
<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>
View Code
五、日期格式化问题
默认日期格式会变成一个数字,是1970年1月1日到当前日期的毫秒数:
Jackson 默认是转成timestamps形式
(1)方法一:注解字段
在实体字段上使用@JsonFormat注解格式化日期
@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")
代码:
/**
* 出生日期
*/
@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")
private Date birthday;
View Code
运行结果:
(2)方法二:取消timestamps形式
如果只取消则会得到一个默认的日期格式,效果如下:
当然自定义输出格式是允许的
@RequestMapping(value = "/userJson",produces = "application/json;charset=utf-8")
@ResponseBody
public String userJson(){
ObjectMapper mapper=new ObjectMapper();
//不使用时间差的方式
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//自定义日期格式对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//指定日期格式
mapper.setDateFormat(sdf);
try {
return mapper.writeValueAsString(userService.queryAllUsers());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
View Code
运行结果:
六、工具类
工具类可以复用代码,提高开发效率,如上文中的序列化JSON:
package com.zhangguo.springmvc08.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.text.SimpleDateFormat;
/**
* JSON工具类,辅助类
* */
public class JsonUtil {
public static String getJson(Object object) {
return getJson(object,"yyyy-MM-dd HH:mm:ss");
}
public static String getJson(Object object,String dateFormat) {
ObjectMapper mapper = new ObjectMapper();
//不使用时间差的方式
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//自定义日期格式对象
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
//指定日期格式
mapper.setDateFormat(sdf);
try {
return mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
View Code
调用:
@RequestMapping(value = "/userJson",produces = "application/json;charset=utf-8")
@ResponseBody
public String userJson(){
return JsonUtil.getJson(userService.queryAllUsers(),"yyyy-MM-dd");
}
View Code