ajax 对springmvc支持

最直接的Ajax处理

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

Controller示例

@RequestMapping(value = "/hello")

public ModelAndView handleRequest(UserModel um,HttpServletResponse response) throws IOException {

response.setCharacterEncoding("utf-8");

response.getWriter().println("{uuid:'"+um.getUuid()+"',name:'"+um.getName()+"'}");

return null;

}

客户端示例,使用jQuery

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

</head>

<script language="javascript" src="/mvcexample/static/js/jquery-1.3.2.min.js"></script>

<script language="javascript">

$().ready(function(){

$.getJSON('/mvcexample/hello',{uuid:'1',name:'test'},function(data){

alert(data.uuid+" , "+data.name);

});

});

</script>

</html>

 

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

数据绑定@RequestBody/@ResponseBody

@RequestBody

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

例子:

@RequestMapping(value = "/hello")

public byte[] handleRequest(@RequestBody String body)

@ResponseBody

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

例子:

@RequestMapping(value = “/hello")

@ResponseBody

public byte[] handleRequest(@RequestBody String body)

 

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

 

使用@RequestBody/@ResponseBody来支持Ajax

n可以使用@RequestBody来自动获取Ajax上传的数据

n同时也可以使用@ResponseBody,把要返回的对象自动拼成JSON的格式返回

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

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

n测试使用的Controller的方法:

@RequestMapping(value = "/hello")

@ResponseBody

public UserModel handleRequest(@RequestBody String reqBody, UserModel um) {

System.out.println("the reqBody="+reqBody);

um.setName(um.getName()+",server");

return um;

}

 

n测试使用的页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

</head>

<script language="javascript" src="/mvcexample/static/js/jquery-1.3.2.min.js"></script>

<script language="javascript">

$().ready(function(){

$.getJSON('/mvcexample/hello',{uuid:'1',name:'test'},function(data){

alert(data.uuid+" , "+data.name);

});

});

</script>

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

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

n测试使用的Controller方法

@RequestMapping(value = "/hello")

@ResponseBody

public List<UserModel> handleRequest(@RequestBody String reqBody, UserModel um) {

System.out.println("the reqBody="+reqBody);

um.setName(um.getName()+",server");

List<UserModel> list = new ArrayList<UserModel>();

list.add(um);

UserModel um2 = new UserModel();

um2.setUuid("22");

um2.setName("222");

list.add(um2);

return list;

}

n测试使用的页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>

<script language="javascript" src="/mvcexample/static/js/jquery-1.3.2.min.js"></script>

<script language="javascript">

$().ready(function(){

$.getJSON('/mvcexample/hello',{uuid:'1',name:'test'},function(data){

$.each(data,function(index,v){

alert("tr="+v.uuid+",v="+v.name);

});

});

});

</script>

 

使用HttpEntity/ResponseEntity来支持Ajax

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

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

@RequestMapping(value = "/hello")

public ResponseEntity<List<UserModel>> handleRequest(HttpEntity<String> req, UserModel um) {

System.out.println("req headers="+req.getHeaders()+", reqBody="+req.getBody());

 

um.setName(um.getName()+",server");

List<UserModel> list = new ArrayList<UserModel>();

list.add(um);

UserModel um2 = new UserModel();

um2.setUuid("22");

um2.setName("222");

list.add(um2);

 

ResponseEntity<List<UserModel>> ret = new ResponseEntity<List<UserModel>>(list,HttpStatus.OK);

return ret;

}

对Ajax返回xml的支持

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

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

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

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

@XmlRootElement(name = "testxml")

public class UserModel {

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

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

 

示例的Controller方法

@RequestMapping(value = "/hello")

@ResponseBody

public UserModel handleRequest(HttpEntity<String> req, UserModel um) {

System.out.println("req headers="+req.getHeaders()+", reqBody="+req.getBody());

 

um.setName(um.getName()+",server");

 

PhoneNumberModel pnm = new PhoneNumberModel("123","321");

PhoneNumberModel pnm2 = new PhoneNumberModel("2222","333");

List<PhoneNumberModel> tempList = new ArrayList<PhoneNumberModel>();

tempList.add(pnm2);

tempList.add(pnm);

 

um.setPm(tempList);

 

return um;

}

 

n示例的页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>

<script language="javascript" src="/mvcexample/static/js/jquery-1.3.2.min.js"></script>

<script language="javascript">

$().ready(function(){

$.ajax({

      url:'/mvcexample/hello',

      type: 'POST',

      dataType: 'xml',

      data: {uuid:'1',name:'test'},

      timeout: 1000,

      error: function(){    alert('Error loading XML document');       },

      success: function(xml){

      $(xml).find("testxml").children("pm").each(function(i){

             var uuid=$(this).children("areaCode").text();

             var name=$(this).children("phoneNumber").text();

             alert("uuid="+uuid+",name="+name);

            

      });        }    }); });

</script>

n返回的xml形如

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<testxml>

<age>0</age>

<name>test,server</name>

<pm>

<areaCode>2222</areaCode>

<phoneNumber>333</phoneNumber>

</pm>

<pm>

<areaCode>123</areaCode>

<phoneNumber>321</phoneNumber>

</pm>

<uuid>1</uuid>

</testxml>

 

HttpMessageConverter

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

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

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

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

ByteArrayHttpMessageConverter

StringHttpMessageConverter

ResourceHttpMessageConverter

SourceHttpMessageConverter<T>

XmlAwareFormHttpMessageConverter

Jaxb2RootElementHttpMessageConverter

MappingJacksonHttpMessageConverter

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

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

 

内容协商

n什么是内容协商

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

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

 

nSpring 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的简洁风范

n

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

 

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

<!--1、检查扩展名(如my.pdf);2、检查Parameter(如my?format=pdf);3、检查Accept Header-->

 <bean id= "contentNegotiationManager"

class= "org.springframework.web.accept.ContentNegotiationManagerFactoryBean">

        <!-- 扩展名至mimeType的映射,即 /user.json => application/json -->

        <property name= "favorPathExtension" value= "true" />

        <!-- 用于开启 /userinfo/123?format=json 的支持 -->

        <property name= "favorParameter" value= "true" />

        <property name= "parameterName" value= "format"/>

        <!-- 是否忽略Accept Header -->

        <property name= "ignoreAcceptHeader" value= "false"/>

 <property name= "mediaTypes">

<!--扩展名到MIME的映射;favorPathExtension, favorParameter是true时起作用  -->

            <value>

                ccjson=application/json

                ccxml=application/xml

                html=text/html

            </value>

        </property>

        <!-- 默认的content type -->

        <property name= "defaultContentType" value= "text/html" />

    </bean>

 

<!-- ========================= VIEW定义 ========================= -->

<!-- 内容协商视图解析器;根据客户端不同的请求决定不同的view进行响应 -->

    <!-- 会自动根据解析的contentType来决定使用哪个视图解析器(默认使用整个web应用中的viewResolver) -->

    <bean class= "org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:order= "0">

        <!-- 内容协商管理器 用于决定media type -->

        <property name= "contentNegotiationManager" ref= "contentNegotiationManager"/>

        <!-- 默认视图 放在解析链最后 -->

        <property name= "defaultViews">

            <list>

               <bean class= "org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>

                <bean class= "org.springframework.web.servlet.view.xml.MarshallingView">

                <property name= "marshaller"

                    <bean class= "org.springframework.oxm.jaxb.Jaxb2Marshaller">

                        <property name= "packagesToScan" value= "cn.javass"></property>

                    </bean>

                </property>

                </bean>

            </list>

        </property>

    </bean>

 

<!-- bean name view resolver-->

    <bean class= "org.springframework.web.servlet.view.BeanNameViewResolver" p:order= "1"/>

    <!-- 默认的视图解析器 在上边的解析错误时使用 (默认使用 html)- -->

    <bean id= "defaultViewResolver"

        class= "org.springframework.web.servlet.view.InternalResourceViewResolver" p:order= "2">

        <property name= "viewClass" value= "org.springframework.web.servlet.view.JstlView"/>

        <property name= "contentType" value= "text/html"/>

        <property name= "prefix" value= "/WEB-INF/jsp/"/>

        <property name= "suffix" value= ".jsp"/>

    </bean>

n在mvc:annotation-driven里面配置使用内容协商

<mvc:annotation-driven

      validator= "validator"

      conversion-service= "conversionService"

      content-negotiation-manager= "contentNegotiationManager"

      >

</mvc:annotation-driven>

 

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',

 

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

 

转载于:https://my.oschina.net/u/2349605/blog/906971

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值