SpringMVC使用@RequestMapping
注解为控制器指定可以处理哪些URL请求。
对于@RequestMapping
注解,在控制器的类定义及方法定义处都可以标注
@RequestMapping
,则方法处标记的URL相对于WEB应用的根目录。DispatcherServlet截获请求后,就通过控制器上@RequestMapping
提供的映射信息确定请求所对应的处理方法
首先web.xml
配置如下:
contextConfigLocation
/WEB-INF/applicationContext.xml
org.springframework.web.context.ContextLoaderListener
dispatcher
org.springframework.web.servlet.DispatcherServlet
1
dispatcher
/
dispatcher-servlet.xml
配置如下:
我们创建一个控制器类SpringMVCTest
,代码如下:
package com.cerr.springmvc.handlers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
private static final String SUCCESS = "success";
@RequestMapping("/testRequestMapping")
public String testRequestMapping(){
System.out.println("testRequestMapping");
return SUCCESS;
}
}
对于这个控制器类,我们在类定义处注解了@RequestMapping("/springmvc")
,在方法定义处注解了@RequestMapping("/testRequestMapping")
,则该方法的映射链接为:springmvc/testRequestMapping。
在index.jsp中
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
Test
@RequestMapping
除了可以使用请求URL映射请求外,还可以使用请求方法、请求参数及请求头映射请求。
@RequestMapping
的value
、method
、params
及heads
分别表示请求URL、请求方法、请求参数及请求头的映射条件,他们之间是与的关系,联合使用多个条件可以让请求映射更加精确化。
对于请求参数及请求头,params和headers支持简单的表达式:
例如:
package com.cerr.springmvc.handlers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
private static final String SUCCESS = "success";
/***
* 映射URL和请求参数
* @return
*/
@RequestMapping(value = "testParamsAndHeaders",params = {"username","age!=10"})
public String testParamsAndHeaders(){
System.out.println("testParamsAndHeaders");
return SUCCESS;
}
/**
* 映射URL和请求方法
* @return
*/
@RequestMapping(value = "/testMethod",method = RequestMethod.POST)
public String testMethod(){
System.out.println("testMethod");
return SUCCESS;
}
}
对于@RequestMapping
注解,还支持通配符:
?
:匹配文件名中的一个字符*
:匹配文件名中的任意字符**
:匹配多层路径例如:@RequestMapping("/testAntPath/*/abc")
,可以匹配/springmvc/testAntPath/mmmm/abc
等等,其中的mmmm可以替换为任意的字符。
通过@PathVariable
注解可以将URL中占位符参数绑定到控制器处理方法的入参中:URL中的{xxx}占位符通过@PathVariable("xxx")
绑定到操作方法的入参中,例如:
package com.cerr.springmvc.handlers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
private static final String SUCCESS = "success";
/***
* @PathVariable可以来映射URAL中的占位符到目标方法的参数中
* @param id
* @return
*/
@RequestMapping("/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println("testPathVariable "+ id);
return SUCCESS;
}
}
超链接为:
testPathVariable
HTTP有四种表示操作方式的动词:
GET
:获取资源POST
:新建资源PUT
:更新资源DELETE
:删除资源在浏览器form表单中,只支持GET与POST请求,而DELETE、PUT等method并不支持,在Spring3.0添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT与DELETE请求。
REST风格的URL的实例,以CRUD为例:
/order POST:新建一个order
/order/1 PUT:修改id=1的order
/order/1 GET:获取id=1的order
/order/1 DELETE:删除id=1的order
使用HiddenHttpMethodFilter来发送PUT请求和DELETE请求的步骤:
HiddenHttpMethodFilter
HiddenHttpMethodFilter
org.springframework.web.filter.HiddenHttpMethodFilter
HiddenHttpMethodFilter
/*
name="_method"
的隐藏域,值为DELETE或PUT下面我们对这四种请求分别举例子,我们编写了如下的html
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
Test Rest Get
package com.cerr.springmvc.handlers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
private static final String SUCCESS = "success";
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.PUT)
public String testRestPut(@PathVariable("id") Integer id){
System.out.println("testRest PUT:"+id);
return SUCCESS;
}
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.DELETE)
public String testRestDelete(@PathVariable("id") Integer id){
System.out.println("testRest DELETE:"+id);
return SUCCESS;
}
@RequestMapping(value = "/testRest",method = RequestMethod.POST)
public String testRest(){
System.out.println("testRest POST");
return SUCCESS;
}
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.GET)
public String testRest(@PathVariable("id") Integer id){
System.out.println("testRest GET:"+id);
return SUCCESS;
}
}
对于PUT、DELETE、GET请求,参数的传递我们可以使用上面所学的@PathVariable
注解来将占位符的值传递给方法的参数。
SpringMVC通过分析处理方法的签名,将HTTP请求信息绑定到处理方法的响应入参中。
SpringMVC对控制器处理方法签名的限制是很宽松的,几乎可以按喜欢的任何方式对方法进行签名。
必要时可以对方法及方法入参标注相应的注解(@PathVariable、@RequestParam、@RequestHeader
等)、SpringMVC会将HTTP请求的信息绑定到相应的方法入参中,并根据方法的返回值类型作出相应的后续处理。
使用@RequestParam
来映射请求参数,其注解有如下方法:
value
值即为请求参数的参数名request
可以指定该参数是否是必须传的defaultValue
表示请求参数的默认值例子:在jsp文件中通过超链接传入两个参数,在控制器类中接受并打印。web.xml
文件配置如下:
contextConfigLocation
/WEB-INF/applicationContext.xml
org.springframework.web.context.ContextLoaderListener
HiddenHttpMethodFilter
org.springframework.web.filter.HiddenHttpMethodFilter
HiddenHttpMethodFilter
/*
dispatcher
org.springframework.web.servlet.DispatcherServlet
1
dispatcher
/
dispatcher-servlet.xml
配置文件如下:
jsp文件:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
Test testRequestParam
package com.cerr.springmvc.handlers;
import org.springframework.stereotype.Controller;
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.RequestParam;
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
private static final String SUCCESS = "success";
@RequestMapping(value = "/testRequestParam")
public String testRequestParam(@RequestParam(value = "username") String un,
@RequestParam(value = "age",required = false) Integer age){
System.out.println("testRequestParam " + un + " " + age);
return SUCCESS;
}
}
请求头包含了若干个属性,服务器可根据此获知客户端的信息,通过@RequestHeader即可将请求头中的属性值绑定到处理方法的入参中。
package com.cerr.springmvc.handlers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
private static final String SUCCESS = "success";
/***
* 用法同@RequestParam
* 作用:映射请求头
* @param al
* @return
*/
@RequestMapping(value = "/testReuqestHeader")
public String testReuqestHeader(@RequestHeader(value = "Accept-Language") String al){
System.out.println("testReuqestHeader,Accept-Language: "+al);
return SUCCESS;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
Test testReuqestHeader
映射一个Cookie值,属性同@RequestParam
package com.cerr.springmvc.handlers;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
private static final String SUCCESS = "success";
@RequestMapping(value = "/testCookieValue")
public String testCookieValue(@CookieValue("JSESSIONID") String sessionId){
System.out.println("testCookieValue: sessionId:"+sessionId);
return SUCCESS;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
Test testCookieValue
SpringMVC会按请求参数名或POJO属性名进行自动匹配,自动为该对象填充属性值,并且支持级联属性。
如dept.deptId、dept.address.city
等。
我们定义一个User类,里面包含另一个实体类Address:
package com.cerr.springmvc.entities;
public class User {
private String username;
private String password;
private String email;
private int age;
private Address address;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
", age=" + age +
", address=" + address +
'}';
}
}
我们再定义一个实体类Address:
package com.cerr.springmvc.entities;
public class Address {
private String province;
private String city;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Address{" +
"province='" + province + '\'' +
", city='" + city + '\'' +
'}';
}
}
index.jsp文件:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
控制器类的代码:
package com.cerr.springmvc.handlers;
import com.cerr.springmvc.entities.User;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
import org.springframework.stereotype.Controller;
import org.springframework.util.concurrent.SuccessCallback;
import org.springframework.web.bind.annotation.*;
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
private static final String SUCCESS = "success";
@RequestMapping("/testPojo")
public String testPojo(User user){
System.out.println("textPojo:"+user);
return SUCCESS;
}
}
可以使用Servlet元素的API作为目标方法的参数,具体支持以下几种类型:
HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal
Locale InputStream
OutputStream
Reader
Writer
例如:我们将HttpServletRequest和HttpServletResponse作为目标方法的参数
@RequestMapping("/testServletAPI")
public String testServletApi(HttpServletRequest request,
HttpServletResponse response){
System.out.println(request+" "+response);
return SUCCESS;
}