SSM學習——SpringMVC(2)

RequestMapping註解

看源碼

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

//標識了作用的地方,即方法和類之前
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
    String name() default "";

    @AliasFor("path")
    String[] value() default {};

    @AliasFor("value")
    String[] path() default {};

    RequestMethod[] method() default {};

    String[] params() default {};

    String[] headers() default {};

    String[] consumes() default {};

    String[] produces() default {};
}

注意標註位置

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("value") 
    //對所有的方法都會加上一個前綴,請求值等於value+test纔會進入test1
public class SpringMVCHandler {
    @RequestMapping("test")
    public String   test1(){
        return "success";
    }
}

映射請求方式

 //只能處理get的請求方式
 @RequestMapping(value = "RequestMapping",method = RequestMethod.GET)
    public String testMethod(){
        return "success";
    }
//我全都要
   @RequestMapping(value = "RequestMapping",method = {RequestMethod.GET,RequestMethod.POST})
    public String testMethod(){
        return "success";
    }    

映射請求頭和請求參數

params 和 headers支持簡單的表達式:
param1: 表示請求必須包含名爲 param1 的請求參數
!param1: 表示請求不能包含名爲 param1 的請求參數
param1 != value1: 表示請求包含名爲 param1 的請求參數,但其值不能爲 value1
{"param1=value1", "param2"}: 請求必須包含名爲 param1 和param2 的兩個請求參數,且 param1 參數的值必須爲 value1
    @RequestMapping(value = "testParamsAndHeader",            
    		params = {"username","age"},
            headers = {"Accept-language"})
public String   test2(){
        return "success";
    }
測試:
	<a href="springmvc/testParamsAndHeaders?username=atguigu&age=10">testParamsAndHeaders</a>

@PathVariable

帶佔位符的 URL 是 Spring3.0 新增的功能,該功能在 SpringMVC 向 REST 目標挺進發展過程中具有里程碑的意義
通過 @PathVariable 可以將 URL 中佔位符參數綁定到控制器處理方法的入參中:
URL 中的 {xxx} 佔位符可以通過 @PathVariable(“xxx”) 綁定到操作方法的入參中。

@RequestMapping(value="/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println("testPathVariable...id="+id);
return "success";
}
<!-- 測試 @PathVariable -->
<a href="springmvc/testPathVariable/1">testPathVariable</a>

REST

REST:即 Representational State Transfer。(資源)表現層狀態轉化。是目前最流行的一種互聯網軟件架構。它結構清晰、符合標準、易於理解、擴展方便,所以正得到越來越多網站的採用
HTTP 協議裏面,四個表示操作方式的動詞:GET、POST、PUT、DELETE。
它們分別對應四種基本操作:GET 用來獲取資源,POST 用來新建資源,PUT 用來更新資源,DELETE 用來刪除資源。

URL風格
	order/1  HTTP GET :得到 id = 1 的 order   
	order/1  HTTP DELETE:刪除 id = 1的 order   
	order    HTTP PUT:更新order   
	order     HTTP POST:新增 order 

HiddenHttpMethodFilter

瀏覽器 form 表單只支持 GET 與 POST 請求,而DELETE、PUT 等 method 並不支持,Spring3.0 添加了一個過濾器,可以將這些請求轉換爲標準的 http 方法,使得支持 GET、POST、PUT 與 DELETE 請求。
(idae打開源碼,需要按倆下shift,然後再輸入你所想要查詢的東西即可)

源碼分析

1.父類

public class HiddenHttpMethodFilter extends OncePerRequestFilter 

public abstract class OncePerRequestFilter extends GenericFilterBean 

public abstract class GenericFilterBean implements Filter, BeanNameAware, EnvironmentAware, EnvironmentCapable, ServletContextAware, InitializingBean, DisposableBean 

2.源碼分析

//過濾器的核心代碼
	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
 
		HttpServletRequest requestToUse = request;
 
		if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
			String paramValue = request.getParameter(this.methodParam);
			if (StringUtils.hasLength(paramValue)) {
				String method = paramValue.toUpperCase(Locale.ENGLISH);
				if (ALLOWED_METHODS.contains(method)) {
					requestToUse = new HttpMethodRequestWrapper(request, method);
				}
			}
		}
 
		filterChain.doFilter(requestToUse, response);
	}

當我們接受request(HttpServletRequest)請求時,它會告訴我們它傳過來的時“POST”還是“GET”請求,從上面代碼可知,我們只有“POST”請求的時候才能根據_method改變method方法名。接着它會幫我們把方法名變成全部大寫,然後調用一個HttpMethodRequestWrapper類的構造方法,request依舊不動,但是method變成了我們傳進來的參數,也就是我們要改成的方法名。wrapper作爲了一個新的HttpServletRequest回到了過濾器鏈之中。
修改web.xml


    <!-- 支持REST風格的過濾器:可以將POST請求轉換爲PUT或DELETE請求 -->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章