ajax 對springmvc支持

最直接的Ajax處理javascript

只要在Controller的方法裏面,直接使用response輸出你要返回的的Ajax數據,而後return null就能夠了,示例以下:html

Controller示例java

@RequestMapping(value = "/hello")jquery

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

response.setCharacterEncoding("utf-8");web

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

return null;spring

}json

客戶端示例,使用jQueryapi

<%@ 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的配置文件中作配置,示例以下:

<!--一、檢查擴展名(如my.pdf);二、檢查Parameter(如my?format=pdf);三、檢查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',

 

應該能夠看到根據不一樣的請求,服務端回返回不一樣格式的數據。

相關文章
相關標籤/搜索