Spring MVC 架构图
一:@RequestMapping 映射请求
如何将请求映射到对应的控制器方法中是 Spring MVC 框架的重要任务之一,这项任务由@ RequestMapping 承担。
在控制器的类定义及方法定义处都可以标注@ RequestMapping ,类定义处的@ RequestMapping 提供初步的请求映射信息,方法定义处的@ RequestMapping 提供进一步的细分映射信息。 DispatcherServlet 截获请求后,就通过控制器上@ RequestMapping 提供的映射信息确定请求所对应的处理方法。
1.通过请求URL 进行映射
@RestController
@RequestMapping("/login")
public class LoginController {
@RequestMapping("/index")
public ModelAndView index(){
ModelAndView view = new ModelAndView();
view.setViewName("/login");
view.addObject("helloStr", "test hello world");
return view;
}
//访问路径 IP:端口/项目服务名/login/index 既可访问
@RequestMapping 不仅支持标准的URL 还支持Ant风格的和带{xxx} 占位符的URL
/user/*/createUser : 匹配 /user/aa/createUser、/user/bb/createUser 等
/user/**/createUser : 匹配 /user/createUser、/user/aa/bb/createUser 等
/user/createUser?? : 匹配 /user/createUseraa、/user/createUserbb 等
/user/{
userId} : 匹配 /user/123 、 /user/456等
/user/**/{
userId} : 匹配 /user/aa/123、/user/aa/bb/123等
实战中没怎么用到,都是具体的明确的URL
@PathVariable(“xxx”) 可以将URL 中的占位符绑定到操作方法中
@RequestMapping("/login/{roleID}")
public class LoginController {
@RequestMapping("/{uerID}")
public ModelAndView test(@PathVariable("roleID") String roleID,@PathVariable("userID") String userID){
ModelAndView view = new ModelAndView();
view.setViewName("/hello");
view.addObject("roleID is", roleID);
view.addObject("userID is", userID);
return view;
}
}
2.通过请求参数,请求方法或请求头进行映射
这是截取的chrome 访问的一段请求报文,上面报文头的参数都是可以获取的,用来当作访问条件
//使用请求方法和请求参数映射请求
@RequestMapping(value="/test1",method=RequestMethod.GET,params="userID")
public String test1(@RequestParam("userID") String userID){
return "SUCCESS";
}
//使用报文头映射请求
@RequestMapping(value="/test1",headers="context-type/*")
public String test1(@RequestParam("userID") String userID){
return "SUCCESS";
}
@RequestMapping 的
value、method、params、headers 分别是请求URL,请求方法,请求参数,报文头的映射条件,联合使用可使请求映射更精确
其中params 表达式和headers 含义一样
- ”param1“ :请求须包含名为param1的请求参数
- ”!param1“ :请求不能包含名为param1的请求参数
- ”param1 != value1“ :请求须包含名为param1的请求参数,但其值不能为value1
- {”param1=value1“,”param2“} : 请求须包含名为param1 和 param2的请求参数,且param1的参数值必须为value1
二:请求处理方法签名
下面是4种典型的处理方法

//1 请求参数按名称匹配的方式绑定到方法入参中,方法返回字符串代表逻辑视图名
@RequestMapping("/handle1")
public String handle1(@RequestParam("userName") String userName) {
return "success";
}
//2.将Cookie值及报文头属性绑定到入参中,方法返回ModelAndView
@RequestMapping(value="/handle2")
public ModelAndView handle2(@CookieValue("JSESSIONID") String sessionId ,
@RequestHeader("Accept-Language") String acceptLanguage){
ModelAndView view = new ModelAndView();
System.out.println("mv hello -----------------");
view.setViewName("/hello");
view.addObject("helloStr", "test hello world");
return view;
}
//3.请求参数按名称匹配的方式绑定到userInfo 的属性中,方法返回字符串代表逻辑视图名
@RequestMapping("/handle3")
public String handle3(UserInfo userInfo) {
return "success";
}
//4.直接将Http请求对象传递给处理方法,方法返回字符串代表逻辑视图名
@RequestMapping("/handle4")
public String handle4(HttpServletRequest request) {
return "success";
}
请求方法签名的详解:
1.@RequestParam 有以下参数:
- value 参数名
- required 是否必需,默认true 表示请求参数中必须包含对应的参数名,否则抛出异常
- defaultValue 默认参数名,在设置该参数时,自动将required 设为false。不推荐使用
2.@CookieValue
和@RequestParam 有一样的参数,其中value 属性 表示 Cookie 的名称
3.@RequestHeader
也和@RequestParam 有一样的参数:通过value 可获取若干请求报文头的属性,报文头直接浏览器F12 就可以查看
4.以实体类为入参参数
如上文的UserInfo ,参数名只需和实体类的属性名一直即可
也可以多种组合
例如:
/handle5?userInfo.userName&roleInfo.roleId
5.使用ServletAPI 对象作为入参
//5.同时使用HttpServletRequest和 HttpServletResponse 入参
@RequestMapping("/handle5")
public void handle5(HttpServletRequest request,HttpServletResponse response) {
String username = WebUtils.findParameterValue(request, "userName");
response.addCookie(new Cookie("userName", username));
}
//6.使用HttpSession 入参
@RequestMapping("/handle6")
public String handle6(HttpSession httpSession) {
httpSession.setAttribute("sessionId", "123");
return "success";
}
(1).在使用ServletAPI 的类入参时,SpringMVC 会自动将Web 层对应的Servlet 对象传递给处理方法的入参。参数位置顺序也没有要求。
(2).注意使用HttpServletResponse 返回响应,则处理方法的返回值设置成void即可
(3).springmvc 在其他定义的ServletAPI的接口如 WebRequest 和NativeWebRequest 这些也可以作为入参,通过这些代理类可访问请求对象的任何信息
6.使用 I/O 对象作为入参
//7.IO 作为入参
@RequestMapping("/handle7")
public void handle7(OutputStream outputStream) throws IOException {
Resource res = new ClassPathResource("/image.jpg");//读取类路径下的图片文件
FileCopyUtils.copy(res.getInputStream(), outputStream);//将图片写入输出流
}
Servlet 的 ServletRequest 拥有 getInputStream() 和 getReader() 方法,可以通过它们读取请求的信息。相应的,Servlet 的 ServletResponse 拥有getOutputStream() 和 getWriter()方法,可以通过它们输出响应信息。
java.io.InputStream / java.io.Reader 和java.io.tOutputStream / java.io.Writer 可作为方法的入参,这些参数继续向下传递给控制器的处理方法
未完待续…
学习笔记 摘自 精通Spring 4.x 企业应用开发实战