Spring MVC使用@RequestMapping注解为控制器指定可以处理那些URL请求。
在控制器的类定义及方法定义处都可以标注
类定义处:提供初步的请求映射信息,相对于WEB应用的根目录
方法处:提供进一步的细分映射信息,相对于类定义出的URL。若类定义处未标注@RequestMapping,则方法处标记的URL相对于WEB应用的根目录。
DisPatcherServlet截获请求后,就通过控制器上的@RequestMapping提供的映射信息确定请求所对应的处理方法。
@RequestMapping除了可以使用请求URL映射请求外,还可以使用请求方法、请求参数及请求头映射请求
@RequestMapping的value、method、params及headers分别表示请求URL、请求方式、请求参数及请求头的映射条件,他们之间是与的关系,使用多个条件可以让请求映射更加精确。
params和headers支持简单的表达式:
param1:表示请求必须包含名为param1的请求参数
!param1:表示请求不能包含名为param1的请求参数
param1 != value1:表示请求包含名为param1的请求参数,但其值不能为value1
{“param1=value1”,“param2”}:请求必须包含名为param1和param2的两个请求参数,且param1参数的值必须为value1。
@Controller
public class HelloWorld {
private static final String SUCCESS = "success";
@RequestMapping("/hello")
public String HelloWorld() {
System.out.println("hello world!");
return SUCCESS;
}
//使用method属性指定请求方式是post还是get
@RequestMapping(value = "/method1",method = RequestMethod.GET)
public String method1() {
System.out.println("getmethod");
return SUCCESS;
}
//表示请求参数里面必须有username和age参数,并且age的参数必须是10,才可以匹配上。headers的使用类似
@RequestMapping(value = "/testParamsAndHeaders",params = {"username","age=10"})
public String testParamsAndHeaders() {
System.out.println("testParamsAndHeaders");
return SUCCESS;
}
}
@RequestMapping支持Ant风格的通配符,支持一下3种匹配符
? :表示匹配文件名中的一个字符
- :表示匹配文件名中的任意字符
** :表示匹配多层路径
/user/*/createUser :匹配/user/aaa/createUser、/user/bbb/createUser等URL
/user/**/createUser :匹配/user/createUser 、/user/aaa/bbb/createUser 等URL
/user/createUser?? :匹配/user/createUseraa、/user/createUserbb等URL
@PathVariable映射URL绑定的占位符
通过@PathVariable可以将URL中占位符参数绑定到控制器处理方法的入参中,URL中的{XXX}占位符可以通过@PathVariable(XXX)绑定到操作方法的入参中。占位符的名字和PathVariable中的名字必须一致
@RequestMapping("/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id")String id) {
System.out.println(id);
return SUCCESS;
}
// jsp中访问时,123会被赋值给id,然后id又会被传入到方法参数中
<a href="testPathVariable/123"><h1>testPathVariable</h1></a>
REST:
即Representational State Transfer。(资源)表现层转化。是目前最流行的一种互联网软件架构。他结构清晰,符合标准,易于理解,扩展方便。
资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本,一张图片,一首可取,一种服务,总之就是一个具体的存在,可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定URI。要获取这个资源,可以通过URI访问,因为URI是独一无二的识别符。
表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层。比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式。
状态转化(state transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。http协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,就必须通过某种手段,让服务器端发生”状态转化“。而这种转化时间里在表现层至上的,所以就是”表现层状态转化“。具体说,就是HTTP协里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四中基本操作,ge用来获取资源,post用来新建资源。put用来更新资源,delete用来删除资源
如:
/order/1 HTTP GET :得到id=1的 order
/order/1 HTTP DELETE:删除id=1的 order
/order/1 HTTP PUT:更新id=1的 order
/order HTTP POST:新增order
HiddenHttpMethodFilter:
浏览器form表单只支持GET与POST请求,而DELETE与PUT请求并不支持,Spring3.0添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT、DELETE请求。
HiddenHttpMethodFilter部分源码,截获post请求,然后根据页面_method属性的值来封装成SpringMVC具体的请求,_method为DELETE或PUT
public static final String DEFAULT_METHOD_PARAM = "_method";
private String methodParam = DEFAULT_METHOD_PARAM;
/**
* Set the parameter name to look for HTTP methods.
* @see #DEFAULT_METHOD_PARAM
*/
public void setMethodParam(String methodParam) {
Assert.hasText(methodParam, "'methodParam' must not be empty");
this.methodParam = methodParam;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String paramValue = request.getParameter(this.methodParam);
if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {
String method = paramValue.toUpperCase(Locale.ENGLISH);
HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);
filterChain.doFilter(wrapper, response);
}
else {
filterChain.doFilter(request, response);
}
}
具体使用时,需要先将HiddenHttpMethodFilter配置到web.xml中,使其生效。
<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>
然后在界面提交时使用post表单提交,并在表单中设置隐藏属性_method,设置为相应的DELETE,PUT,然后在Controller中映射方法时指定method的具体属性。
<form action="springmvc/testRest/1" method="post">
<input type="hidden" name="_mathod" value="DELETE"/>
<input type="submit" value="test" />
</form>
@RequestMapping(value = "/method1",method = RequestMethod.DELETE)
请求处理方法签名
SpringMVC通过分析处理方法的签名,将HTTP请求信息绑定到处理方法的入参中。
SpringMVC对控制器处理方法签名的限制是很宽松的,几乎可以按喜欢的任何方式对方法进行签名。
必要时可以对方法及方法入参标注相应的注解(@PathVariable,@RequestParam、@RequestHeader等)、SpringMVC框架会将HTTP请求的信息绑定到相应的方法入参中,并根据方法的返回类型做出相应的后续处理。
@RequestParam来映射请求参数
/**
* @RequestParam用来映射请求参数
* value 即请求的参数名
* required 该参数是否必须,默认是true
* defaultValue 请求参数的默认值
*/
@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam("username")String name,@RequestParam(value = "age",required = false,defaultValue = "0") int age) {
System.out.println("username is :" +name +";age is :" +age);
return SUCCESS;
}
@RequestHeader用法与@RequestParam相同,用于映射请求头中的属性。
@CookieValue用法与@RequestParam相同,用于映射请求中的cookie中的属性
@RequestMapping("/testRequestHeaders")
public String testRequestHeaders(@RequestHeader("Cookie") String cookie) {
System.out.println("cookie is :"+cookie);
return SUCCESS;
}
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue("JSESSIONID") String jessionid) {
System.out.println("cookie is :"+jessionid);
return SUCCESS;
}
使用POJO对象绑定请求参数值
SpringMVC会按请求参数名和POJO属性名进行自动匹配,自动为该对象填充属性值。支持级联属性,如dept.deptId、dept.address.tel等。
@RequestMapping("/testPojo")
public String testPojo(User user) {
System.out.println(user.toString());
return SUCCESS;
}
SpringMVC使用Servlet原生API:
SpringMVC的Handler中的方法可以接受下面ServletAPI类型的参数:
HttpServletRequest
HttpServletResponse
HttpSession
java.security.principal
Local
InputStream
OutputStream
Reader
Writer