说明:SpringMVC提供了处理json格式请求/响应的HttpMessageConverter(MappingJackson2HttpMessageConverter。利用Jackson格式的请求或响应消息)。在配置文件中使用<mvc:annotation-driven/>时Spring会默认加载许多默认的支持,其中对读写json格式的数据默认使用jackson,使用时只需添加响应的jar包即可,不需其他配置。若要使用其他开源类包处理json,则要在<mvc:annotation-driven/>配置中添加配置,后面会讲到。。先看第一种情况:
-------------------------------------------------------------------------------------
1.本测试使用maven项目构建工具
-------------------------------------------------------------------------------
2.先搭建起测试环境:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lin.json</groupId>
<artifactId>JacksonTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!--spring-core-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<!-- spring-web-mvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<!-- spring end -->
<!-- jackson begin -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-lgpl</artifactId>
<version>1.9.13</version>
</dependency>
<!-- 在测试jackson发送接收数据时,如果没有添加此依赖,会报错,异常如下
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver logException
警告: Handler execution resulted in exception: Content type 'application/json;charset=UTF-8' not supported
-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
<!-- jackson end -->
</dependencies>
<!-- 添加项目jdk编译插件 -->
<build>
<!-- 设置编译版本为1.8 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- 配置tomcat7的插件,如果使用maven的命令方式运行,则命令为:tomcat7:run ,
而不能是tomcat:run(如果使用该命令,还是会使用maven默认的tomcat来编译运行项目)。
可以直接使用eclipse中的tomcat来运行项目(就是原先没有使用maven时的那样运行项目就可以了,那样的话也不需要配这个插件了)。
-->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
</plugin>
</plugins>
</build>
</project>
--------------------------------------------
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>JacksonTest</display-name>
<!-- 定义Spring MVC的前端控制器 -->
<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:spring/springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 让Spring MVC的前端控制器拦截所有请求 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 编码过滤器 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
-------------------------------------------------------
springmvc-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://mybatis.org/schema/mybatis-spring
http://mybatis.org/schema/mybatis-spring.xsd">
<!-- 自动扫描该包,SpringMVC会将包下用@Controller注解的类注册为Spring的controller -->
<context:component-scan base-package="org.fkit"/>
<!-- 设置默认配置方案 -->
<mvc:annotation-driven/>
<!-- 使用默认的Servlet来响应静态文件 -->
<mvc:default-servlet-handler/>
<!-- 视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix">
<value>/WEB-INF/content/</value>
</property>
<!-- 后缀 -->
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
------------------------------------------------------
Book.java
public class Book implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private String author;
/**省略set和get方法*/
}
------------------------------------------------------------------------
index.jsp(本测试首先通过访问这个页面来发起ajax请求)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试JSON格式的数据</title>
</head>
<script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="js/json2.js"></script>
<script type="text/javascript">
$(document).ready(function(){
testRequestBody();
});
function testRequestBody(){
$.ajax("${pageContext.request.contextPath}/json/testRequestBody",// 发送请求的URL字符串。
{
dataType : "json", // 预期服务器返回的数据类型。
type : "post", // 请求方式 POST或GET
contentType:"application/json", // 发送信息至服务器时的内容编码类型
// 发送到服务器的json数据。
data:JSON.stringify({id : 1, name : "Spring MVC企业应用实战"}),
async: true , // 默认设置下,所有请求均为异步请求。如果设置为false,则发送同步请求
// 请求成功后的回调函数。
success :function(data){
console.log(data);
$("#id").html(data.id);
$("#name").html(data.name);
$("#author").html(data.author);
},
// 请求出错时调用的函数
error:function(){
alert("数据发送失败");
}
});
}
</script>
</head>
<body>
编号:<span id="id"></span><br>
书名:<span id="name"></span><br>
作者:<span id="author"></span><br>
</body>
</html>
------------------------------------------------------------------------
BookController.java
package org.fkit.controller;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.map.ObjectMapper;
import org.fkit.domain.Book;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/json")
public class BookController {
private static final Log logger = LogFactory.getLog(BookController.class);
// @RequestBody根据json数据,转换成对应的Object
@RequestMapping(value="/testRequestBody")
public void setJson(@RequestBody Book book,
HttpServletResponse response) throws Exception{
// ObjectMapper类是Jackson库的主要类。它提供一些功能将Java对象转换成对应的JSON格式的数据
ObjectMapper mapper = new ObjectMapper();
// 将book对象转换成json输出
logger.info(mapper.writeValueAsString(book) );
book.setAuthor("肖文吉");
response.setContentType("text/html;charset=UTF-8");
// 将book对象转换成json写出到客户端
response.getWriter().println(mapper.writeValueAsString(book));
}
}
-----------------------------------------------------------------
(ps:以上代码不能直接跑起来,因为需要jQuery的一些文件支持。。但是原理还是相对好懂的)
====================================================================
第二种使用其他开源类包来处理json数据:
其代码与第一种方法几乎都是一样的,一下仅说明不同部分:
--------------------------------------------------------------
1.首先是添加maven依赖,fastjson所需的jar包:
<!-- fastjson begin -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.41</version>
</dependency>
<!-- fastjson end -->
--------------------------------------------------
2.控制器BookController.java
@Controller
@RequestMapping("/json")
public class BookController {
private static final Log logger = LogFactory.getLog(BookController.class);
// @RequestBody根据json数据,转换成对应的Object
@RequestMapping(value="/testRequestBody")
public void setJson(@RequestBody Book book,HttpServletResponse response) throws Exception{
//JSONObject-lib包是一个beans,collections,maps,java arrars和xml和json互相转换的包
//使用JSONObject将book对象转换成json输出
logger.info(JSONObject.toJSONString(book));
book.setAuthor("肖文吉");
response.setContentType("text/html;charset=UTF-8");
//将book对象转换成json写到客户端
response.getWriter().println(JSONObject.toJSONString(book));
}
}
---------------------------------------------
3.最重要的一步,在springmvc配置文件中配置该信息转换器:
<!-- 设置默认配置方案 -->
<mvc:annotation-driven>
<!-- 设置不使用默认的消息转换器 -->
<mvc:message-converters register-defaults="false">
<!-- 配置Spring的转换器 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
<!-- 配置fastjson中实现HttpMessageConverter接口的转换器 -->
<!-- FastJsonHttpMessageConverter是fastjson中实现了HttpMessageConverter接口的类 -->
<bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<!-- 加入支持的媒体类型:返回contentType -->
<property name="supportedMediaTypes">
<list>
<!-- 这里顺序不能反,一定要先写text/html,不然IE下会出现下载提示 -->
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
--------------------------------------------------------------------------------------
=====================================================
小结:以上就是客户端发送json数据给服务器端,然后由服务器端来解析json格式的数据。发送部分用了ajax来发送请求,数据使用json格式,这两块内容在开发中很常用,所以还是要好好学一下!
=====================================================
=====================================================
这里必须加个修改,今天在测试发送以及响应json格式的数据时发现了问题,并结合之前跟另一个同事做的ajax部分做了如下修改:
1.首先是修改后的ajax部分代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试接收JSON格式的数据</title>
<script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="js/json2.js"></script>
<script type="text/javascript">
$(document).ready(function(){
testRequestBody();
});
function testRequestBody(){
$.ajax({
url:"${pageContext.request.contextPath}/json/testRequestBody",// 发送请求的URL字符串。
// 发送到服务器的数据。
data:{id : 1, name : "Spring MVC企业应用实战"},
/*如果将contentType设置成application/json,则数据部分必须用JSON.stringify将数据转为json格式再发送
contentType:"application/json", // 发送信息至服务器时的内容编码类型
data:JSON.stringify({id : 1, name : "Spring MVC企业应用实战"}),
*/
type : "post", // 请求方式 POST或GET
dataType : "json", // 预期服务器返回的数据类型。
async: true , // 默认设置下,所有请求均为异步请求。如果设置为false,则发送同步请求
// 请求成功后的回调函数。
success :function(data){
console.log(data);
$("#id").html(data.id);
$("#name").html(data.name);
$("#author").html(data.author);
},
// 请求出错时调用的函数
error:function(){
alert("数据发送失败");
}
});
}
</script>
</head>
<body>
编号:<span id="id"></span><br>
书名:<span id="name"></span><br>
作者:<span id="author"></span><br>
</body>
</html>
2.经过以上代码的修改之后,后台的代码就非常简洁了,而且接收跟输出json格式都是可以的
package org.fkit.controller;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.fkit.domain.Book;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/json")
public class BookController {
private static final Log logger = LogFactory.getLog(BookController.class);
@RequestMapping("/testRequestBody")
@ResponseBody//这个注解表示将以下方法的返回值自动转换成json格式的数据(记得要添加jackson的jar包(无需配置)或者其它的第三方json类库(需另外在springmvc配置文件中配置))
public Book setJson(Book book){
System.out.println(book);
book.setAuthor("肖");
return book;
}
}
为了对比明显,下面是原先的旧代码:
其他代码不变,与上相同。