【springmvc学习第九弹】对Ajax的支持

最直接的Ajax处理

只要在Controller的方法里面,直接使用response输出你要返回的的Ajax数据,然后return null就可以了,示例如下:

Controller示例

1 @RequestMapping(value = "/hello")
2 public ModelAndView handleRequest(UserModel um,HttpServletResponse response) throws IOException {
3   response.setCharacterEncoding("utf-8");
4   response.getWriter().println("{uuid:‘"+um.getUuid()+"‘,name:‘"+um.getName()+"‘}");
5   return null;
6 }

客户端示例,使用jQuery

 1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 2 <head>
 3   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 4 </head>
 5 <script language="javascript" src="/mvcexample/static/js/jquery-1.3.2.min.js"></script>
 6 <script language="javascript">
 7   $().ready(function(){
 8     $.getJSON(‘/mvcexample/hello‘,{uuid:‘1‘,name:‘test‘},function(data){
 9       alert(data.uuid+" , "+data.name);
10     });
11   });
12 </script>
13 </html>

然后就可以启动服务器测试了。

数据绑定@RequestBody/@ResponseBody

@RequestBody

功能:用于将HttpServletRequest的getInputStream()内容绑定到入参

例子:

1 @RequestMapping(value = "/hello")
2 public byte[] handleRequest(@RequestBody String body)

@ResponseBody

功能:用于将方法的返回值作为响应体

例子:

@RequestMapping(value = “/hello")
@ResponseBody
public byte[] handleRequest(@RequestBody String body)

注意:他们都只能访问报文体,不能访问报文头

使用@RequestBody/@ResponseBody来支持Ajax

可以使用@RequestBody来自动获取Ajax上传的数据,同时也可以使用@ResponseBody,把要返回的对象自动拼成JSON的格式返回

当然,需要加入几个jackson的包,这里加入了:

jackson-core-2.1.2.jar、jackson-annotations-2.1.2.jar、jackson-databind-2.1.2.jar

测试使用的Controller的方法:

1 @RequestMapping(value = "/hello")
2 @ResponseBody
3 public UserModel handleRequest(@RequestBody String reqBody, UserModel um) {
4   System.out.println("the reqBody="+reqBody);
5   um.setName(um.getName()+",server");
6   return um;
7 } 

测试使用的页面

 1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 2 <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 3 </head>
 4 <script language="javascript" src="/mvcexample/static/js/jquery-1.3.2.min.js"></script>
 5 <script language="javascript">
 6   $().ready(function(){
 7     $.getJSON(‘/mvcexample/hello‘,{uuid:‘1‘,name:‘test‘},function(data){
 8       alert(data.uuid+" , "+data.name);
 9     });
10   });
11 </script>

去测试看看吧,可以看到Controller的方法直接返回一个um对象,但是 @ResponseBody会把这个对象自动变成json格式的,再传回客户端,非常方便。

当然, @ResponseBody也支持集合对象自动变成json格式,比如:

测试使用的Controller方法

 1 @RequestMapping(value = "/hello")
 2 @ResponseBody
 3 public List<UserModel> handleRequest(@RequestBody String reqBody, UserModel um) {
 4   System.out.println("the reqBody="+reqBody);
 5   um.setName(um.getName()+",server");
 6   List<UserModel> list = new ArrayList<UserModel>();
 7   list.add(um);
 8   UserModel um2 = new UserModel();
 9   um2.setUuid("22");
10   um2.setName("222");
11   list.add(um2);
12   return list;
13 }

测试使用的页面

 1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 2 <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
 3 <script language="javascript" src="/mvcexample/static/js/jquery-1.3.2.min.js"></script>
 4 <script language="javascript">
 5   $().ready(function(){
 6     $.getJSON(‘/mvcexample/hello‘,{uuid:‘1‘,name:‘test‘},function(data){
 7       $.each(data,function(index,v){
 8         alert("tr="+v.uuid+",v="+v.name);
 9       });
10     });
11   });
12 </script>

使用HttpEntity/ResponseEntity来支持Ajax

使用HttpEntity/ResponseEntity不但能访问到报文体,还可以访问报文头

示例,主要的变化在Controller的方法上,页面不用变化,如下:

 1 @RequestMapping(value = "/hello")
 2 public ResponseEntity<List<UserModel>> handleRequest(HttpEntity<String> req, UserModel um) {
 3   System.out.println("req headers="+req.getHeaders()+", reqBody="+req.getBody());
 4
 5   um.setName(um.getName()+",server");
 6   List<UserModel> list = new ArrayList<UserModel>();
 7   list.add(um);
 8   UserModel um2 = new UserModel();
 9   um2.setUuid("22");
10   um2.setName("222");
11   list.add(um2);
12
13   ResponseEntity<List<UserModel>> ret = new ResponseEntity<List<UserModel>>(list,HttpStatus.OK);
14   return ret;
15 }

对Ajax返回xml的支持

前面的Ajax使用的是json格式,下面看看对xml的支持

要让Spring Web MVC支持xml格式,需要加入如下jar包:

jaxb-api-2.2.5.jar,jaxb-impl-2.2.5.jar

在要返回的对象头上使用如下注解,例如:

1 @XmlRootElement(name = "testxml")
2 public class UserModel {

这表明返回的xml的根元素名称为testxml,注意:由于xml是单根的,所以只能返回一个对象,而不能返回一个list,如果要返回多条值,可以在这个对象中包含多个其他对象

返回的结果同样用@ResponseBody注解即可,这个注解会根据请求的类型,自动决定是返回json还是xml,当然默认是返回json格式的,如 果要返回xml格式,那么请求的时候,要指定accept=application/xml

示例的Controller方法

 1 @RequestMapping(value = "/hello")
 2 @ResponseBody
 3 public UserModel handleRequest(HttpEntity<String> req, UserModel um) {
 4   System.out.println("req headers="+req.getHeaders()+", reqBody="+req.getBody());
 5
 6   um.setName(um.getName()+",server");
 7
 8   PhoneNumberModel pnm = new PhoneNumberModel("123","321");
 9   PhoneNumberModel pnm2 = new PhoneNumberModel("2222","333");
10   List<PhoneNumberModel> tempList = new ArrayList<PhoneNumberModel>();
11   tempList.add(pnm2);
12   tempList.add(pnm);
13
14   um.setPm(tempList);
15
16   return um;
17 }

示例的页面

 1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 2 <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
 3 <script language="javascript" src="/mvcexample/static/js/jquery-1.3.2.min.js"></script>
 4 <script language="javascript">
 5 $().ready(function(){
 6 $.ajax({
 7       url:‘/mvcexample/hello‘,
 8       type: ‘POST‘,
 9       dataType: ‘xml‘,
10       data: {uuid:‘1‘,name:‘test‘},
11       timeout: 1000,
12       error: function(){    alert(‘Error loading XML document‘);       },
13       success: function(xml){
14       $(xml).find("testxml").children("pm").each(function(i){
15              var uuid=$(this).children("areaCode").text();
16              var name=$(this).children("phoneNumber").text();
17              alert("uuid="+uuid+",name="+name);
18
19       });        }    }); });
20 </script>

返回的xml形如

 1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 2 <testxml>
 3 <age>0</age>
 4 <name>test,server</name>
 5 <pm>
 6 <areaCode>2222</areaCode>
 7 <phoneNumber>333</phoneNumber>
 8 </pm>
 9 <pm>
10 <areaCode>123</areaCode>
11 <phoneNumber>321</phoneNumber>
12 </pm>
13 <uuid>1</uuid>
14 </testxml>

HttpMessageConverter

其实前面的程序实现对json和xml的支持,之所以能正常运行,幕后英雄就是HttpMessageConverter,它负责对http传入和传出的内容进行格式转换

比如前面学的@RequestBody是将Http请求正文插入方法中,其实它就会使用适合的HttpMessageConverter将请求体写入某个对象

比如前面学的@ResponseBody是将内容或对象作为Http响应正文返回,使用@ResponseBody将会跳过视图处理部分,直接调用合适的HttpMessageConverter,将返回值写入输出流

现在只要你开启了<mvc:annotation-driven  />,它会给AnnotationMethodHandlerAdapter初始化7个转换器,可以通过调用 AnnotationMethodHandlerAdapter类的getMessageConverts()方法来获取转换器的一个集合 List<HttpMessageConverter>,默认开启的有:

1、ByteArrayHttpMessageConverter

2、StringHttpMessageConverter

3、ResourceHttpMessageConverter

4、SourceHttpMessageConverter<T>

5、XmlAwareFormHttpMessageConverter

6、Jaxb2RootElementHttpMessageConverter

7、MappingJacksonHttpMessageConverter

Spring是如何寻找最佳的HttpMessageConverter呢?

最基本的方式就是通过请求的accept里面的格式来匹配,如果accept=application/json之类的,就使用json的 HttpMessageConverter,如果accept=application/xml之类的,就使用xml的 HttpMessageConverter,

内容协商

什么是内容协商

简单点说,就是同一资源,可以有多种表现形式,比如xml、json等,具体使用哪种表现形式,是可以协商的。

这是RESTfull的一个重要特性,Spring Web MVC也支持这个功能。

Spring MVC REST是如何决定采用何种方式(视图)来展示内容呢?

一:根据Http请求的header中的Accept属性的值来判读,比如:

Accept: application/xml                将返回xml格式数据

Accept: application/json               将返回json格式数据

优点:是这种方式是理想的标准方式

缺点:是由于浏览器的差异,导致发送的Accept Header头可能会不一样,从而导致服务器不知要返回什么格式的数据

二:根据扩展名来判断,比如:

/mvc/test.xml  将返回xml格式数据

/mvc/test.json 将返回json格式数据

/mvc/test.html 将返回html格式数据

缺点:丧失了同一URL的多种展现方式。在实际环境中使用还是较多的,因为这种方式更符合程序员的习惯

三:根据参数来判断

/mvc/test?format=xml        将返回xml数据

/mvc/test?format=json       将返回json数据

缺点:需要额外的传递format参数,URL变得冗余繁琐,缺少了REST的简洁风范

使用内容协商的功能,如果不使用第三种方式的话,3.2的版本可以什么都不用配置,默认就能支持前面两种。下面还是看看怎么配置,示例如下:

需要在spring的配置文件中做配置,示例如下:

 1 <!--1、检查扩展名(如my.pdf);2、检查Parameter(如my?format=pdf);3、检查Accept Header-->
 2     <bean id= "contentNegotiationManager" class= "org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
 3         <!-- 扩展名至mimeType的映射,即 /user.json => application/json -->
 4         <property name= "favorPathExtension" value= "true" />
 5         <!-- 用于开启 /userinfo/123?format=json 的支持 -->
 6         <property name= "favorParameter" value= "true" />
 7         <property name= "parameterName" value= "format"/>
 8         <!-- 是否忽略Accept Header -->
 9         <property name= "ignoreAcceptHeader" value= "false"/>
10      <property name= "mediaTypes"> <!--扩展名到MIME的映射;favorPathExtension, favorParameter是true时起作用  -->
11             <value>
12                 ccjson=application/json
13                 ccxml=application/xml
14                 html=text/html
15             </value>
16         </property>
17         <!-- 默认的content type -->
18         <property name= "defaultContentType" value= "text/html" />
19     </bean>
20
21 <!-- ========================= VIEW定义 ========================= -->
22 <!-- 内容协商视图解析器;根据客户端不同的请求决定不同的view进行响应 -->
23     <!-- 会自动根据解析的contentType来决定使用哪个视图解析器(默认使用整个web应用中的viewResolver) -->
24     <bean class= "org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:order= "0">
25         <!-- 内容协商管理器 用于决定media type -->
26         <property name= "contentNegotiationManager" ref= "contentNegotiationManager"/>
27         <!-- 默认视图 放在解析链最后 -->
28         <property name= "defaultViews">
29             <list>
30              <bean class= "org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
31                 <bean class= "org.springframework.web.servlet.view.xml.MarshallingView">
32                 <property name= "marshaller">
33             <bean class= "org.springframework.oxm.jaxb.Jaxb2Marshaller">
34               <property name= "packagesToScan" value= "cn.javass"></property>
35             </bean>
36          </property>
37                </bean>
38             </list>
39         </property>
40     </bean>
41
42 <!-- bean name view resolver-->
43     <bean class= "org.springframework.web.servlet.view.BeanNameViewResolver" p:order= "1"/>
44     <!-- 默认的视图解析器 在上边的解析错误时使用 (默认使用 html)- -->
45     <bean id= "defaultViewResolver" class= "org.springframework.web.servlet.view.InternalResourceViewResolver" p:order= "2">
46         <property name= "viewClass" value= "org.springframework.web.servlet.view.JstlView"/>
47         <property name= "contentType" value= "text/html"/>
48         <property name= "prefix" value= "/WEB-INF/jsp/"/>
49         <property name= "suffix" value= ".jsp"/>
50     </bean>
51 <!-- 在mvc:annotation-driven里面配置使用内容协商-->
52 <mvc:annotation-driven
53       validator= "validator"
54       conversion-service= "conversionService"
55       content-negotiation-manager= "contentNegotiationManager"
56       >
57 </mvc:annotation-driven>
58  

n测试文件的变化:

1:dataType: ‘json’, 这句话可以注掉了

2:在请求的url上添加 后缀,还有参数试试看,注意,前面配置的映射格式是ccjson、ccxml哦,例如:

url:‘/mvcexample/hello?format=ccxml‘,

url:‘/mvcexample/hello?format=ccjson‘,

url:‘/mvcexample/hello.ccxml‘,

url:‘/mvcexample/hello.ccjson‘,

应该可以看到根据不同的请求,服务端回返回不同格式的数据。

时间: 2024-10-14 19:52:36

【springmvc学习第九弹】对Ajax的支持的相关文章

Python3 学习第九弹: 模块学习二之文件管理模块

os模块 提供访问操作系统的接口 1> name 获得当前操作系统 其中 'nt' 是 windows 'posix' 是 linux 2> environ 获得当前系统的环境变量的字典,(变量名:变量值) 3> getcwd() 获得当前工作目录 4> getgid() 返回当前进程的真实组id 5> getlogin() 返回当前登录的用户名 6> getpid() 返回当前进程的pid 7> system(command) 运行shell命令 在linux下

C#学习第九弹之委托

先上委托的例子: 1 using System; 2 3 delegate int myDelegateHandler(int a, int b); 4 5 public class A 6 { 7 //静态方法 8 public static int M1(int a, int b) 9 { 10 return a + b; 11 } 12 } 13 14 public class Test 15 { 16 public static void Main() 17 { 18 //实例一个委托

springmvc学习笔记(19)-RESTful支持

springmvc学习笔记(19)-RESTful支持 springmvc学习笔记19-RESTful支持 概念 REST的样例 controller REST方法的前端控制器配置 对静态资源的解析 本文介绍RESTful的概念,并通过一个小样例展示怎样编写RESTful风格的controller和配置前端控制器,最后展示静态资源的解析 概念 首先附上两篇博客链接 理解RESTful架构 - 阮一峰的网络日志 RESTful API 设计指南- 阮一峰的网络日志 RESTful架构.就是眼下最流

springmvc学习笔记---面向移动端支持REST API

前言: springmvc对注解的支持非常灵活和飘逸, 也得web编程少了以往很大一坨配置项. 另一方面移动互联网的到来, 使得REST API变得流行, 甚至成为主流. 因此我们来关注下springmvc对rest api的支持程度, 以及需要做的工作评估. 样例设计和准备: springmvc学习笔记系列的文章目录: • idea创建springmvc项目 REST API的设计原则遵循之前的博文来实现 • 移动互联网实战--Web Restful API设计和基础架构  初步设计一个查询系

SpringMVC学习笔记(二): 日常使用功能

前提: 1.web.xml 和spring-mvc核心配置如:SpringMVC学习笔记(一): 基础知识中注解实现. 2.类的@RequestMapping(value="/annotationController") 3.spring-mvc 推荐使用注解实现. 一.数据的接收 (一)URL参数数据的接收 1.使用 HttpServletRequest 获取参数 <span style="font-size:18px;"><span style

SpringMVC学习系列(12) 完结篇 之 基于Hibernate+Spring+Spring MVC+Bootstrap的管理系统实现

到这里已经写到第12篇了,前11篇基本上把Spring MVC主要的内容都讲了,现在就直接上一个项目吧,希望能对有需要的朋友有一些帮助. 一.首先看一下项目结构: InfrastructureProjects:是抽取出的基础项目,主要封装了一些通用的操作. SpringMVC3Demo:就是管理系统所在的项目. WeiXinAPI:是之前做微信管理平台测试时封装一些操作,如果不需要把该项目移除即可. 注:项目的前端UI框架用的是国外的一个基于Bootstrap框架的开发的Demo,如不需要替换为

史上最全的SpringMVC学习笔记

SpringMVC学习笔记---- 一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于SpringMVC的配置 <!--configure the setting of springmvcDispatcherServlet and configure the mapping--> <servlet> <servlet-name>springmvc</servlet

SpringMVC学习系列(11) 之 表单标签

本篇我们来学习Spring MVC表单标签的使用,借助于Spring MVC提供的表单标签可以让我们在视图上展示WebModel中的数据更加轻松. 一.首先我们先做一个简单了例子来对Spring MVC表单表单标签的使用有一个大致的印象,然后再结合例子对各个标签介绍一下如何使用. 1.首先,在com.demo.web.models包中添加一个模型TagsModel内容如下: package com.demo.web.models; import java.util.List; import ja

SpringMVC学习系列(7) 之 格式化显示

在系列(6)中我们介绍了如何验证提交的数据的正确性,当数据验证通过后就会被我们保存起来.保存的数据会用于以后的展示,这才是保存的价值.那么在展示的时候如何按照要求显示?(比如:小数保留一定的位数,日期按指定的格式等).这就是本篇要说的内容->格式化显示. 从Spring3.X开始,Spring提供了Converter SPI类型转换和Formatter SPI字段解析/格式化服务,其中Converter SPI实现对象与对象之间的相互转换,Formatter SPI实现String与对象之间的转