• @RequestMapping
  • 解释:
  • 映射url目录,属性可以请求参数、请求方法、响应类型等,可以有多个映射值
  • 加在方法上时,方法返回String类型,代表视图名,会被视图解析器解析,从而跳转到该视图
  • 加在类上时,将特定的请求映射到当前控制器上,然后根据方法上的注解细化映射
  • 方法形参可以是String类型、类类型,会根据参数名将url中的参数自动注入类类型的形参中,简化参数的获取方式
  • 属性:
  • path/value:访问路径,字符串数组
  • name:映射器名称
  • method:http请求方法(格式:method = RequestMethod.POST)
  • params:访问路径中必须带有的参数,字符串数组
  • headers:请求头字段,字符串数组
  • consumes:请求数据的类型(即contentType)
  • produces:返回数据的类型(即accept)
  • @GetMapping
  • 等同@RequestMapping(method = RequestMethod.GET)
  • 还有@PostMapping、@PutMapping等
  • @ResponseBody
  • 配合@RequestMapping/@GetMapping…使用,控制器方法只能返回响应资源,而不能返回视图名进行页面转发
  • @PathVariable
  • 映射@RequestMapping中的占位符,将url的某部分当做参数处理,简化了原来的请求参数写法 …/login?xx=xx
@RequestMapping("login/{param}")
public String login(@PathVariable("param") String name, String pwd){...}

// ../login/smith?pwd=abc

// @PathVariable可以不写数值
@RequestMapping("login/{name}")
public String login(@PathVariable String name, String pwd){...}
  • @RequestParam
  • 映射及限定请求参数
  • value/name属性:映射url参数名与方法形参名
  • required属性:url中是否必须包含该参数,如果true就相当于设置了@RequestMapping中的params,默认true
  • defaultValue属性:默认值
@RequestMapping("login")
public String login(String name, @RequestParam(value = "password", required = false) String pwd) {..}

// ../login?name=smith&password=abc
  • @RestController
  • 支持Rest请求风格,相当于@Controller+@ResponseBody
  • 当前页面只能返回响应资源,无法返回视图名进行跳转页面(只能使用ModelAndView跳转)
  • 源码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}
  • @SessionAttributes
  • 作用:
  • model在添加了数据后,会将数据存入request中,转发页面后可以在request域中获取到
  • 如果数据是@SessionAttributes中指定的对象名/类型,则会再将数据存入session中
  • 局限:
  • 只能定义在类上,用于在多个请求之间传递参数,类似于Session的Attribute,但不完全一样
  • 只用于暂时的传递,保存时间比HttpSession的Attribute要短
  • 生效要求:
  1. 首先在注解中设置了需要保存的数据的名称或类型
  2. 其次使用Model/ModelMap/ModelAndView保存了数据对象,三者效果一样
  • 清除数据:
  • SessionStatus.setComplete()清除所有数据,但不会清除HttpSession设置的数据
  • 在方法形参中如果有HttpSession对象,清除数据后,当前HttpSession对象还是保留有清除前数据的,只有刷新后才无法获取到
  • 示例:
// 匹配model中名为“online”的对象和类型为User的对象,并添加到session中
@SessionAttributes(value = "online", types = User.class)
@Controller
public class UserController {
    // ...
}
  • @SessionAttribute
  • 只能定义在方法形参上,从session中获取指定的对象,并注入形参。如果没有,则报400
  • 注意:
  • 区分@SessionAttributes,两者不是一个注解
  • 要将@SessionAttributes设置的对象值注入形参,必须先调用一次该对象值,否则报错显示session没有该对象
  • 示例:
@RequestMapping("home")
@ResponseBody
public String home(@SessionAttribute("user") User user) {
	// 获取session中名为“user”的数据对象,注入形参。如果是@SessionAttributes添加的,必须先调用过才能获取到
	return "user: " + user;
}
  • @ModelAttribute
  1. 添加到方法上,在每个控制器方法执行前被调用的方法:
  • 如果没有返回值,通常用于参数的初始化
  • 如果有具体返回值,就会将该返回值添加到model中,同时可以在注解属性value中设置其名称
// 1.没有返回值,做参数的初始化
 @ModelAttribute
 public void initMethod(Model model, User user, Result result) {
     // 如果按照上面@SessionAttributes示例代码所述,"user"符合要求,会存入session中,“result”不符合,只会存入request中
     user.setName("smith");
     model.addAttribute("user", user);
     
     result.setMsg("successful");
     model.addAttribute("result", result);
 }
 
 // 2.有返回值,会将返回值添加到model中,名字就是“user”,如果是@SessionAttributes指定的对象,还会同步到session中
 @ModelAttribute("user")
 public User initMethod(User user) {
     user.setName("smith");
     return user;
 }
  1. 添加到方法形参上,从model中获取指定对象,注入到方法形参中
@RequestMapping("home2")
  @ResponseBody
  public String home2(@ModelAttribute("result") Result result) {
  
  	return "result: "+result;
  }
  • @CookieValue
  • 用在方法形参上,获取当前服务器中的cookie值注入形参中
@RequestMapping("cookie")
@ResponseBody
public String getCookie(@CookieValue(required = false, name = "JSESSIONID") String sessionId) {
	// ...
}
  • @RequestHeader
  • 用在方法形参上,获取请求头属性值,并注入形参
@RequestMapping("header")
@ResponseBody
public String getHeadaer(@RequestHeader("User-Agent") String userAgent) {
    // ...
}
  • @InitBinder
  • 为控制器注册一个绑定器初始化方法,在每个映射方法执行前执行,类似@ModelAttribute方法
  • 属性value是用来限定对哪些映射器方法起作用,默认当前类所有
<form action="index" method="get">
    <input type="date" name="date"><br/>
    <input type="submit" value="提交">
</form>
@InitBinder
protected void initBinder(WebDataBinder binder) {
    System.out.println("initBinder...");

    // WebDataBinder:表单到方法的数据绑定,进行数据转换
    binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
}

// 会返回日期的毫秒数,如果没有@InitBinder方法中的转换,日期接收会报错
@RequestMapping("index")
@ResponseBody
public Date index(Date date) {
    return date;
}
  • @ExceptionHandler
  • 拦截指定异常,在方法内进行处理
// 测试下面配置的@ExceptionHandler是否起作用
@RequestMapping("intercept")
@ResponseBody
public void intercept() {
    Integer[] integers = {1, 1};
    for (int i = 0; i <= 2; i++) {
        // 数组下标越界:java.lang.ArrayIndexOutOfBoundsException
        System.out.println(integers[i]);
    }
}

// 拦截上面intercept方法中的数组下标越界异常,然后跳转页面
@ExceptionHandler(ArrayIndexOutOfBoundsException.class)
public String exceptionHandler() {
    System.out.println("error: java.lang.ArrayIndexOutOfBoundsException");
    return "exception";
}
  • 处理异常方法与出现异常的方法只能在一个控制器内,为了全局起效,可将@ExceptionHandler方法放在@ControllerAdvice控制器中
  • @ControllerAdvice
  • 增强的@Controller,实现三个功能:
  1. 全局异常处理:与@ExceptionHandler搭配使用
  2. 全局数据绑定:
  3. 全局数据预处理
  • 注入Servlet内置对象
  • 可以在方法形参中直接注入HttpServletRequest、HttpSession等
  • HttpSession对象可以与上面的@SessionAttributes搭配使用
  • 示例:
@RequestMapping("servlet")
@ResponseBody
public void getServlet(
        // 注入请求对象
        HttpServletRequest request,
        // 注入响应对象
        HttpServletResponse response,
        // 注入会话对象
        HttpSession session,
        // 注入请求对象的输入、响应对象的输出
        InputStream is, OutputStream os) {
    // ...
}