@RequestAttribute注解用法
@RequestAttribute用在方法入参上,作用:从request中取对应的值,至于request中是怎么存在该属性的,方式多种多样,拦截器中预存、ModelAttribute注解预存、请求转发带过来的;
该注解出现自Spring4.3版本
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestAttribute { /** * Alias for {@link #name}. */ @AliasFor("name") String value() default ""; /** * The name of the request attribute to bind to. * <p>The default name is inferred from the method parameter name. */ @AliasFor("value") String name() default ""; /** * Whether the request attribute is required. * <p>Defaults to {@code true}, leading to an exception being thrown if * the attribute is missing. Switch this to {@code false} if you prefer * a {@code null} or Java 8 {@code java.util.Optional} if the attribute * doesn't exist. */ boolean required() default true; }
尝试访问一个request中不存在的值时,@RequestAttribute抛出异常:
@RequestMapping("/demo1") public String demo1(@RequestAttribute String name){ System.out.println(name); return "test"; }
请求request中预存属性的方式:
方式一.ModelAttribute注解
@ModelAttribute public void storeEarly(HttpServletRequest request){ request.setAttribute("name","lvbinbin"); }
方式二.拦截器中request.setAttribute()
public class SimpleInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println(" Simple Interceptor preHandle"); request.setAttribute("name",24); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println(" Simple Interceptor postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println(" Simple Interceptor afterCompletion"); } }
方式三.请求转发,转发过来的请求属性中存在;
@RequestAttribute解析流程
SpringMvc中对于方法入参解析采用HandlerMethodArgumentResolver接口,而@RequestAttribute采用RequestAttributeMethodArgumentResolver解析:
其中name属性默认为 @RequestAttribute中name/value值,如果不存在就去方法入参的名字!
@RequestAttribute属性required默认为true, request.getAttribute获取不到参数就会抛出异常 ServletRequestBindingException ;
required设置为false,即使没有从request中获取到就忽略跳过,赋值为null;