Spring MVC Rest 學習 二

 一、Controller應該是SpringMVC的核心,Controller中要學習的註解也是多之又多,不過這些註解在程序中的做用確實不可小覷,看看列出這幾項:
html

@Controller  :  定義一個類爲控制器,這個與 @Repository 有點像java

@RequestMapping : 定義Controller的URL映射以及請求方法node

@PathVariable : 定義路徑參數,Rest自己就是把資源進行惟必定義,那麼URL中使用參數也是惟必定義的一種形式web

@ResponseBody : 定義返回結果,這個在ajax請求的時候特別有用,由於不須要跳轉到其餘URLajax

@ResponseStatus : 定義返回狀態spring

@RequestParam : 定義請求參數,若是是前臺與後臺同名參數,那麼不必使用它數據庫

........................json

    下面貼出Controller的代碼
api

/**
 * <p>項目名稱:restful
 * <p>Package名稱:com.hnust.controller
 * 文件名稱:ResourceController.java 
 * 版本:1.00 
 * 建立日期:2014年10月26日
 * Copyright©2014 HNUST .All Rights Reserved.
 */
package com.hnust.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hnust.bean.Message;
import com.hnust.bean.Resource;
import com.hnust.service.ResourceService;

/**
 *
 *@author:Heweipo
 *@version 1.00
 *
 */
@Controller
@RequestMapping("/resource")
public class ResourceController {

	@Autowired
	private ResourceService service;
	
	/**
	 * 
	 * <p>經過id獲取資源
	 * 在這裏採用@PathVariable註解,同時返回一個String,讓SpringMVC自動尋找最合適的視圖解析器
	 * 優勢是可以找到html視圖解析器,可是缺點是,JavaBean轉爲XML格式,
	 * 須要在 org.springframework.oxm.jaxb.Jaxb2Marshaller綁定JavaBean
	 * 因此 這裏Resource必定要進行綁定
	 * @param id
	 * @param model
	 * @return 
	 * @return String    
	 * author: Heweipo
	 */
	@RequestMapping(value="/get/{id}" , method=RequestMethod.GET)
	public String get(@PathVariable("id") String id , ModelMap model){
		model.put("resource", service.getResource(id));
		return "resource";
	}
	
	/**
	 * 
	 * <p>存儲resource,另外,關於resource的number參數注入很值得注意,若是URL中攜帶的參數不能轉爲
	 * Integer類型,那麼是沒法繼續訪問這個方法的!!因此,對於JavaBean最好設置與數據庫對應的數據類型
	 * 進行類型約束。
	 * 在這裏採用@ResponseBody註解,那麼返回的對象將會被對應的視圖解析器解析,
	 * 可是不會有html解析器,可是有一個
	 * 優勢:javaBean 若是轉爲 XML 是不須要在spring-servlet 中
	 * org.springframework.oxm.jaxb.Jaxb2Marshaller 綁定的
	 * @param resource
	 * @param model 
	 * @return void    
	 * author: Heweipo
	 */
	@RequestMapping(value="/put" , method=RequestMethod.PUT)
	public @ResponseBody Message put(Resource resource , ModelMap model){
		Message message = new Message();
		if(StringUtils.isEmpty(resource.getId()) 
		        || StringUtils.isEmpty(resource.getName())){
			message.setMsg("請輸入id 和 用戶名");
			message.setResult("faile");
			return message;
		}
		service.insertResource(resource);
		message.setMsg("數據已經存儲");
		message.setResult("success");
		return message;
	}
	
	/**
	 * 
	 * <p>經過id更新resource
	 * @param resource
	 * @param model
	 * @return 
	 * @return Message    
	 * author: Heweipo
	 */
	@RequestMapping(value="/post" , method=RequestMethod.POST)
	public @ResponseBody Message post(Resource resource , ModelMap model){
		Message message = new Message();
		if(StringUtils.isEmpty(resource.getId())){
			message.setMsg("id不能爲空");
			message.setResult("faile");
			return message;
		}
		service.updateResource(resource);
		message.setMsg("數據已經修改");
		message.setResult("success");
		return message;
	}
	
	/**
	 * 
	 * <p>經過id刪除資源
	 * @param id
	 * @param model
	 * @return 
	 * @return Message    
	 * author: Heweipo
	 */
	@RequestMapping(value="/delete/{id}" , method=RequestMethod.DELETE)
	public @ResponseBody Message delete(@PathVariable("id")String id, ModelMap model){
		Message message = new Message();
		service.deleteResource(id);
		message.setMsg("數據已刪除");
		message.setResult("success");
		return message;
	}
	
}

注意的幾點說明:restful

1)關於請求參數自動封裝問題,當咱們在方法的形參中採用JavaBean時,SpringMVC會把請求的參數中與JavaBean對應的屬性封裝成JavaBean的一個實例返回,若是有些屬性沒有值,他就爲空;若是屬性值進行賦值是類型轉換髮生錯誤,則沒法請求URL。封裝好的JavaBean實例會存儲在ModelMap中,而且以JavaBean的類名首字母小寫的形式做爲key值,因此,你能夠 這樣獲取 model.get('resource');實際這也是很經常使用的,由於 XML解析的時候須要一個根元素,那麼,若是咱們的model中存儲太多的元素XML是沒法解析的。這個Controller不存在這種狀況,緣由是我是用了@ResponseBody

2)關於返回值的問題,@ResponseBody 是返回值的標識,尤爲是對象解析的時候特別有用。並且,使用@ResponseBody後,對於XML解析的對象均可以不用在spring-servlet中進行綁定,然而,若是咱們有些時候須要返回一個html,或者Json,或者XML的時候,咱們就不會去使用@ResponseBody,而是採用String的形式,把返回的對象存儲在model中。當返回值爲null時效果與@ResponseBody 是同樣的。

下面是修改後的代碼:

/**
	 * 
	 * <p>經過id更新resource
	 * Message 必定要在 org.springframework.oxm.jaxb.Jaxb2Marshaller 綁定
	 * @param resource
	 * @param model
	 * @return 
	 * @return Message    
	 * author: Heweipo
	 */
	@RequestMapping(value="/post" , method=RequestMethod.POST)
	public String post(Resource resource , ModelMap model){
		// 這裏清除掉SpringMVC幫咱們封裝的JavaBean
		model.remove("resource");
		Message message = new Message();
		// 這裏存儲咱們須要解析的JavaBean
		model.put("message", message);
		if(StringUtils.isEmpty(resource.getId())){
			message.setMsg("id不能爲空");
			message.setResult("faile");
			return null;
		}
		service.updateResource(resource);
		message.setMsg("數據已經修改");
		message.setResult("success");
		// 返回空的效果和使用@ResponseBody是同樣的,可是原理不一樣,
		// @ResponseBody 貌似採用了Servlet3.0 的異步特性
		return null;
	}

對應的spring-servlet.xml源代碼:

 <!-- XML 與 Java 數據轉換  -->
	  <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
		<property name="classesToBeBound">
			<list>
			 <!-- 須要在這裏綁定,緣由是controller裏沒有采用@ResponseBody進行返回 -->
			 <value>com.hnust.bean.Message</value>
			</list>
		</property>
	  </bean>

2 請求類型

    在@RequestMapping中咱們對method進行賦值,若是賦值了那麼必須按照對應的請求方法進行訪問,否者出現405.該項目中採用測試工具進行測試:

工具採用:Firefox 的RestClient 插件 https://addons.mozilla.org/zh-CN/firefox/addon/restclient/

1)新增資源:put  http://localhost:8080/restful/resource/put?id=id_888&name=ireport&number=89

<message>
<msg>數據已經存儲</msg>
<result>success</result>
</message>

2)更新資源 post http://localhost:8080/restful/resource/post?id=id_888&name=node.js&number=12

<message>
<msg>數據已經更新</msg>
<result>success</result>
</message>

3) 刪除資源 delete http://localhost:8080/restful/resource/delete/id_888

<message>
<msg>數據已刪除</msg>
<result>success</result>
</message>

3 關於返回內容格式

    內容協商機制很簡單,有兩種方式,一種是該項目中使用的視圖渲染進行內容協商,另一種則是進行類型轉換,本項目中源碼以下:

  <!-- 主要是進行Controller 和 URL 的一些註解綁定,這裏能夠進行轉換器配置:只有配置好了轉換器才能進行類與JSON和XML的轉換,固然只是針對基於轉換器協商資源表述 -->
	  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
	  
	  
	   <!-- XML 與 Java 數據轉換  -->
	  <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
		<property name="classesToBeBound">
			<list>
				<!--common XML 映射  JavaBean 註冊  -->
				<value>com.hnust.bean.Resource</value> 
				<!-- 不須要在這裏綁定,緣由是controller裏採用ResponseBody進行返回 -->
				<!-- <value>com.hnust.bean.Message</value>  -->
			</list>
		</property>
	  </bean>
	  
	  <!-- 基於視圖渲染進行協商資源表述  -->
	  <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
	  	<!-- restful 是否採用擴展名的方式肯定內容格式,id.json 返回JSON格式 -->
	    <property name="favorPathExtension" value="true"></property>
	  
	    <!-- restful 是否採用參數支持肯定內容格式,id?format=json 返回JSON格式 -->
	    <property name="favorParameter" value="true"></property>
	  
	    <!-- restful 是否忽略掉accept header,Accept:application/json -->
	    <property name="ignoreAcceptHeader" value="false"></property>
	    
	    <!-- 基於視圖按順序解析  -->
	    <property name="order" value="1" />
	    
	    <!-- 對採用擴展名,參數新式的 URL 進行獲取對應的 accept  -->
		<property name="mediaTypes">
		    <map>
		    	<entry key="json" value="application/json"/>
		        <entry key="xml" value="application/xml"/>
		        <entry key="html" value="text/html"/>
		    </map>
		</property>
		
		<!-- 若是擴展名,參數甚至header 信息都沒有找到對應的accept時  -->
		<property name="defaultContentType" value="text/html"/>
		
		<!-- 採用對應的視圖進行渲染  -->
		<property name="defaultViews">
		    <list >
				<!-- 轉換Java對象爲XML格式數據 -->
				<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
					<constructor-arg ref="jaxbMarshaller" />
				</bean>
				
				<!-- 轉換Java對象爲JSON 格式數據 -->
				<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/> 
		    </list>
		</property>
		<!-- 採用對應的視圖進行渲染  -->
		<property name="viewResolvers">
		    <list >
		    	<!-- 查找在上下文中定義了ID的Bean,而且定位該ID  -->
		        <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
		        <!-- 對Controller中返回的視圖實例進行解析,而且組裝URL定位到對應的資源  -->
		        <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
					<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
					<property name="prefix" value="/WEB-INF/jsp/"/>
					<property name="suffix" value=".jsp"/>
				</bean>
		    </list>
		</property>
	</bean>

然而若是使用轉換機制的話:

<!-- 輸出字符串內容,非路徑 -->
	<bean id="stringConverter"
		class="org.springframework.http.converter.StringHttpMessageConverter">
		<property name="supportedMediaTypes">
			<list>
				<value>text/plain;charset=UTF-8</value>
			</list>
		</property>
	</bean>

	<!-- JSON -->
	<bean id="jsonConverter"
		class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
	 <bean id="marshallingHttpMessageConverter"
          class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
        <constructor-arg ref="jaxbMarshaller"/>
        <property name="supportedMediaTypes" value="application/xml" />
    </bean>

    <!-- 基於轉換器進行內容協商 -->
    <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <!-- XML轉換器須要綁定須要轉換的類 -->
        <property name="classesToBeBound">
            <list>
                <value>com.hnust.bean.Resource</value>
            </list>
        </property>
    </bean>
		
    <!-- 註冊對象轉換器  -->	
    <bean
	class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
	    <property name="messageConverters">
		<list>
			<ref bean="stringConverter" />
			<ref bean="jsonConverter" />
                        <ref bean="marshallingHttpMessageConverter"/>
		</list>
	</property>
    </bean>

4 pom文件,獲取jar包

  	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
		<version>3.2.8.RELEASE</version>
	</dependency>
  
  	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
		<version>3.2.8.RELEASE</version>
	</dependency>
	
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-oxm</artifactId>
		<version>3.2.8.RELEASE</version>
	</dependency>
	
  
 	<dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>jstl</artifactId>
		<version>1.2</version>
	</dependency>
	<dependency>
		<groupId>log4j</groupId>
		<artifactId>log4j</artifactId>
		<version>1.2.17</version>
	</dependency>
	<dependency>
		<groupId>commons-logging</groupId>
		<artifactId>commons-logging</artifactId>
		<version>1.1.3</version>
	</dependency>
	<dependency>
		<groupId>net.sf.json-lib</groupId>
		<artifactId>json-lib</artifactId>
		<version>2.4</version>
		<classifier>jdk15</classifier>
	</dependency>
	<dependency>
		<groupId>org.codehaus.jackson</groupId>
		<artifactId>jackson-mapper-asl</artifactId>
		<version>1.9.13</version>
	</dependency>
  
  	<dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>servlet-api</artifactId>
		<version>3.0-alpha-1</version>
	</dependency>

5 項目源碼連接:

 http://download.csdn.net/detail/wp562846864/8113077

說明:源碼中沒有jar包,由於Maven項目,jar包就經過pom文件去取吧,若是實在須要,能夠留言.....

相關文章
相關標籤/搜索