spring mvc post jsonmvc怎么将响应数据转换成json数据

SpringMVC 生成JSON(一)
我的图书馆
SpringMVC 生成JSON(一)
本示例基于前面几篇文章的代码。
一、JSON-lib框架,转换JSON
&&&1、首先要去官方下载json-lib工具包
本示例中使用的是v2.3;json-lib还需要以下依赖包:
commons-lang 2.5
commons-beanutils 1.8.0
commons-collections 3.2.1
commons-logging 1.1.1
官方网址:
然后在工程中添加如下jar包:
如果你还不了解JSON是什么?那么你应该可以看看
&&& 2、 要转换的JavaBean的代码如下:
Java代码 &&span&style=""&package&com.wy.&&&&import&java.io.S&&&&/**&&*&User对象必须实现serializable接口,因为放在session中的数据必须是可序列化的。&&*&否则会出现错误&setAttribute:&Non-serializable&attribute...&&*&@author&Administrator&&*&@version&&&*/&&public&class&User&implements&Serializable&{&&&&&&&&&&&&private&static&final&long&serialVersionUID&=&1L;&&&&&&private&String&&&&&&&private&String&&&&&&&private&int&&&&&&&private&String&&&&&&&private&String&&&&&&&&&public&String&getUsername()&{&&&&&&&&&&return&&&&&&&}&&&&&&&&public&void&setUsername(String&username)&{&&&&&&&&&&this.username&=&&&&&&&}&&&&&&&&public&String&getPassword()&{&&&&&&&&&&return&&&&&&&}&&&&&&&&public&void&setPassword(String&password)&{&&&&&&&&&&this.password&=&&&&&&&}&&&&&&&&public&int&getAge(){&&&&&&&&&&return&&&&&&&}&&&&&&&&public&void&setAge(int&age){&&&&&&&&&&this.age&=&&&&&&&}&&&&&&&&public&String&getSex()&{&&&&&&&&&&return&&&&&&&}&&&&&&&&public&void&setSex(String&sex)&{&&&&&&&&&&this.sex&=&&&&&&&}&&&&&&&&public&String&getBirthday()&{&&&&&&&&&&return&&&&&&&}&&&&&&&&public&void&setBirthday(String&birthday)&{&&&&&&&&&&this.birthday&=&&&&&&&}&&&&&&&&@Override&&&&&&public&String&toString()&{&&&&&&&&&&//&TODO&Auto-generated&method&stub&&&&&&&&&&return&this.username&+"#"+&this.password&+"#"+&this.age&+"#"+&this.sex&+"#"+&this.&&&&&&}&&&&}&&&/span&&&
新建JsonlibTest测试类,基本代码如下:
Java代码 &package&com.wy.&&&&import&org.junit.B&&import&org.junit.T&&&&import&com.wy.controller.annotation.EntryOrJsonC&&&&public&class&JsonlibTest&{&&&&&&&&@Before&&&&&&public&void&setUp()&throws&Exception&{&&&&&&}&&&&&&&&//@Test&&&&&&public&void&testEntry2Json()&{&&&&&&&&&&new&EntryOrJsonController().entry2Json();&&&&&&}&&&&&&&&//@Test&&&&&&public&void&testList2Json()&{&&&&&&&&&&new&EntryOrJsonController().list2Json();&&&&&&}&&&&&&&&&&&&//@Test&&&&&&public&void&testMap2Json()&{&&&&&&&&&&new&EntryOrJsonController().map2Json();&&&&&&}&&&&&&&&&&&&//@Test&&&&&&public&void&testJson2Entry()&{&&&&&&&&&&new&EntryOrJsonController().json2Entry();&&&&&&}&&&&&&&&&&&&//@Test&&&&&&public&void&testJson2MorphDynaBean()&{&&&&&&&&&&new&EntryOrJsonController().json2MorphDynaBean();&&&&&&}&&&&&&&&&&&&//@Test&&&&&&public&void&testJson2Array()&{&&&&&&&&&&new&EntryOrJsonController().json2Array();&&&&&&}&&&&&&&&&&&&//@Test&&&&&&public&void&testJson2List()&{&&&&&&&&&&new&EntryOrJsonController().json2List();&&&&&&}&&&&&&&&&&&&//@Test&&&&&&public&void&testJson2Collection()&{&&&&&&&&&&new&EntryOrJsonController().json2Collection();&&&&&&}&&&&&&&&&&&&@Test&&&&&&public&void&testJson2Map()&{&&&&&&&&&&new&EntryOrJsonController().json2Map();&&&&&&}&&}&&
JSON中重要的对象:JSONObject、JSONArray、JSONSerializer,下面也是围绕着这几个对象来说明问题。
&& JSONObject是将Java对象转换成一个json的Object形式。
& JSONArray是将一个Java对象转换成json的Array格式。
& JSONSerializer也一样可以完成将Java对象转换成JSON。
&& JSONObject、JSONArray、JSONSerializer不仅可以将Java对象转换成JSON,还可以将JSON转换成Java对象。
Java对象序列化成JSON对象
将JavaObject转换吃JSON字符串
Java代码 &&span&style="color:&#4b4b4b;"&&span&style=""&&span&style=""&/**&&&&&&*&1、&将JavaObject转换成JSON字符串&&&&&&*&&&&JSONObject是将Java对象转换成一个json的Object形式,&&&&&&*&&&&JSONArray是将一个Java对象转换成json的Array格式。&&&&&&&*&&&&JSONSerializer是将Java对象转换成一个json。&&&&&&*&&&&&&&&&&*&&&&JSONArray、JSONObject、JSONSerializer可以将Java对象转换成JSON,也可将JSON字符串转换成Java对象。&&&&&&*/&&&&&&@SuppressWarnings("static-access")&&&&&&public&void&entry2Json(){&&&&&&&&&&user&=&new&User();&&&&&&&&&&&&&&&&&&&&user.setUsername("wy");&&&&&&&&&&user.setPassword("321");&&&&&&&&&&user.setAge(23);&&&&&&&&&&user.setSex("man");&&&&&&&&&&user.setBirthday(new&SimpleDateFormat("yyyy-MM-d").format(new&Date()));&&&&&&&&&&&&&&&&&&&&("==============Java&Bean&&&&&JSON&Object==================");&&&&&&&&&&JSONArray&ja&=&jsonArray.fromObject(user);&&&&&&&&&&JSONObject&jo&=&jsonObject.fromObject(user);&&&&&&&&&&JSON&jsja&=&jsonSerializer.toJSON(user);&&&&&&&&&&&&&&&&&&&&("JSONArray:&\r\n"+ja+"\r\n"+"JSONObject:&\r\n"+jo+"\r\n"+"JSONSerializer:&\r\n"+jsja);&&&&&&&&&&&&&&&&}&/span&&/span&&/span&&&
将JavaList集合转换吃JSON字符串
Java代码 &&span&style="color:&#4b4b4b;"&&span&style=""&&span&style=""&/**&&&&&&*&2.将JavaList集合转换吃JSON字符串&&&&&&*&&&如果你是转换List集合,一定得用JSONArray或是JSONSrializer提供的序列化方法。&&&&&&*&&&如果你用JSONObject.fromObject方法转换List会出现异常,&&&&&&*&&&通常使用JSONSrializer这个JSON序列化的方法,它会自动识别你传递的对象的类型,然后转换成相应的JSON字符串。&&&&&&&&*/&&&&&&@SuppressWarnings("static-access")&&&&&&public&void&list2Json(){&&&&&&&&&&List&User&&userList&=&new&ArrayList&User&();&&&&&&&&&&for(int&i=0;i&3;i++){&&&&&&&&&&&&&&user&=&new&User();&&&&&&&&&&&&&&user.setUsername("wy"+i);&&&&&&&&&&&&&&user.setPassword("321"+i);&&&&&&&&&&&&&&user.setAge(23+i);&&&&&&&&&&&&&&user.setSex("man"+i);&&&&&&&&&&&&&&user.setBirthday(new&SimpleDateFormat("yyyy-MM-d").format(new&Date())+"&"+i);&&&&&&&&&&&&&&&&&&&&&&&&&&&&userList.add(user);&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&("==============Java&List&&&&&JSON&Object==================");&&&&&&&&&&JSONArray&ja&=&jsonArray.fromObject(userList);&&&&&&&&&&//JSONObject&jo&=&jsonObject.fromObject(userList);&+"JSONObject:&\r\n"+jo+"\r\n"&&&&&&&&&&JSON&jsja&=&jsonSerializer.toJSON(userList);&&&&&&&&&&&&&&&&&&&&("JSONArray:&\r\n"+ja+"\r\n"+"JSONSerializer:&\r\n"+jsja);&&&&&&}&/span&&/span&&/span&&&
将Map集合转换成JSON对象
Java代码 &/**&&&&&&*&3.将Map集合转换成JSON对象&&&&&&*&&&&&&&*/&&&&&&@SuppressWarnings("static-access")&&&&&&public&void&map2Json(){&&&&&&&&&&user&=&new&User();&&&&&&&&&&user.setUsername("wy");&&&&&&&&&&user.setPassword("321");&&&&&&&&&&user.setAge(23);&&&&&&&&&&user.setSex("man");&&&&&&&&&&user.setBirthday(new&SimpleDateFormat("yyyy-MM-d").format(new&Date()));&&&&&&&&&&&&&&&&&&&&Map&String,&Object&&map&=&new&HashMap&String,&Object&();&&&&&&&&&&map.put("bool",&Boolean.TRUE);&&&&&&&&&&map.put("int",&321);&&&&&&&&&&map.put("Long",&321.01);&&&&&&&&&&map.put("Str",&"wy");&&&&&&&&&&map.put("array",&new&String[]{"wy",&"321"});&&&&&&&&&&map.put("func",&"function(i){&return&this.arr[i];&}");&&&&&&&&&&&map.put("user",&user);&&&&&&&&&&&&&&&&&&&&("==============Java&Map&&&&&JSON&Object==================");&&&&&&&&&&JSONArray&ja&=&jsonArray.fromObject(map);&&&&&&&&&&JSONObject&jo&=&jsonObject.fromObject(map);&&&&&&&&&&JSON&jsja&=&jsonSerializer.toJSON(map);&&&&&&&&&&&&&&&&&&&&("JSONArray:&\r\n"+ja+"\r\n"+"JSONObject:&\r\n"+jo+"\r\n"+"JSONSerializer:&\r\n"+jsja);&&&&&&}&&&&&&&&
&JSON对象反序列化成Java对象
将json字符串转成Java对
Java代码 &/**&&&&&&*&4.JSON对象反序列化成Java对象&&&&&&*&&&&&&&*/&&&&&&public&void&json2Entry(){&&&&&&&&&&("==============JSON&Object&String&&&&&Java&Bean&==================");&&&&&&&&&&jsonObject&=&JSONObject.fromObject(json);&&&&&&&&&&User&joUser&=&(User)JSONObject.toBean(jsonObject,&User.class);&&&&&&&&&&("JSONObject:&\r\n"+joUser.toString());&&&&&&}&&
将json字符串转换成动态Java对象(MorphDynaBean)
Java代码 &/**&&&&&&*&5.将json字符串转换成动态Java对象(MorphDynaBean)&&&&&&*&&&转换后的对象Object是一个MorphDynaBean的动态JavaBean,通过PropertyUtils可以获得指定的属性的值。&&&&&&*/&&&&&&public&void&json2MorphDynaBean(){&&&&&&&&&&("==============JSON&Object&String&&&&&Java&MorphDynaBean&==================");&&&&&&&&&&JSON&j&=&JSONSerializer.toJSON(json);&&&&&&&&&&Object&obj&=&JSONSerializer.toJava(j);//MorphDynaBean&&&&&&&&&&String&userName&=&&&&&&&&&&&try&{&&&&&&&&&&&&&&userName&=&PropertyUtils.getProperty(obj,&"username")+"";&&&&&&&&&&}&catch&(IllegalAccessException&e)&{&&&&&&&&&&&&&&//&TODO&Auto-generated&catch&block&&&&&&&&&&&&&&e.printStackTrace();&&&&&&&&&&}&catch&(InvocationTargetException&e)&{&&&&&&&&&&&&&&//&TODO&Auto-generated&catch&block&&&&&&&&&&&&&&e.printStackTrace();&&&&&&&&&&}&catch&(NoSuchMethodException&e)&{&&&&&&&&&&&&&&//&TODO&Auto-generated&catch&block&&&&&&&&&&&&&&e.printStackTrace();&&&&&&&&&&}&&&&&&&&&&("JSONSerializer:&\r\n"+obj.toString()+"&"+userName);&&&&&&}&&
将json字符串转成Java的Array数组
Java代码 &/**&&&&&&*&6.&将json字符串转成Java的Array数组&&&&&&*&&&&&&&*/&&&&&&public&void&json2Array(){&&&&&&&&&&("==============JSON&String&&&&&Java&Array&==================");&&&&&&&&&&json&=&"["&+&json&+&"]";&&&&&&&&&&jsonArray&=&JSONArray.fromObject(json);&&&&&&&&&&Object[]&obj&=&jsonArray.toArray();&&&&&&&&&&User[]&user&=&(User[])JSONArray.toArray(jsonArray,&User.class);&&&&&&&&&&("JSONArray:&\r\n"+obj+"&"+obj[0]+"\r\n"+user+"&"+user[0]);&&&&&&}&&
将JSON字符串转成Java的List集合
Java代码 &/**&&&&&&*&7.将JSON字符串转成Java的List集合&&&&&&*/&&&&&&public&void&json2List(){&&&&&&&&&&json&=&"["&+&json&+&"]";&&&&&&&&&&("==============JSON&Array&String&&&&&Java&List&==================");&&&&&&&&&&jsonArray&=&JSONArray.fromObject(json);&&&&&&&&&&List&User&&user&=&jsonArray.toList(jsonArray,&User.class);&&&&&&&&&&&&&&&&&&&&("JSONArray:&\r\n"+user.get(0).toString());&&&&&&}&&
将json字符串转换成Collection接口
Java代码 &/**&&&&&&*&8.将json字符串转换成Collection接口&&&&&&*/&&&&&&public&void&json2Collection(){&&&&&&&&&&json&=&"["&+&json&+&"]";&&&&&&&&&&("==============JSON&Array&String&&&&&Java&Collection&==================");&&&&&&&&&&jsonArray&=&JSONArray.fromObject(json);&&&&&&&&&&Collection&User&&user&=&jsonArray.toCollection(jsonArray,&User.class);&&&&&&&&&&Object[]&obj&=&user.toArray();&&&&&&&&&&("JSONArray:&\r\n"+user+"&"+obj);&&&&&&}&&
将json字符串转换成Map集合
Java代码 &/**&&&&&&*&9.将json字符串转换成Map集合&&&&&&*/&&&&&&public&void&json2Map(){&&&&&&&&&&("==============JSON&String&&&&&Java&Map&==================");&&&&&&&&&&jsonObject&=&JSONObject.fromObject(json);&&&&&&&&&&Map&String,&Class&?&&&clazzMap&=&new&HashMap&String,&Class&?&&();&&&&&&&&&&clazzMap.put("A",&User.class);&&&&&&&&&&Map&String,&?&&mapBean&=&(Map)&JSONObject.toBean(jsonObject,&Map.class,&clazzMap);&&&&&&&&&&("JSONObject&"+&mapBean);&&&&&&&&&&Set&String&&set&=&mapBean.keySet();&&&&&&&&&&Iterator&String&&iter&=&set.iterator();&&&&&&&&&&while&(iter.hasNext())&{&&&&&&&&&&&&&&String&key&=&iter.next();&&&&&&&&&&&&&&("JSONObject&"+&key&+&":"&+&mapBean.get(key).toString());&&&&&&&&&&}&&&&&&}&&
将JSON返回到页面
&& 1、HttpServletResponse
Java代码 &/**&&&&&&*&10.&将JSON返回到页面&&&&&&*&@param&response&&&&&&*/&&&&&&public&String&entry2JSON(){&&&&&&&&&&user&=&new&User();&&&&&&&&&&user.setUsername("wy");&&&&&&&&&&user.setPassword("321");&&&&&&&&&&user.setAge(23);&&&&&&&&&&user.setSex("man");&&&&&&&&&&user.setBirthday(new&SimpleDateFormat("yyyy-MM-d").format(new&Date()));&&&&&&&&&&&&&&&&&&&&("==============Java&Bean&&&&&JSON&Object==================");&&&&&&&&&&JSONArray&ja&=&jsonArray.fromObject(user);&&&&&&&&&&JSONObject&jo&=&jsonObject.fromObject(user);&&&&&&&&&&JSON&jsja&=&jsonSerializer.toJSON(user);&&&&&&&&&&return&jo.toString();&&&&&&}&&&&&&&&&&&&/**&&&&&&*&将JSON返回到页面&&&&&&*&@param&response&&&&&&*/&&&&&&/*@RequestMapping(value="/returnJson",&method=RequestMethod.GET)&&&&&public&void&commonReturnType(HttpServletResponse&response){&&&&&&&&&try&{&&&&&&&&&&&&&PrintWriter&out&=&response.getWriter();&&&&&&&&&&&&&out.print(new&EntryOrJsonController().entry2JSON());&&&&&&&&&&&&&out.flush();&&&&&&&&&&&&&out.close();&&&&&&&&&}&catch&(IOException&e)&{&&&&&&&&&&&&&//&TODO&Auto-generated&catch&block&&&&&&&&&&&&&e.printStackTrace();&&&&&&&&&}&&&&&}*/&&
2、PrintWriter out
Java代码 &/**&&&&&&*&将JSON返回到页面&&&&&&*&默认策略生产viewName&&&&&&*&@param&out&&&&&&*/&&&&&&/*@RequestMapping(value="/returnJson",&method=RequestMethod.POST)&&&&&public&void&commonReturnType(PrintWriter&out){//其实也是从HttpServletResponse&通过getWriter()得到out&&&&&&&&&out.print(new&EntryOrJsonController().entry2JSON());&&&&&&&&&out.flush();&&&&&&&&&out.close();&&&&&}*/&&
3、ModelAndView
Java代码 &@RequestMapping(value="/returnJson",&method=RequestMethod.GET)&&&&&&public&ModelAndView&commonReturnType(){&&&&&&&&&&ModelAndView&mav&=&new&ModelAndView();&&&&&&&&&&mav.addObject("json",&new&EntryOrJsonController().entry2JSON());&&&&&&&&&&mav.setViewName("returnJson");&&&&&&&&&&return&&&&&&&}&&
4、@ResponseBody
Java代码 &/**&&&&&&*&注解&&&&&&&*&将JSON返回到页面&&&&&&*&默认策略生产viewName&&&&&&*&@return&&&&&&*/&&&&&&@ResponseBody&&&&&&@RequestMapping(value="/returnJson",&method=RequestMethod.POST)&&&&&&public&String&commonReturnTypeAnno(){&&&&&&&&&&String&jsonAnnotation&=&new&EntryOrJsonController().entry2JSON();&&&&&&&&&&return&jsonA&&&&&&}&&
视图层接受JSON
&& returnJson.jsp
Html代码 &&%@&page&language="java"&import="java.util.*"&pageEncoding="UTF-8"%&&&&%@&taglib&prefix="c"&uri="/jsp/jstl/core"&%&&&&%&&String&path&=&request.getContextPath();&&String&basePath&=&request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";&&%&&&&&&!DOCTYPE&HTML&PUBLIC&"-//W3C//DTD&HTML&4.01&Transitional//EN"&&&&html&&&&&&head&&&&&&&&base&href="&%=basePath%&"&&&&&&&&&&&&&&title&JSON输出到页面&/title&&&&&&&&&&&&&&meta&http-equiv="pragma"&content="no-cache"&&&&&&&&meta&http-equiv="cache-control"&content="no-cache"&&&&&&&&meta&http-equiv="expires"&content="0"&&&&&&&&&&&&meta&http-equiv="keywords"&content="keyword1,keyword2,keyword3"&&&&&&&&meta&http-equiv="description"&content="This&is&my&page"&&&&&&&&!--&&&&&&link&rel="stylesheet"&type="text/css"&href="styles.css"&&&&&&--&&&&&&&&/head&&&&&&&&&&body&&&&&&&&JSON输出到页面.&&br/&&&&&&&&&c:if&test="${json&!=&null}"&&&&&&&&&&&&&&&&&&&&&&&&通过GET方式请求并以ModelAndView返回的JSON:&${json}&&&&&&&&/c:if&&&&&&&&&c:if&test="${jsonAnnotation&!=&null}"&&&&&&&&&&&&&&&&&&&&&&&&完全基于注解返回的JSON:&${jsonAnnotation}&&&&&&&&/c:if&&&&&&&&&&&&&&&&&form&action="&%=path%&/returnJson.do"&method="post"&&&&&&&&&&&input&type="submit"&value="提交"&/&&&&&&&&&/form&&&&&&/body&&&&/html&&&
附件中是完整的Controller。&
TA的最新馆藏[转]&SpringMVC中使用@RequestBody,@ResponseBody注解实现Java对象和XML/JSON数据自动转换(上)
Spring3.1开始使用新的HandlerMapping 和 HandlerAdapter 来支持@Contoller 和@RequestMapping注解处理:处理器映射RequestMappingHandlerMapping和处理器适配器RequestMappingHandlerAdapter组合来代替Spring2.5 开始的处理器映射DefaultAnnotationHandlerMapping和处理器适配器AnnotationMethodHandlerAdapter。
HandlerMapping:请求到处理器的映射,如果映射成功返回一个HandlerExecutionChain 对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor 拦截器)对象;
HandlerAdapter:HandlerAdapter 将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器。
配合@ResponseBody注解,以及HTTP Request Header中的Accept属性,Controller返回的Java对象可以自动被转换成对应的XML或者JSON数据。
先看一个例子,只需要简单的几步,就可以返回XML数据。(本文使用Spring版本 4.1.6,并使用maven做项目构建)
1)在配置文件中添加
&!-- 自动扫描的包名 --&
&context:component-scan base-package=&learning.webapp.controller& /&
&!-- 默认的注解映射的支持 --&
&mvc:annotation-driven/&
2)添加以下几个java类
package learning.webapp.
public class Employee {
public Employee() {
public Employee(String name, int salary) {
this.name =
this.salary =
public String getName() {
public int getSalary() {
public void setName(String name) {
this.name =
public void setSalary(int salary) {
this.salary =
package learning.webapp.
import javax.xml.bind.annotation.XmlRootE
@XmlRootElement
public class EmployeeX extends Employee {
public EmployeeX() {
public EmployeeX(String name, int salary) {
super(name, salary);
package learning.webapp.
import learning.webapp.model.E
import learning.webapp.model.EmployeeX;
import org.springframework.stereotype.C
import org.springframework.web.bind.annotation.PathV
import org.springframework.web.bind.annotation.RequestM
import org.springframework.web.bind.annotation.RequestM
import org.springframework.web.bind.annotation.ResponseB
@Controller
@RequestMapping(&/employees&)
public class XmlOrJsonController {
@RequestMapping(value=&/xml/{name}&, method=RequestMethod.GET)
@ResponseBody
public Employee getEmployeeXml(@PathVariable String name) {
return new EmployeeX(name, 16000);
3) 在Eclipse中使用Jetty插件启动Web Server,然后在浏览器中访问:
非常简单!Spring是怎么实现这个转换的呢?我们先了解下Spring的消息转换机制。
在SpringMVC中,可以使用@RequestBody和@ResponseBody两个注解,分别完成请求报文到对象和对象到响应报文的转换,底层这种灵活的消息转换机制,就是Spring3.x中新引入的HttpMessageConverter即消息转换器机制。
我们可以用下面的图,简单描述一下这个过程。
这里最关键的就是&mvc:annotation-driven/&,加了这句配置,Spring会调用org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser来解析。
在这个类的parse(Element, ParserContext)方法中,分别实例化了RequestMappingHandlerMapping,RequestMappingHandlerAdapter等诸多类。
RequestMappingHandlerAdapter是请求处理的适配器,我们重点关注它的messageConverters属性。
1)RequestMappingHandlerAdapter在调用handle()的时候,会委托给ServletInvocableHandlerMethod的invokeAndHandle()方法进行处理,这个方法又调用HandlerMethodReturnValueHandlerComposite类进行处理。
HandlerMethodReturnValueHandlerComposite维护了一个HandlerMethodReturnValueHandler列表。
由于我们使用了@ResponseBody注解,getReturnValueHandler就会返回RequestResponseBodyMethodProcessor的实例。
2)之后RequestResponseBodyMethodProcessor.handleReturnValue()方法会被调用。此方法会调用AbstractMessageConverterMethodProcessor.writeWithMessageConverters()。它会根据request header中的Accept属性来选择合适的message converter.
3)&messageConverters中有如下的6个converter. 它们是从哪里来的呢?前面提到,AnnotationDrivenBeanDefinitionParser.parse(Element, ParserContext)方法中,分别实例化了RequestMappingHandlerMapping,RequestMappingHandlerAdapter以及messageConverters属性。
需要关注org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter这个类,就是它实现了返回对象到XML的转换。
4)看一下getMessageConverters()中的处理。有5个message converter是一定会加进来的。
if (convertersElement == null || Boolean.valueOf(convertersElement.getAttribute(&register-defaults&))) {
messageConverters.setSource(source);
messageConverters.add(createConverterDefinition(ByteArrayHttpMessageConverter.class, source));
RootBeanDefinition stringConverterDef = createConverterDefinition(StringHttpMessageConverter.class, source);
stringConverterDef.getPropertyValues().add(&writeAcceptCharset&, false);
messageConverters.add(stringConverterDef);
messageConverters.add(createConverterDefinition(ResourceHttpMessageConverter.class, source));
messageConverters.add(createConverterDefinition(SourceHttpMessageConverter.class, source));
messageConverters.add(createConverterDefinition(AllEncompassingFormHttpMessageConverter.class, source));
然后再看,这里jaxb2Present为true, 因此Jaxb2RootElementHttpMessageConverter被添加到messageConverters中。
5)看一下jaxb2Present的定义,原来javax.xml.bind.Binder这个类是JDK中包含的类,所以jaxb2Present=true。
6)我们看一下Jaxb2RootElementHttpMessageConverter的canWrite()方法。返回true的条件有两个
a) 返回对象的类具有XmlRootElement注解;
b) 请求头中的Accept属性包含application/xml。
public boolean canWrite(Class&?& clazz, MediaType mediaType) {
return (AnnotationUtils.findAnnotation(clazz, XmlRootElement.class) != null && canWrite(mediaType));
7) 在chrome中打开开发者工具,可以看到请求头中确实包含了Accept=application/xml
接下来我们看看如果想要返回JSON数据,应该怎么做?
根据上面的分析,首先我们需要添加一个支持JSON的message converter. 前面分析getMessageConverters()代码的时候,看到
if (jackson2Present) {
RootBeanDefinition jacksonConverterDef = createConverterDefinition(MappingJackson2HttpMessageConverter.class, source);
GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
messageConverters.add(jacksonConverterDef);
else if (gsonPresent) {
messageConverters.add(createConverterDefinition(GsonHttpMessageConverter.class, source));
然后再来看看jackson2Present和gsonPresent的定义。
private static final boolean jackson2Present =
ClassUtils.isPresent(&com.fasterxml.jackson.databind.ObjectMapper&, AnnotationDrivenBeanDefinitionParser.class.getClassLoader()) &&
ClassUtils.isPresent(&com.fasterxml.jackson.core.JsonGenerator&, AnnotationDrivenBeanDefinitionParser.class.getClassLoader());
private static final boolean gsonPresent =
ClassUtils.isPresent(&com.google.gson.Gson&, AnnotationDrivenBeanDefinitionParser.class.getClassLoader());
所以我们只要把Jackson2或者GSON加入工程的class path,Spring就会自动把GsonHttpMessageConverter加进来。
1)我们在POM中添加以下依赖
&dependency&
&groupId&com.fasterxml.jackson.core&/groupId&
&artifactId&jackson-databind&/artifactId&
&version&2.6.1&/version&
&/dependency&
&dependency&
&groupId&com.google.code.gson&/groupId&
&artifactId&gson&/artifactId&
&version&2.3.1&/version&
&/dependency&
2)在XmlOrJsonController.java中添加getEmployeeJson()方法
@RequestMapping(value=&/json/{name}&, method=RequestMethod.GET)
@ResponseBody
public Employee getEmployeeJson(@PathVariable String name) {
return new Employee(name, 16000);
和getEmployeeXml()相比,这里唯一的不同是返回对象变成了Employee,因为Employee类上没有@XmlRootElement注解,所以Spring不会选择Jaxb2RootElementHttpMessageConverter。又因为Accept属性中包含了*/*,表示接受任意格式返回数据,所以GsonHttpMessageConverter的canWrite()方法返回true.这样Spring就会选择MappingJackson2HttpMessageConverter或者GsonHttpMessageConverter来进行数据转换。
至此,我们知道请求头中的Accept属性是一个很关键的东西,我们可以根据这个在Controller中写一个方法,根据Accept的值自动返回XML或者JSON数据。
* 根据request header中的Accept自动选择返回XML or JSON
@RequestMapping(value=&/{name}&, method=RequestMethod.GET)
@ResponseBody
public Employee getEmployee(@PathVariable String name) {
return new EmployeeX(name, 16000);
因为浏览器的Accept值不方便修改,我们自己写客户端来调用。
package learning.
import java.io.IOE
import java.io.InputS
import java.net.URI;
import java.net.URISyntaxE
import org.junit.T
import org.springframework.http.HttpE
import org.springframework.http.HttpH
import org.springframework.http.HttpM
import org.springframework.http.client.ClientHttpR
import org.springframework.http.client.ClientHttpR
import org.springframework.http.client.SimpleClientHttpRequestF
import org.springframework.web.client.RestT
public class XmlOrJasonControllerTest {
public void testJsonResponse() throws IOException, URISyntaxException {
String url = &http://localhost:8080/employees/Jack&;
ClientHttpRequest request = new SimpleClientHttpRequestFactory().createRequest(new URI(url), HttpMethod.GET);
request.getHeaders().set(&Accept&, &application/json&);
ClientHttpResponse response = request.execute();
InputStream is = response.getBody();
byte bytes[] = new byte[(int) response.getHeaders().getContentLength()];
is.read(bytes);
String jsonData = new String(bytes);
System.out.println(jsonData);
public void testXmlResponse() throws IOException, URISyntaxException {
String url = &http://localhost:8080/employees/Jack&;
// response headers 中包含Transfer-Encoding:chunked,没有content length,
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.set(&Accept&, &application/xml&);
RestTemplate restTemplate = new RestTemplate();
HttpEntity&Object& httpEntity = new HttpEntity&Object&(requestHeaders);
String xmlData = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class).getBody();
System.out.println(xmlData);
[参考资料]
1)/fangjian0423/p/springMVC-xml-json-convert.html
2)http://my.oschina.net/lichhao/blog/172562
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?}

我要回帖

更多关于 spring mvc 返回json 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信