Spring学习笔记_44——@ModelAttribute
Spring学习笔记_45——@ControllerAdvice
Spring学习笔记_46——@InitBinder
@RequestAttribute
文章目录
- @RequestAttribute
- 1. 介绍
- 2. 场景
- 3. 源码
- 4. Demo
- 4.1
- 4.2
- 5. 注意
- 6. 补充
1. 介绍
@RequestAttribute
注解用于将Web请求的属性注入到控制器方法的参数中。这些属性可能是在请求处理过程中的某个阶段,如过滤器或拦截器中设置的。通过该注解,开发者可以方便地访问这些请求属性,而无需手动从HttpServletRequest
对象中获取。
2. 场景
不通过HttpServletRequest
的getAttribute()
方法从请求域中获取数据,从而实现与Servlet API
进行解耦,就可以使用@RequestAttribute
注解实现
@RequestAttribute
注解通常用于以下场景:
- 表单提交:在处理表单提交时,可能需要访问由前端传递或在服务器端设置的请求属性。
- 文件上传:在文件上传场景中,可以结合其他注解(如@RequestParam)一起使用,以访问请求中的文件和其他属性。
- 自定义请求处理:在自定义请求处理逻辑中,可能需要访问请求属性来执行特定的业务逻辑。
3. 源码
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestAttribute {
// String类型的属性,主要用于之情请求作用域中的属性名称
@AliasFor("name")
String value() default "";
// String类型的属性,作用与value属性相同
@AliasFor("value")
String name() default "";
// boolean类型的属性,表示请求作用域中的属性是否必需
// true: 必需
// false: 非必需
// 如果为true,则当前请求域中没有对应的属性,就会抛出异常。
// 默认值为true
boolean required() default true;
}
4. Demo
4.1
// 在拦截器中对请求添加一个属性
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
// 假设我们已经验证了用户身份,并获取到了用户的ID
String userId = "12345";
httpRequest.setAttribute("userId", userId);
chain.doFilter(request, response);
}
}
// 在控制器中,通过@RequestAttribute注解访问拦截器中设定的属性
@Controller
public class UserController {
@GetMapping("/user")
public String getUser(@RequestAttribute("userId") String userId, Model model) {
// 使用 userId 进行业务逻辑处理
User user = userService.getUserById(userId);
model.addAttribute("user", user);
return "userProfile";
}
}
4.2
// 从请求中获取名为 preferences 的属性,这是一个可能不存在的属性。
// 如果它不存在,我们将不会抛出异常,而是使用一个空的 HashMap 作为默认值
@Controller
public class PreferenceController {
@GetMapping("/preferences")
public String getPreferences(
@RequestAttribute("userId") String userId,
@RequestAttribute(value = "preferences", required = false) Map<String, String> preferences,
Model model) {
if (preferences != null) {
model.addAttribute("preferences", preferences);
} else {
model.addAttribute("preferences", new HashMap<>());
}
return "userPreferences";
}
}
5. 注意
属性来源:@RequestAttribute
注解访问的请求属性可能来自过滤器、拦截器或其他请求处理组件。因此,在使用该注解时,需要确保请求属性在请求处理过程中已被正确设置。
异常处理:如果@RequestAttribute
注解的required
属性设置为true且请求中没有找到指定的属性,则会抛出一个异常。因此,在使用该注解时,需要考虑异常处理逻辑。
类型转换:Spring MVC会自动将请求属性转换为方法参数所需的类型。如果转换失败,则会抛出一个类型转换异常。因此,在使用该注解时,需要确保请求属性的类型与方法参数的类型兼容
6. 补充
在Web开发中,“请求属性”(Request Attributes)是指与HTTP请求相关联的一组键值对数据。这些数据可以在请求的处理过程中被设置、访问和修改。请求属性通常用于在请求的不同阶段之间传递信息,例如在过滤器(Filters)、拦截器(Interceptors)、控制器(Controllers)以及视图(Views)之间。
请求属性与请求参数(Request Parameters)和请求头(Request Headers)不同。请求参数通常是通过URL查询字符串或表单数据传递的,而请求头则包含了HTTP请求的各种元数据,如内容类型、用户代理等。相比之下,请求属性是在服务器端设置的,并且对于客户端来说是不可见的。
在Spring MVC框架中,请求属性可以通过多种方式设置,包括但不限于:
- 过滤器(Filters):过滤器可以拦截HTTP请求,并在请求到达控制器之前设置请求属性。
- 拦截器(Interceptors):拦截器是Spring MVC提供的一种机制,允许在控制器方法执行之前或之后执行特定的逻辑。拦截器可以设置或修改请求属性。
- 控制器(Controllers):在控制器方法中,可以通过
HttpServletRequest
对象的setAttribute
方法设置请求属性。然而,更常见的是使用Spring MVC提供的注解(如@ModelAttribute
、@SessionAttributes
以及@RequestAttribute
)来访问和设置属性。 - 其他请求处理组件:在请求处理流程中的其他组件(如视图解析器、视图渲染器等)也可能设置或访问请求属性。