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>