我的學習參考所用,勿噴! html
返回JSON java
1) 用Maven構建web項目: web
構建過程參考limingnihao的blog(寫得至關的詳細!!!):使用Eclipse構建Maven的SpringMVC項目 ajax
註解@ResponseBody能夠將結果(一個包含字符串和JavaBean的Map),轉換成JSON。因爲Spring是採用對JSON進行了封裝的jackson來生成JSON和返回給客戶端,因此這裏須要添加jackson的相關包。項目的pom.xml配置以下: spring
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/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.watson</groupId>
- <artifactId>rest-spring</artifactId>
- <packaging>war</packaging>
- <version>0.0.1-SNAPSHOT</version>
- <name>rest-spring Maven Webapp</name>
- <url>http://maven.apache.org</url>
-
- <dependencies>
- <!-- 省略其餘配置,具體能夠參考附件-->
- ......
- <dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
- <version>1.4.2</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-core-asl</artifactId>
- <version>1.4.2</version>
- </dependency>
- </dependencies>
- </project>
2) 在web.xml配置Spring的請求處理的Servlet,具體設置: apache
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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- 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>Spring-Rest</display-name>
- <servlet>
- <servlet-name>rest</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>/WEB-INF/rest-servlet.xml</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>rest</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
- </web-app>
3) 在rest-servlet.xml中配置以下: json
Xml代碼
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd
- http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
-
- <context:component-scan base-package="com.mkyong.common.controller" />
- <mvc:annotation-driven />
-
- </beans>
爲了解決亂碼問題,須要添加以下配置,而且這裏能夠顯示的添加MappingJacksonHttpMessageConverter這個轉換器。 瀏覽器
Xml代碼
- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
- <property name="messageConverters">
- <list>
- <bean class="org.springframework.http.converter.StringHttpMessageConverter">
- <property name="supportedMediaTypes">
- <list>
- <value>text/plain;charset=UTF-8</value>
- </list>
- </property>
- </bean>
- <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
- </list>
- </property>
- </bean>
4) 編寫本身的服務組件類,使用MVC的annotation風格,使用 @ResponseBody處理返回值。具體代碼以下: spring-mvc
Java代碼
- @RequestMapping("/jsonfeed")
- public @ResponseBody Object getJSON(Model model) {
- List<TournamentContent> tournamentList = new ArrayList<TournamentContent>();
- tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "World Cup", "www.fifa.com/worldcup/"));
- tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "U-20 World Cup", "www.fifa.com/u20worldcup/"));
- tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "U-17 World Cup", "www.fifa.com/u17worldcup/"));
- tournamentList.add(TournamentContent.generateContent("中超", new Date(), "中超", "www.fifa.com/confederationscup/"));
- model.addAttribute("items", tournamentList);
- model.addAttribute("status", 0);
-
- return model;
- }
5)將運行項目,在瀏覽器中輸入http://[host]:[port]/[appname]/jsonfeed.json,例如樓主的實例中輸入以下:http://localhost:7070/rest-spring/jsonfeed/,獲得結果爲: mvc
Json代碼
- {"status":0,"items":[{"name":"World Cup","id":8,"link":"www.fifa.com/worldcup/","author":"FIFA","publicationDate":1334559460940},{"name":"U-20 World Cup","id":9,"link":"www.fifa.com/u20worldcup/","author":"FIFA","publicationDate":1334559460940},{"name":"U-17 World Cup","id":10,"link":"www.fifa.com/u17worldcup/","author":"FIFA","publicationDate":1334559460940},{"name":"Confederations Cup","id":11,"link":"www.fifa.com/confederationscup/","author":"FIFA","publicationDate":1334559460940}]}
這裏咱們也能夠利用Spring3MVC中對試圖和內容協商的方法來處理返回JSON的狀況,下面步驟接上面第2步:
3) 在rest-servlet.xml中對相關進行具體的設置:
Xml代碼
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
- xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd
- http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
-
- <!-- 自動搜索@Controller標註的類,包括其下面的子包 -->
- <context:component-scan base-package="com.watson.rest" />
-
- <!-- 根據客戶端的不一樣的請求決定不一樣的view進行響應, 如 /blog/1.json /blog/1.xml -->
- <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
- <!-- 設置爲true以忽略對Accept Header的支持 -->
- <property name="ignoreAcceptHeader" value="true" />
-
- <!-- 在沒有擴展名時即: "/blog/1" 時的默認展示形式 -->
- <property name="defaultContentType" value="text/html" />
-
- <!-- 擴展名至mimeType的映射,即 /blog.json => application/json -->
- <property name="mediaTypes">
- <map>
- <entry key="html" value="text/html" />
- <entry key="pdf" value="application/pdf" />
- <entry key="xsl" value="application/vnd.ms-excel" />
- <entry key="xml" value="application/xml" />
- <entry key="json" value="application/json" />
- </map>
- </property>
-
- <!-- 用於開啓 /blog/123?format=json 的支持 -->
- <property name="favorParameter" value="false" />
- <property name="viewResolvers">
- <list>
- <bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
- <property name="prefix" value="/pages" />
- <property name="suffix" value=".jsp"></property>
- </bean>
- </list>
- </property>
- <property name="defaultViews">
- <list>
- <!-- for application/json -->
- <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
- <!-- for application/xml -->
- <!--
- <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
- <property name="marshaller">
- <bean class="org.springframework.oxm.xstream.XStreamMarshaller"/>
- </property>
- </bean>
- -->
- </list>
- </property>
- </bean>
- </beans>
4)編寫本身的服務組件類,使用MVC的annotation風格,這裏能夠再也不使用@ResponseBody斷言。具體代碼以下:
Java代碼
- //FINAL
- package com.watson.rest.json;
-
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.Model;
- import org.springframework.web.bind.annotation.RequestMapping;
-
- import com.watson.rest.feeds.TournamentContent;
-
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.List;
-
-
- @Controller
- public class FeedController {
- @RequestMapping("/jsonfeed")
- public String getJSON(Model model) {
- List<TournamentContent> tournamentList = new ArrayList<TournamentContent>();
- tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "World Cup", "www.fifa.com/worldcup/"));
- tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "U-20 World Cup", "www.fifa.com/u20worldcup/"));
- tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "U-17 World Cup", "www.fifa.com/u17worldcup/"));
- tournamentList.add(TournamentContent.generateContent("FIFA", new Date(), "Confederations Cup", "www.fifa.com/confederationscup/"));
- model.addAttribute("items", tournamentList);
- model.addAttribute("status", 0);
- return "jsontournamenttemplate";
- }
- }
這裏的TournamentContent是自定義的POJO類:
Java代碼
- public class TournamentContent {
- private static int idCounter = 0;
- private String author;
- private Date publicationDate;
- private String name;
- private String link;
- private int id;
-
- public static TournamentContent generateContent(String author, Date date, String name, String link) {
- TournamentContent content = new TournamentContent();
- content.author = author;
- content.publicationDate = date;
- content.name = name;
- content.link = link;
- content.id = idCounter++;
-
- return content;
- }
-
- //省略getter、setter
- }
5)將運行項目,在瀏覽器中輸入http://[host]:[port]/[appname]/jsonfeed.json,例如樓主的實例中輸入以下:http://localhost:7070/rest-spring/jsonfeed.json,獲得結果爲:
Json代碼
- {"status":0,"items":[{"name":"World Cup","id":8,"link":"www.fifa.com/worldcup/","author":"FIFA","publicationDate":1334559460940},{"name":"U-20 World Cup","id":9,"link":"www.fifa.com/u20worldcup/","author":"FIFA","publicationDate":1334559460940},{"name":"U-17 World Cup","id":10,"link":"www.fifa.com/u17worldcup/","author":"FIFA","publicationDate":1334559460940},{"name":"Confederations Cup","id":11,"link":"www.fifa.com/confederationscup/","author":"FIFA","publicationDate":1334559460940}]}
至此,Spring RESTful服務返回JSON的實踐基本完成(由於這裏對EXCEPTION的處理還夠)。我的認爲第一種方式更加適合通常的使用,特別是顯示的添加MappingJacksonHttpMessageConverter這個轉換器和對亂碼的處理。
接收JSON
使用 @RequestBody 註解前臺只須要向 Controller 提交一段符合格式的 JSON,Spring 會自動將其拼裝成 bean。
1)在上面的項目中使用第一種方式處理返回JSON的基礎上,增長以下方法:
Java代碼
- @RequestMapping(value="/add",method=RequestMethod.POST)
- @ResponseBody
- public Object addUser(@RequestBody User user)
- {
- System.out.println(user.getName() + " " + user.getAge());
- return new HashMap<String, String>().put("success", "true");
- }
這裏的POJO以下:
Java代碼
- public class User {
- private String name;
- private String age;
-
- //getter setter
- }
2)而在前臺,咱們能夠用 jQuery 來處理 JSON。從這裏,我獲得了一個 jQuery 的插件,能夠將一個表單的數據返回成JSON對象:
Js代碼
- $.fn.serializeObject = function(){
- var o = {};
- var a = this.serializeArray();
- $.each(a, function(){
- if (o[this.name]) {
- if (!o[this.name].push) {
- o[this.name] = [o[this.name]];
- }
- o[this.name].push(this.value || '');
- }
- else {
- o[this.name] = this.value || '';
- }
- });
- return o;
- };
如下是使用 jQuery 接收、發送 JSON 的代碼:
Js代碼
- $(document).ready(function(){
- jQuery.ajax({
- type: 'GET',
- contentType: 'application/json',
- url: 'jsonfeed.do',
- dataType: 'json',
- success: function(data){
- if (data && data.status == "0") {
- $.each(data.data, function(i, item){
- $('#info').append("姓名:" + item.name +",年齡:" +item.age);
- });
- }
- },
- error: function(){
- alert("error")
- }
- });
- $("#submit").click(function(){
- var jsonuserinfo = $.toJSON($('#form').serializeObject());
- jQuery.ajax({
- type: 'POST',
- contentType: 'application/json',
- url: 'add.do',
- data: jsonuserinfo,
- dataType: 'json',
- success: function(data){
- alert("新增成功!");
- },
- error: function(){
- alert("error")
- }
- });
- });
- });
可是彷佛用Spring這套東西真是個麻煩的事情,相對Jersey對RESTful的實現來看,確實有不少不簡潔的地方。
參考:
官方文檔:http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch18.html
badqiu的BOLG: 《spring REST中的內容協商(同一資源,多種展示:xml,json,html)》
liuweifeng的BOLG :http://blog.liuweifeng.net/archives/407
Gary Mark等的書籍:《Spring Recipes》2ed