spring MVC基础注解汇总

目录

一、Spring MVC 请求处理的整体流程

从核心组件方面分析流程

从不同类型注解的使用方面分析流程 

 二、核心控制器注解

1. @Controller 注解

2. @RestController 注解

@Controller vs @RestController 详细对比

@Controller 和 @RestController 的组合使用

二、请求映射注解 

1. @RequestMapping

2. @GetMapping

3. @PostMapping

4. @PutMapping

5. @DeleteMapping

6. @PatchMapping

7. 请求映射注解的总结

三、自动绑定参数

1. 自动绑定 URL 查询参数

2. 自动绑定表单字段

3.自动绑定对象

4. 自动绑定的限制

 四、请求参数绑定相关注解 

1. @PathVariable

2. @RequestParam 

3. @RequestBody

4. @ModelAttribute

5. @RequestHeader

6. @CookieValue

7.@RequestPart 注解

8. 请求参数绑定注解的总结

五、响应相关注解 

1. @ResponseBody

2. @ResponseStatus

3. @RestController

4. @ExceptionHandler

5. @ResponseBody 与视图解析器的区别

六、会话和请求作用域注解 

1. @RequestScope

2. @SessionScope

3. 请求作用域与会话作用域的区别

七、安全和认证相关注解 

1. @Secured

2. @PreAuthorize

3. @PostAuthorize

4. @RolesAllowed

5. @AuthenticationPrincipal

6.安全和认证相关注解总结

八、拦截器相关注解 

1. @Component

2. @Configuration

3. @Order

九、跨域相关注解 

1. @CrossOrigin

2. @Configuration 配置跨域

3. @CrossOrigin 与全局配置的区别

十、总结 


一、Spring MVC 请求处理的整体流程

从核心组件方面分析流程

  1. 请求进入 DispatcherServlet:客户端的 HTTP 请求被 DispatcherServlet 接收,它是请求的统一入口。
  2. HandlerMapping 查找 ControllerDispatcherServlet 将请求转交给 HandlerMapping,后者根据 URL 选择合适的 Controller
  3. Interceptor 拦截请求:在调用控制器方法之前,Interceptor 进行前置处理,如权限验证。
  4. Controller 处理请求Controller 执行业务逻辑,处理请求,返回 ModelAndView,其中包含模型数据和视图名称。
  5. ViewResolver 解析视图DispatcherServlet 使用 ViewResolver 将逻辑视图名称转换为物理视图(如 JSP 页面)。
  6. 视图渲染和响应:视图将模型数据渲染为最终的页面,DispatcherServlet 将生成的响应返回给客户端。

从不同类型注解的使用方面分析流程 

1.控制器定义:当用户发出请求时,Spring 通过 @Controller@RestController 识别哪个类是处理请求的控制器。这一步,Spring 知道哪个类应该接收请求并处理逻辑。

2.请求映射:Spring 查找控制器类中的方法,并根据 @RequestMapping@GetMapping@PostMapping 等注解,将请求的 URL 和 HTTP 方法映射到具体的控制器方法上。比如,GET 请求会被映射到带有 @GetMapping 注解的方法。

3.跨域检查:如果请求是跨域的,Spring 会检查 @CrossOrigin 注解,决定是否允许跨域请求。这一步确保跨域请求可以安全地被控制器方法处理。

4.拦截器预处理:在请求进入控制器方法前,Spring 可能通过拦截器的 preHandle 方法进行预处理,比如记录日志或执行权限验证。拦截器可以在 @Configuration 配置类中注册。这一步会先检查请求是否符合预处理逻辑,比如用户是否已登录或是否有访问权限。

5.安全验证:Spring Security 会使用 @PreAuthorize@Secured 注解来检查当前用户是否有权限执行该方法。如果用户没有权限,Spring 会拒绝请求。这一阶段确保用户只能访问他们有权限访问的资源或执行的操作。

6.请求参数绑定:Spring 通过 @RequestParam@PathVariable@RequestBody、或 @ModelAttribute 等注解,将请求中的 URL 参数、表单数据或 JSON 数据绑定到控制器方法的参数中。例如,表单中的数据会被自动绑定到 Java 对象,供控制器方法使用。

7.控制器方法执行:完成参数绑定后,Spring 执行映射的控制器方法来处理业务逻辑。

8.拦截器后处理:在控制器方法执行完后,拦截器的 postHandle 方法可能会对响应数据进行修改或记录处理信息。例如,可以在这一步修改响应的模型数据。

9.响应处理:控制器方法的返回值会经过 @ResponseBody 注解处理,将 Java 对象直接转换为 JSON 或 XML 返回给客户端。如果使用了 @RestController,Spring 会自动将方法的返回值作为 HTTP 响应体。

10.拦截器完成处理:在整个请求完成后,拦截器的 afterCompletion 方法执行,用于清理资源或记录完成状态。

11.作用域管理:如果使用了 @RequestScope@SessionScope,Spring 会在请求处理或会话期间管理这些 Bean 的生命周期。请求结束或会话失效时,Bean 实例会被销毁。

 二、核心控制器注解

1. @Controller 注解

作用

@Controller 是 Spring MVC 中的核心注解之一,主要用于标识 一个类为控制器,用于处理 Web 请求。使用 @Controller 的类通常包含处理客户端请求的业务逻辑,并返回一个视图名称。

特点
  • @Controller 注解的类是 Spring MVC 中的 处理器类,它与前端控制器 DispatcherServlet 配合使用。
  • 通过方法级别的 @RequestMapping@GetMapping@PostMapping 等注解,可以将请求 URL 映射到具体的控制器方法上。
  • @Controller 默认用于返回 视图名称,由 Spring MVC 的 视图解析器ViewResolver将逻辑视图名称解析为具体的视图模板(如 JSP、Thymeleaf)。
使用场景
  • 适用于传统的 MVC 模式,其中控制器方法会返回视图名称,并渲染前端页面。
  • 用于需要返回网页、HTML、JSP 或其他视图模板的场景。
示例代码
@Controller
public class UserController {

    // 处理 GET 请求,返回视图名称 "userDetails"
    @GetMapping("/users/{id}")
    public String getUserDetails(@PathVariable Long id, Model model) {
        // 假设我们通过 id 获取用户对象,并添加到模型中
        User user = userService.findUserById(id);
        model.addAttribute("user", user);
        // 返回逻辑视图名 "userDetails",Spring MVC 会根据视图解析器解析该视图
        return "userDetails";
    }
}

详细解释

(1)@Controller:定义 UserController 类为控制器类。

(2)@GetMapping("/users/{id}"):将 URL /users/{id} 映射到 getUserDetails() 方法。该方法处理用户请求,获取用户信息。

(3)Model 对象:用于将数据传递给视图层。控制器方法处理完后,将用户数据放入 Model 对象中,供视图显示。

(4)返回视图名称return "userDetails" 返回逻辑视图名称,视图解析器会将其解析为具体的 JSP 或 Thymeleaf 模板文件(如 WEB-INF/views/userDetails.jsp)。

2. @RestController 注解

作用

@RestController 是 Spring MVC 提供的另一个核心注解,它是 @Controller @ResponseBody 的组合注解,主要用于构建 RESTful API。与 @Controller 不同,@RestController 返回的数据不会通过视图解析器解析,而是直接写入 HTTP 响应体。

特点
  • @RestController 注解的类被视为 RESTful 控制器,专用于返回 JSON、XML 或其他格式的数据。
  • 所有控制器方法返回的数据会被自动序列化为 JSON 或 XML 格式(取决于请求头 Content-Type),无需手动使用 @ResponseBody
  • 适用于构建 RESTful API,处理客户端请求并返回结构化数据(如 JSON)。
使用场景
  • 适用于构建 API,返回 JSON、XML 等数据格式,而不是视图页面。
  • 用于需要开发 RESTful Web 服务 的场景,特别是客户端请求需要处理数据,而不需要返回完整的网页时。
示例代码
@RestController
@RequestMapping("/api/users")
public class UserRestController {

    // 处理 GET 请求,返回用户信息(JSON)
    @GetMapping("/{id}")
    public User getUserDetails(@PathVariable Long id) {
        // 假设通过 id 获取用户对象
        return userService.findUserById(id);
    }

    // 处理 POST 请求,创建新用户,并返回创建的用户信息
    @PostMapping
    public User createUser(@RequestBody User user) {
        // 创建新用户
        return userService.saveUser(user);
    }
}

详细解释

  • @RestController:定义 UserRestController 类为 RESTful 控制器。所有返回的数据会自动序列化为 JSON 或 XML 格式。
  • @RequestMapping("/api/users"):将控制器的所有请求路径前缀设为 /api/users
  • @GetMapping("/{id}"):将 URL /api/users/{id} 映射到 getUserDetails() 方法。该方法返回的是 User 对象,Spring 会将其序列化为 JSON 格式,并写入响应体。
  • @PostMapping@RequestBodycreateUser() 方法处理 POST 请求,@RequestBody 注解会自动将请求体中的 JSON 数据反序列化为 User 对象,并返回保存后的用户信息。
返回示例

客户端发送 GET /api/users/123 请求时,服务器响应:

{
  "id": 123,
  "name": "John Doe",
  "email": "john.doe@example.com"
}

@Controller vs @RestController 详细对比

特性@Controller@RestController
主要用途返回视图页面(JSP、Thymeleaf 等)返回 JSON 或 XML 数据,构建 RESTful API
返回值返回逻辑视图名称返回数据,通常为对象或列表,自动转换为 JSON
视图解析使用视图解析器(ViewResolver)解析视图不使用视图解析器,直接返回数据
@ResponseBody 关系需要与 @ResponseBody 一起使用内置了 @ResponseBody,无需单独使用
典型使用场景传统 MVC 应用,需要渲染页面的场景构建 RESTful API,返回数据而不是视图页面

@Controller@RestController 的组合使用

在实际项目中,通常我们需要结合使用 @Controller@RestController@Controller 用于处理需要返回视图的请求,而 @RestController 用于处理 API 请求。这种组合方式可以让一个项目同时支持前端页面渲染和 API 服务。

  • @Controller:主要用于处理返回视图页面的请求,适合传统的 MVC 应用。它与视图解析器一起工作,返回 JSP、Thymeleaf 等页面。
  • @RestController:主要用于返回数据而不是视图页面,适合构建 RESTful API。它自动将返回值转换为 JSON 或 XML,直接输出到 HTTP 响应体中。

二、请求映射注解 

1. @RequestMapping

作用

@RequestMapping 是最基本的请求映射注解,可以应用在类或者方法上,用于映射请求的 URL 和处理器方法。它不仅可以指定 URL,还可以指定 HTTP 方法、请求参数等多种匹配条件。

特点
  • 灵活性:可以同时应用在控制器类级别和方法级别。
  • 支持多种配置:除了映射 URL,还可以设置请求方法、请求参数、请求头等条件。
  • 用法:常用于处理多个 HTTP 方法的请求,比如 GET 和 POST。
示例代码
@Controller
@RequestMapping("/users")
public class UserController {

    // 处理 GET 请求,获取用户列表
    @RequestMapping(method = RequestMethod.GET)
    public String getUsers(Model model) {
        List<User> users = userService.findAll();
        model.addAttribute("users", users);
        return "userList";
    }
}

详细解释

  • @RequestMapping("/users"):将控制器的请求路径前缀设为 /users。类级别的注解意味着所有方法的 URL 都会以 /users 开头。
  • method = RequestMethod.GET:将请求方法限定为 GET,仅处理 GET 请求。
  • 返回值:返回视图名称 userList,由视图解析器处理。

2. @GetMapping

作用

@GetMapping@RequestMapping 的简化版本,专门用于处理 GET 请求。GET 请求通常用于获取资源或页面。

特点
  • 专注于 GET 请求:相比于 @RequestMapping,它只处理 GET 请求,语法简洁。
  • 常用场景:用于从服务器获取资源(如数据、页面)而不改变服务器状态。
示例代码
@GetMapping("/users/{id}")
public String getUser(@PathVariable Long id, Model model) {
    User user = userService.findUserById(id);
    model.addAttribute("user", user);
    return "userDetails";
}

详细解释

  • @GetMapping("/users/{id}"):映射 GET 请求到 getUser() 方法,URL 中的 {id} 是路径变量,绑定到方法参数 id
  • @PathVariable:用于从 URL 中获取动态路径部分(例如用户 ID)。
  • 返回值:返回视图名称 userDetails,视图解析器处理后展示用户详情页面。

3. @PostMapping

作用

@PostMapping 是专门用于处理 POST 请求的注解,POST 请求通常用于提交表单数据或者创建新的资源。

特点
  • 专注于 POST 请求:简化了处理 POST 请求的配置。
  • 常用场景:用于服务器端资源的创建或数据提交操作。
示例代码
@PostMapping("/users")
public String createUser(@RequestBody User user, Model model) {
    userService.saveUser(user);
    model.addAttribute("user", user);
    return "userCreated";
}

详细解释

  • @PostMapping("/users"):映射 POST 请求到 createUser() 方法,处理新用户的创建。
  • @RequestBody:从请求体中接收 JSON 数据,并将其转换为 User 对象。
  • 返回值:返回视图名称 userCreated,视图解析器处理后展示创建成功页面。

4. @PutMapping

作用

@PutMapping 是专门用于处理 PUT 请求的注解,PUT 请求通常用于更新现有资源。

特点
  • 专注于 PUT 请求:与 POST 类似,但 PUT 用于更新现有资源。
  • 常用场景:当你需要更新服务器上现有的数据时,通常使用 PUT 请求。
示例代码
@PutMapping("/users/{id}")
public String updateUser(@PathVariable Long id, @RequestBody User user) {
    userService.updateUser(id, user);
    return "userUpdated";
}

详细解释

  • @PutMapping("/users/{id}"):映射 PUT 请求到 updateUser() 方法,用于更新用户信息。
  • @RequestBody:从请求体中接收 JSON 数据,并将其转换为 User 对象。
  • @PathVariable:从 URL 中获取用户 ID,用于更新指定用户的信息。

5. @DeleteMapping

作用

@DeleteMapping 是专门用于处理 DELETE 请求的注解,DELETE 请求通常用于删除资源。

特点
  • 专注于 DELETE 请求:用于删除服务器端的资源。
  • 常用场景:当你需要从服务器删除某个资源时,使用 DELETE 请求。
示例代码
@DeleteMapping("/users/{id}")
public String deleteUser(@PathVariable Long id) {
    userService.deleteUser(id);
    return "userDeleted";
}

详细解释

  • @DeleteMapping("/users/{id}"):映射 DELETE 请求到 deleteUser() 方法,用于删除指定的用户。
  • @PathVariable:从 URL 中获取用户 ID,指定删除哪个用户。
  • 返回值:返回视图名称 userDeleted,视图解析器处理后展示删除成功页面。

6. @PatchMapping

作用

@PatchMapping 是专门用于处理 PATCH 请求的注解,PATCH 请求通常用于部分更新资源。

特点
  • 专注于 PATCH 请求:与 PUT 相似,但用于部分更新,而不是全量更新。
  • 常用场景:当你只需要更新资源的一部分时,可以使用 PATCH 请求。
示例代码
@PatchMapping("/users/{id}")
public String patchUser(@PathVariable Long id, @RequestBody Map<String, Object> updates) {
    userService.patchUser(id, updates);
    return "userPatched";
}

详细解释

  • @PatchMapping("/users/{id}"):映射 PATCH 请求到 patchUser() 方法,用于部分更新用户信息。
  • @RequestBody:接收部分更新数据,并以 Map 的形式传递。
  • 返回值:返回视图名称 userPatched,视图解析器处理后展示更新成功页面。

7. 请求映射注解的总结

注解用途HTTP 方法
@RequestMapping映射任意请求方法(GET、POST、PUT、DELETE 等)任意
@GetMapping处理 GET 请求,用于获取资源GET
@PostMapping处理 POST 请求,用于创建资源或提交数据POST
@PutMapping处理 PUT 请求,用于更新资源PUT
@DeleteMapping处理 DELETE 请求,用于删除资源DELETE
@PatchMapping处理 PATCH 请求,用于部分更新资源PATCH

三、自动绑定参数

在某些情况下,Spring MVC 可以通过参数名称与 URL 查询参数表单字段名称 的匹配,自动绑定参数到控制器方法的参数上 而不需要显式地使用注解。这种情况下,参数名称与请求中的字段名称一致时,Spring MVC 会自动完成数据绑定。

1. 自动绑定 URL 查询参数

如果 URL 查询参数的名称与控制器方法的参数名称一致,Spring MVC 可以自动将查询参数绑定到方法的参数上,而无需使用 @RequestParam 注解。

示例
@GetMapping("/search")
public String search(String query, int page, Model model) {
    // Spring MVC 会自动将 URL 中的 query 和 page 绑定到对应的参数上
    model.addAttribute("query", query);
    model.addAttribute("page", page);
    return "searchResults";
}
示例请求
GET /search?query=springmvc&page=2
  • 在这个例子中,Spring 会自动将 querypage 的值从 URL 查询参数中提取出来,并绑定到方法的 querypage 参数上。无需显式使用 @RequestParam 注解。

2. 自动绑定表单字段

POST 请求 中,如果表单字段的名称和控制器方法的参数名称一致,Spring 也可以自动将表单字段的数据绑定到方法参数上,而不需要显式地使用 @RequestParam

示例
@PostMapping("/submitForm")
public String handleForm(String name, int age, Model model) {
    // 表单字段 name 和 age 会自动绑定到对应的参数上
    model.addAttribute("name", name);
    model.addAttribute("age", age);
    return "formSuccess";
}
示例表单
<form action="/submitForm" method="post">
    <input type="text" name="name" />
    <input type="number" name="age" />
    <button type="submit">Submit</button>
</form>
  • 表单提交后,nameage 字段的数据将自动绑定到控制器方法的 nameage 参数上,无需显式使用 @RequestParam 注解。

这种机制通常依赖于对象的字段名称与请求参数的名称匹配,并且可以通过对象的 gettersetter 方法来自动绑定数据。

这种方式主要使用的是 @ModelAttribute 注解或者不加注解的对象参数。

3.自动绑定对象

Spring MVC 可以自动将 表单数据查询参数 映射到一个 Java 对象,前提是请求中的参数名称与对象的属性名称一致。Spring 会根据参数的名称,自动调用对象的 setter 方法进行属性赋值。

(1)自动绑定对象 (表单提交)

假设我们有一个包含多个字段的表单,Spring MVC 可以自动将表单数据绑定到一个 Java 对象的属性中。

public class User {
    private String name;
    private int age;
    // getters and setters
}
控制器方法
@PostMapping("/register")
public String registerUser(User user, Model model) {
    // Spring MVC 自动将表单字段绑定到 User 对象的属性中
    model.addAttribute("user", user);
    return "registrationSuccess";
}
HTML 表单
<form action="/register" method="post">
    <input type="text" name="name" />
    <input type="number" name="age" />
    <button type="submit">Register</button>
</form>

详细解释

  • User:包含 nameage 属性,并且具有对应的 getter 和 setter 方法。
  • Spring MVC 绑定机制:在表单提交时,Spring 会将表单中 nameage 字段的值绑定到 User 对象的 nameage 属性上,使用 setter 方法自动进行数据赋值。

示例请求

POST /register
name=John&age=25
  • nameage 会自动绑定到 User 对象的 nameage 属性上。

(2)自动绑定对象 (查询参数)

类似地,Spring MVC 也支持从 URL 查询参数 直接绑定到 Java 对象的属性中。

控制器方法
@GetMapping("/userSearch")
public String searchUser(User user, Model model) {
    // Spring MVC 自动将查询参数绑定到 User 对象的属性中
    model.addAttribute("user", user);
    return "userDetails";
}
示例 URL
GET /userSearch?name=John&age=25
  • Spring 会自动将查询参数 name=Johnage=25 绑定到 User 对象的 nameage 属性上。

详细解释

  • URL 查询参数:URL 中的 ?name=John&age=25 会被自动解析,并且绑定到 User 对象的对应属性中。
  • 对象绑定机制:Spring 通过反射机制和对象的 setter 方法来实现这种参数到对象属性的自动绑定。

4. 自动绑定的限制

虽然 Spring MVC 能够自动完成参数绑定,但在某些复杂场景下,仍然建议使用注解来明确指定绑定行为。以下是几种情况,你可能仍然需要使用注解:

  • 自定义参数名称:如果 URL 查询参数或表单字段的名称与方法参数名称不一致,你需要使用 @RequestParam 来指定参数名称。

    @GetMapping("/search")
    public String search(@RequestParam("q") String query) {
        // 如果 URL 查询参数是 `q`,而方法参数是 `query`,则必须使用 @RequestParam 指定绑定
    }
    
  • 可选参数或默认值:当某些参数是可选的或者你希望提供默认值时,使用 @RequestParam 注解更灵活。

    @GetMapping("/search")
    public String search(@RequestParam(defaultValue = "spring") String query) {
        // 如果没有提供 query 参数,则使用默认值 "spring"
    }
    
  • 非简单类型:当你需要绑定复杂的对象或列表时,通常需要使用其他注解(如 @ModelAttribute@RequestBody),而不是依赖自动绑定。

  • 自动绑定:Spring MVC 能够根据 参数名称和 URL 查询参数/表单字段名称 自动完成数据绑定。如果名称一致,无需显式使用注解。
  • 适合场景:这种自动绑定方式适合简单的请求参数和表单字段处理,尤其是名称一致的情况下。
  • 需要使用注解的情况:当需要处理可选参数、提供默认值、名称不一致或处理复杂对象时,建议使用 @RequestParam 或其他注解来明确指定绑定逻辑。

 四、请求参数绑定相关注解 

在 Spring MVC 中,请求参数绑定相关的注解主要用于将 HTTP 请求中的参数(如 URL 路径中的变量、查询参数、表单数据或请求体中的 JSON 数据等)绑定到控制器方法的参数上。以下是常用的请求参数绑定相关的注解及其详细解释:

1. @PathVariable

作用

@PathVariable 注解用于将 URL 路径中的模板变量绑定到控制器方法的参数上。它通常用于 RESTful 风格的 URL 中,用于获取路径中的动态部分。

特点
  • 绑定路径中的变量@PathVariable 可以将 URL 中的某个部分直接绑定到方法参数上。
  • 常用于 RESTful URL:特别适合于资源标识符(如 ID)的绑定。
示例代码
@GetMapping("/users/{id}")
public String getUser(@PathVariable Long id, Model model) {
    // 通过 id 获取用户信息
    User user = userService.findUserById(id);
    model.addAttribute("user", user);
    return "userDetails";
}

详细解释

  • @PathVariable("{id}"):将 URL /users/{id} 中的 {id} 动态路径变量绑定到方法参数 id 上。
  • 示例请求GET /users/123 会将 123 作为参数传递给 id,并用于查询用户信息。
支持多个路径变量
@GetMapping("/users/{userId}/orders/{orderId}")
public String getOrder(@PathVariable Long userId, @PathVariable Long orderId, Model model) {
    // 处理业务逻辑
}
  • 示例请求GET /users/123/orders/456 会将 userId 绑定为 123orderId 绑定为 456

2. @RequestParam 

作用

@RequestParam 注解用于将请求的查询参数或表单参数绑定到方法的参数上。它通常用于处理 GET 请求中的查询参数或 POST 请求中的表单数据。

特点
  • 绑定查询参数或表单字段:用于从 URL 查询字符串或表单字段中获取参数。
  • 支持默认值和是否必需:可以指定参数的默认值,也可以配置参数是否必须存在。

这里的@RequestParam注解所说的 “从 URL 查询字符串获取参数”就是指从普通的URL中获取参数(因为普通的URL中参数都是跟在路径下的问号之后),所以@RequestParam主要负责处理的是普通的URL。

还有就是“从表单字段获取参数”就是指前端创建了个HTML表单,@RequestParam将这些表单字段绑定到控制器方法的参数上。

示例代码--从 URL 查询字符串获取参数
@GetMapping("/search")
public String search(@RequestParam String query, @RequestParam(defaultValue = "1") int page, Model model) {
    // 执行搜索逻辑
    model.addAttribute("query", query);
    model.addAttribute("page", page);
    return "searchResults";
}

详细解释

  • @RequestParam("query"):将请求的查询参数 query 绑定到方法参数 query
  • @RequestParam(defaultValue = "1"):如果未提供 page 参数,则使用默认值 1
示例代码--从表单字段获取参数

 HTML表单

<form action="/submitForm" method="post">
    <input type="text" name="name" />
    <input type="number" name="age" />
    <button type="submit">Submit</button>
</form>
@PostMapping("/submitForm")
public String handleForm(@RequestParam String name, @RequestParam int age, Model model) {
    // 处理表单提交的数据
    model.addAttribute("name", name);
    model.addAttribute("age", age);
    return "formSuccess";
}

 详细解释

  • @RequestParam("name"):从表单字段 name 获取用户输入的值并绑定到方法参数 name 上。
  • @RequestParam("age"):从表单字段 age 获取用户输入的值并绑定到方法参数 age 上。
支持多个查询参数
@GetMapping("/filter")
public String filter(@RequestParam String category, @RequestParam(required = false) String brand) {
    // 处理业务逻辑
}
  • 示例请求GET /filter?category=electronics&brand=applecategory 绑定为 electronicsbrand 绑定为 apple

3. @RequestBody

作用

@RequestBody 注解用于将请求体中的 JSON、XML 或其他格式的数据绑定到方法参数上。它通常用于处理 POST、PUT 请求,接收客户端发送的 JSON 数据并将其反序列化为 Java 对象。

特点
  • 处理请求体数据:将请求体中的数据解析并绑定到方法参数,常用于 RESTful API 中的数据传递。
  • 自动反序列化 JSON:Spring MVC 自动将请求体中的 JSON 数据转换为 Java 对象。
示例代码
@GetMapping("/filter")
public String filter(@RequestParam String category, @RequestParam(required = false) String brand) {
    // 处理业务逻辑
}

详细解释

  • @RequestBody:用于接收请求体中的 JSON 数据并将其反序列化为 User 对象。
  • 示例请求
    POST /users
    {
      "name": "John",
      "email": "john@example.com"
    }
    
    • Spring MVC 会将 JSON 数据自动解析为 User 对象,并将其传递给控制器方法。
处理复杂数据
@PutMapping("/users/{id}")
public String updateUser(@PathVariable Long id, @RequestBody UserUpdateRequest updateRequest) {
    // 更新用户信息
}
  • 示例请求
    PUT /users/123
    {
      "email": "new-email@example.com",
      "name": "New Name"
    }
    

4. @ModelAttribute

作用

@ModelAttribute 注解用于将请求参数自动绑定到模型对象上,或者在方法上添加属性到模型中。它特别适合处理表单提交的数据绑定,将表单字段的数据自动绑定到 Java 对象中。

特点
  • 用于表单数据绑定:将请求参数自动填充到 Java 对象中。
  • 可以在方法级别使用:也可以用于向视图添加模型数据。
示例代码
@PostMapping("/register")
public String registerUser(@ModelAttribute User user, Model model) {
    userService.register(user);
    model.addAttribute("user", user);
    return "registrationSuccess";
}

详细解释

  • @ModelAttribute:自动将表单字段绑定到 User 对象的属性上。
  • 示例表单
<form action="/register" method="post">
  <input type="text" name="name" />
  <input type="email" name="email" />
  <button type="submit">Register</button>
</form>
  • 提交的表单数据会自动绑定到 User 对象的 nameemail 属性上。
向模型添加数据
@ModelAttribute("roles")
public List<String> getRoles() {
    return Arrays.asList("Admin", "User", "Guest");
}
  • 解释:该方法将 roles 数据添加到模型中,供视图层使用。

5. @RequestHeader

作用

@RequestHeader 注解用于将请求头中的数据绑定到方法参数上。它可以获取请求头中的某个字段的值,并将其传递给控制器方法。

特点
  • 用于绑定请求头数据:用于获取 HTTP 请求中的头信息。
  • 可以设置默认值:可以在请求头不存在时使用默认值。
示例代码
@GetMapping("/greet")
public String greetUser(@RequestHeader("User-Agent") String userAgent, Model model) {
    model.addAttribute("userAgent", userAgent);
    return "greeting";
}

详细解释

  • @RequestHeader("User-Agent"):将请求头中的 User-Agent 值绑定到方法参数 userAgent
  • 示例请求GET /greet 时,Spring MVC 会提取请求头中的 User-Agent 字段的值,并传递给 greetUser() 方法。
设置默认值
@GetMapping("/greet")
public String greetUser(@RequestHeader(value = "User-Agent", defaultValue = "Unknown") String userAgent) {
    // 如果请求头中没有 "User-Agent",使用默认值 "Unknown"
}

6. @CookieValue

作用

@CookieValue 注解用于将 HTTP 请求中的 Cookie 值绑定到方法参数上。它可以获取指定的 Cookie 的值,并传递给控制器方法。

特点
  • 用于绑定 Cookie 数据:获取客户端发送的 Cookie 中的值。
  • 支持设置默认值:如果 Cookie 不存在,可以设置默认值。
示例代码
@GetMapping("/welcome")
public String welcomeUser(@CookieValue(value = "userSessionId", defaultValue = "defaultSessionId") String sessionId) {
    // 使用 sessionId 处理逻辑
    return "welcome";
}

详细解释

  • @CookieValue("userSessionId"):将名为 userSessionId 的 Cookie 值绑定到 sessionId 参数。
  • 示例请求:客户端请求携带 Cookie userSessionId=abc123,该值将传递给 sessionId

7.@RequestPart 注解

作用

@RequestPart 注解用于处理 multipart/form-data 类型的请求,这种请求格式通常用于文件上传。通过 @RequestPart,Spring MVC 可以将文件部分绑定到 MultipartFile 对象,文件的元数据(如文件名、大小等)以及文件的实际内容都可以通过 MultipartFile 来获取。

特点
  • 处理文件上传:专门用于处理文件上传请求,绑定 multipart 请求中的文件数据。
  • 适合 multipart/form-data:这种类型的请求包含多个部分(如文件和其他普通字段),@RequestPart 主要处理文件部分。
  • MultipartFile 配合使用:Spring 提供了 MultipartFile 类型来处理上传的文件。

MultipartFile

MultipartFile 是 Spring 提供的一个接口,用来表示上传的文件。它包含文件的基本信息以及一些常用的方法,如获取文件名、文件大小、文件类型、将文件保存到服务器等。

常用方法:

  • getOriginalFilename():获取上传的文件名。
  • getSize():获取文件大小。
  • getContentType():获取文件类型(MIME type)。
  • transferTo(File dest):将文件保存到服务器上的某个位置。

示例代码:文件上传

控制器方法
@PostMapping("/upload")
public String handleFileUpload(@RequestPart("file") MultipartFile file) {
    if (!file.isEmpty()) {
        try {
            // 获取文件信息
            String fileName = file.getOriginalFilename();
            long fileSize = file.getSize();
            String contentType = file.getContentType();

            // 将文件保存到服务器
            file.transferTo(new File("/path/to/save/" + fileName));

            return "File uploaded successfully!";
        } catch (IOException e) {
            return "File upload failed: " + e.getMessage();
        }
    } else {
        return "No file uploaded!";
    }
}

详细解释

  • @RequestPart("file"):将文件上传表单字段 file 绑定到控制器方法的 MultipartFile 参数 file
  • MultipartFile:表示上传的文件,可以通过其方法获取文件名、大小、类型等信息。
  • file.transferTo():将上传的文件保存到服务器指定的目录。
HTML 示例
<form action="/upload" method="post" enctype="multipart/form-data">
    <label for="file">Choose a file:</label>
    <input type="file" id="file" name="file" />
    <button type="submit">Upload</button>
</form>
  • <input type="file">:这是文件输入控件,允许用户选择一个文件。
  • enctype="multipart/form-data":这是一种 MIME 类型,用于表示表单包含文件上传的数据。对于文件上传的表单,必须将 enctype 设置为 "multipart/form-data",否则文件不会被正确上传。
  • <button type="submit">Upload</button>:这是提交按钮,点击后会将选定的文件与表单数据一起提交到服务器。

8. 请求参数绑定注解的总结

注解用途数据来源
@PathVariable从 URL 路径中获取动态变量并绑定到方法参数URL 路径
@RequestParam从 URL 查询参数或表单字段中获取参数查询参数、表单
@RequestBody从请求体中接收 JSON 或 XML 数据并绑定到方法参数请求体
@ModelAttribute从请求参数中自动绑定到模型对象,或添加数据到模型中表单数据
@RequestHeader从请求头中获取某个字段的值并绑定到方法参数请求头
@CookieValue从请求的 Cookie 中获取值并绑定到方法参数Cookie

@PathVariable主要用于获取RESTfu类型的URL中的参数,而@RequestParam则用于普通URL中的参数与从表单字段中获取参数,当然如果不加这两个注解,只要URL中的参数名称与控制器方法中的名称一致也是可以自动绑定参数的。

五、响应相关注解 

pring MVC 提供了多个与响应相关的注解,用于控制 HTTP 响应的格式和内容。响应相关的注解主要用于将处理结果转换成客户端所期望的格式,比如 JSON、XML 或直接返回文本信息。以下是 Spring MVC 中常用的响应相关注解的详细介绍:

1. @ResponseBody

作用

@ResponseBody 是最常用的响应注解之一,它的作用是将控制器方法的返回值直接写入 HTTP 响应体(response body),而不是将其解析为视图名称。它通常用于返回 JSON、XML 或文本数据,特别适合用于构建 RESTful API

特点
  • 直接写入响应体:控制器方法的返回值不会通过视图解析器,而是直接写入 HTTP 响应体中。
  • 自动序列化:如果返回值是对象或列表,Spring 会自动将其序列化为 JSONXML 格式,前提是请求头中包含 Accept 字段,指定所期望的响应格式(如 application/json)。
示例代码
@RestController  // 也可以用 @Controller + @ResponseBody 组合
@RequestMapping("/api")
public class UserController {

    @GetMapping("/users/{id}")
    @ResponseBody  // 将返回的 User 对象作为 JSON 输出
    public User getUserById(@PathVariable Long id) {
        return userService.findUserById(id);
    }
}

详细解释

  • @ResponseBody:将方法的返回值 User 对象转换为 JSON 格式,并直接返回给客户端,而不是返回视图名称。
  • 示例请求GET /api/users/1
  • 返回的 JSON 格式:
{
    "id": 1,
    "name": "John",
    "email": "john@example.com"
}
@RestController 的关系
  • @RestController@Controller@ResponseBody 的组合注解,它将所有控制器方法的返回值都默认转换为响应体中的数据。因此,当你使用 @RestController 时,不再需要单独为每个方法添加 @ResponseBody 注解。

2. @ResponseStatus

作用

@ResponseStatus 注解用于为控制器方法或异常处理器指定 HTTP 状态码。当方法执行成功时,可以通过该注解指定自定义的 HTTP 状态码返回给客户端,通常用于在 RESTful API 中设置 HTTP 响应状态。

特点
  • 设置响应状态码:可以为成功或失败的操作设置特定的 HTTP 状态码,例如 201 Created204 No Content404 Not Found 等。
  • 可用于异常处理器:当捕获特定异常时,可以通过 @ResponseStatus 返回自定义的错误状态码。
示例代码
@PostMapping("/users")
@ResponseStatus(HttpStatus.CREATED)  // 返回 201 状态码
public User createUser(@RequestBody User user) {
    return userService.saveUser(user);
}

详细解释

  • @ResponseStatus(HttpStatus.CREATED):指定该方法成功执行后,返回 201 Created 状态码,表示资源已成功创建。
  • 示例请求POST /users,成功创建用户后,返回状态码 201 Created,并附带新创建的用户信息。
结合异常处理器
@ResponseStatus(HttpStatus.NOT_FOUND)  // 返回 404 状态码
public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message);
    }
}
  • 解释:当抛出 UserNotFoundException 时,Spring 会自动返回 404 Not Found 状态码。

3. @RestController

作用

@RestController 是一个组合注解,等同于 @Controller@ResponseBody 的组合。标注了 @RestController 的类中的每个方法都会默认返回对象或数据,并将其写入 响应体,而不需要每个方法都手动添加 @ResponseBody

特点
  • 简化 API 开发:对于 RESTful 风格的 API 开发,@RestController 非常适用,简化了控制器方法的开发流程。
  • 自动将返回值序列化:默认情况下,返回的对象会被自动序列化为 JSON 格式(如果客户端请求了 JSON 格式的响应)。
示例代码
@RestController
@RequestMapping("/api")
public class UserController {

    @GetMapping("/users")
    public List<User> getAllUsers() {
        return userService.findAllUsers();
    }
}

详细解释

  • @RestController:将控制器中的所有方法返回的对象直接转换为 JSON 数据,并将其写入响应体中。
  • 示例请求GET /api/users
  • 返回的 JSON 格式:
[
    {"id": 1, "name": "John"},
    {"id": 2, "name": "Jane"}
]

4. @ExceptionHandler

作用

@ExceptionHandler 注解用于定义异常处理器,处理控制器中抛出的特定异常。它可以返回自定义的响应内容和状态码,确保程序异常时返回一致的错误格式。

特点
  • 处理异常:通过 @ExceptionHandler,可以捕获指定的异常并返回自定义的错误信息和状态码。
  • @ResponseStatus 结合:可以结合 @ResponseStatus 一起使用,返回特定的 HTTP 状态码。
示例代码
@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.findUserById(id).orElseThrow(() -> new UserNotFoundException("User not found"));
    }

    @ExceptionHandler(UserNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public Map<String, String> handleUserNotFound(UserNotFoundException ex) {
        Map<String, String> error = new HashMap<>();
        error.put("error", ex.getMessage());
        return error;
    }
}

详细解释

  • userService.findUserById(id):这里通过 userService 服务层的方法根据用户 ID 查找用户,返回的是一个 Optional<User>,如果找到用户,就返回用户对象。
  • orElseThrow():这是 Java 8Optional 类的一个方法,它的作用是在找不到用户的情况下抛出一个自定义异常。这里抛出的是 UserNotFoundException,带有一个错误消息 "User not found"。
  • ExceptionHandler(UserNotFoundException.class):这个注解声明了一个异常处理方法,用于捕获控制器中抛出的 UserNotFoundException 异常,并自定义异常的响应内容和格式。当 UserNotFoundException 被抛出时,该方法会被调用,返回一个自定义的错误信息。
  • @ResponseStatus(HttpStatus.NOT_FOUND):这行注解表示,当捕获到 UserNotFoundException 时,HTTP 响应的状态码将设置为 404 Not Found
  • UserNotFoundException ex:该参数表示捕获的异常对象,可以用来获取异常中的信息。
  • ex.getMessage():从异常对象中获取错误消息,在 UserNotFoundException 中,这个消息是 "User not found"
  • 返回的错误信息
    {
        "error": "User not found"
    }
    

5. @ResponseBody 与视图解析器的区别

在 Spring MVC 中,如果没有使用 @ResponseBody,默认情况下,方法返回的字符串会被视为 视图名称,由 视图解析器(如 Thymeleaf、JSP)来渲染页面。使用了 @ResponseBody@RestController 后,返回的内容将直接写入 HTTP 响应体,而不再经过视图解析器。

示例对比
  • 没有 @ResponseBody(返回视图)
@GetMapping("/hello")
public String hello() {
    return "helloPage";  // 将视图名称 "helloPage" 交给视图解析器处理
}
  • @ResponseBody(返回文本或 JSON)
@GetMapping("/hello")
@ResponseBody
public String hello() {
    return "Hello, World!";  // 将 "Hello, World!" 写入 HTTP 响应体
}
  • @ResponseBody:将控制器方法的返回值直接写入响应体,适用于返回 JSON、XML 或文本数据,特别适用于 RESTful API 开发。
  • @ResponseStatus:用于指定控制器方法的返回状态码,常用于成功创建、删除或自定义异常处理等场景。
  • @RestController:组合了 @Controller@ResponseBody,简化 RESTful 控制器的开发,自动将返回值转换为 JSON 并写入响应体。
  • @ExceptionHandler:用于处理控制器中的异常,并返回自定义的错误响应和状态码。

六、会话和请求作用域注解 

在 Spring MVC 中,作用域(Scope)用于定义 Spring Bean 的生命周期和可见性范围。在 Spring 中,最常用的作用域有 会话作用域(Session Scope)请求作用域(Request Scope)

1. @RequestScope

作用

@RequestScope 注解用于声明一个 Bean 具有 请求作用域,即每次新的 HTTP 请求都会创建一个新的 Bean 实例。当请求结束时,Bean 实例会被销毁。

特点
  • 短生命周期:每次 HTTP 请求都会生成一个新的 Bean 实例,生命周期从请求开始到请求结束。
  • 适用场景:适合处理与单个 HTTP 请求相关的数据或对象。

Bean就是一个由Spring容器管理的类,Spring来负责控制这个对象的创建与销毁,就比如在下图中通过 @Component注解规定了RequestBean类是一个Bean,然后在控制器类中创建RequestBean类的对象就是Bean的实例,这个对象的生命周期就是从请求开始到请求结束,请求结束之后就销毁该对象,释放相关资源。

示例代码
@Component
@RequestScope
public class RequestBean {
    private String message;
    // getter and setter
}

@RestController
public class MyController {
    @Autowired
    private RequestBean requestBean;

    @GetMapping("/request")
    public String handleRequest() {
        requestBean.setMessage("Request Scoped Bean Example");
        return requestBean.getMessage();
    }
}

详细解释

  • @RequestScope:标注的 RequestBean 是请求作用域的,每次发送请求 /request 时,都会生成一个新的 RequestBean 实例。
  • 生命周期:每个请求都会有一个新的实例,在请求结束后,RequestBean 会被销毁。

2. @SessionScope

作用

@SessionScope 注解用于声明一个 Bean 具有 会话作用域,即同一用户的多个请求会共享同一个 Bean 实例,直到用户会话结束。

特点
  • 长生命周期:Bean 在整个用户会话期间存在,可以跨多个 HTTP 请求共享数据。
  • 适用场景:适合需要跨多个请求共享数据的情况,如用户登录信息、购物车等。
示例代码
@Component
@SessionScope
public class SessionBean {
    private String username;
    // getter and setter
}

@RestController
public class MyController {
    @Autowired
    private SessionBean sessionBean;

    @GetMapping("/login")
    public String login(@RequestParam String username) {
        sessionBean.setUsername(username);
        return "User " + sessionBean.getUsername() + " logged in.";
    }

    @GetMapping("/user")
    public String getUser() {
        return "Current user: " + sessionBean.getUsername();
    }
}

详细解释

  • @SessionScope:标注的 SessionBean 是会话作用域的,在整个会话期间,SessionBean 实例会被多次请求共享。
  • 生命周期:会话开始时创建 SessionBean,在会话结束时销毁实例。

3. 请求作用域与会话作用域的区别

特性请求作用域(Request Scope)会话作用域(Session Scope)
生命周期每次请求都会创建新的 Bean 实例,生命周期随请求结束而结束在整个会话期间共享同一个 Bean 实例,直到会话过期
实例数量每次请求都有一个新的实例整个会话期间共享一个实例
适用场景适合短暂的数据存储,处理一次请求的数据适合需要在整个会话中共享的数据(如用户登录状态)
结束时间请求处理完毕后销毁 Bean 实例会话结束时销毁 Bean 实例
  • @RequestScope:Bean 在每个请求中生存,每次请求会创建一个新的实例,适用于一次请求期间的数据存储。
  • @SessionScope:Bean 在整个用户会话中生存,每次会话共享一个实例,适用于在整个会话中保持数据,如用户登录状态等。

通过选择不同的作用域,你可以精确控制 Spring Bean 的生命周期,确保它们在合适的范围内生存,避免资源浪费和逻辑错误。

七、安全和认证相关注解 

在 Spring Security 中,安全和认证 相关的注解用于处理用户权限、认证和授权等问题。这些注解可以帮助你轻松地为应用添加安全保护功能。

Spring Security 中,用户的权限(或角色)通常用于控制该用户能执行哪些操作或访问哪些资源。

用户角色解释

  • 角色 是一种 权限标识,它定义了用户在系统中的操作权限范围。比如 ROLE_ADMIN 通常代表用户是管理员,具有较高的权限,可以执行创建、修改、删除等敏感操作。
  • 具备 ROLE_ADMIN 角色的用户,就是指在系统中,用户的权限信息中包含 ROLE_ADMIN 这个角色。Spring Security 会根据这个角色判断用户是否有权访问某些方法或资源。

用户角色的来源

  • 用户角色通常是在用户 认证(登录) 时,通过数据库、内存或第三方认证服务(如 OAuth、LDAP)加载的。认证完成后,Spring Security 会将这些角色与用户绑定,用户的角色信息会存储在 SecurityContext 中。

例子:用户的角色信息

假设一个用户登录后,其角色信息如下:

  • 用户名:admin
  • 角色:ROLE_ADMIN, ROLE_USER

那么这个用户既具备 普通用户 (ROLE_USER) 的权限,也具备 管理员 (ROLE_ADMIN) 的权限。

用户角色的存储与分配

  • 数据库:角色信息通常存储在数据库中,和用户的记录关联在一起。登录时系统会从数据库中读取用户的角色信息。
  • 硬编码:有时,角色信息会直接在代码中指定,特别是在简单的应用中

1. @Secured

作用

@Secured 用于基于 用户角色 限制方法访问。只有拥有指定角色的用户才能访问该方法。

特点
  • 基于 角色 限制访问。
  • 简单易用,适用于只需要基于角色的权限控制场景。
示例代码
@Secured("ROLE_ADMIN")
public void adminOnlyMethod() {
    // 只有拥有 ROLE_ADMIN 角色的用户才能访问
}

详细解释

  • @Secured("ROLE_ADMIN"):只有具备 ROLE_ADMIN 角色的用户才能访问 adminOnlyMethod() 方法。用户如果没有该角色,Spring Security 会拒绝访问。

2. @PreAuthorize

作用

@PreAuthorize 用于方法执行 之前 验证权限。支持复杂的权限控制逻辑,可以通过 Spring Expression Language (SpEL) 表达式实现。

特点
  • 支持 复杂权限控制,不仅可以基于角色,还可以基于方法参数和用户属性进行控制。
  • 灵活,适用于需要根据多种条件进行权限验证的场景。
示例代码
@PreAuthorize("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')")
public void userOrAdminAccess() {
    // 用户或管理员角色的用户可以访问
}

详细解释

  • @PreAuthorize("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')"):允许拥有 ROLE_USERROLE_ADMIN 角色的用户访问该方法。@PreAuthorize 在方法执行前进行权限检查,确保用户满足至少一个角色的条件。

3. @PostAuthorize

作用

@PostAuthorize 用于在方法执行 之后 验证权限,通常用于根据方法的返回结果判断用户是否有权限访问。

特点
  • 支持 返回结果 的权限验证,适合在方法执行后根据返回的对象属性进行权限检查。
  • 常用于需要先执行逻辑,再验证用户是否有权限查看或处理返回数据的场景。
示例代码
@PostAuthorize("returnObject.owner == authentication.name")
public Document getDocument(Long id) {
    // 只有文档的拥有者才能访问
    return documentService.findById(id);
}

详细解释

  • @PostAuthorize("returnObject.owner == authentication.name"):在方法执行后,检查返回的 Document 对象的 owner 属性是否等于当前登录用户的用户名。如果当前用户不是文档的拥有者,Spring Security 将拒绝访问返回的结果。

4. @RolesAllowed

作用

@RolesAllowed 限制方法访问,只有具有指定角色的用户才能访问该方法。它是 JSR-250 标准的一部分,功能类似于 @Secured

特点
  • 基于 角色 的权限控制,支持多个角色。
  • 多个角色之间的权限是 OR 关系,即用户只要拥有其中一个角色即可访问。
示例代码
@RolesAllowed({"ROLE_USER", "ROLE_ADMIN"})
public void userOrAdminAccess() {
    // 拥有 ROLE_USER 或 ROLE_ADMIN 的用户可以访问
}

详细解释

  • @RolesAllowed({"ROLE_USER", "ROLE_ADMIN"}):方法只允许拥有 ROLE_USERROLE_ADMIN 角色的用户访问。如果用户拥有其中任意一个角色,访问将被允许。

5. @AuthenticationPrincipal

作用

@AuthenticationPrincipal 用于获取当前登录用户的详细信息,通常用于在控制器方法中直接访问用户的认证信息。

特点
  • 可以直接访问 当前登录用户 的信息,简化了从 SecurityContext 中手动获取用户信息的流程。
  • 适用于需要在控制器中使用当前用户信息的场景。
示例代码
@GetMapping("/profile")
public String getUserProfile(@AuthenticationPrincipal UserDetails userDetails) {
    return "User profile: " + userDetails.getUsername();
}

详细解释

  • @AuthenticationPrincipal UserDetails userDetails:Spring Security 会自动将当前认证用户的详细信息注入到 userDetails 参数中,开发者可以直接获取用户的用户名、权限等信息,而不需要手动从 SecurityContext 获取。

6.安全和认证相关注解总结

注解作用适用场景示例解释
@Secured基于角色限制方法访问简单的角色权限控制只有指定角色的用户才能访问方法,角色必须以 ROLE_ 为前缀。
@PreAuthorize在方法执行前进行权限检查,支持复杂的 SpEL 表达式灵活、复杂的权限控制根据角色或方法参数灵活控制访问,适合多种条件下的权限控制。
@PostAuthorize在方法执行后进行权限检查返回结果的权限控制根据方法返回的对象属性进行权限判断,例如检查是否为数据的拥有者。
@RolesAllowed基于角色限制方法访问,JSR-250 标准简单的角色权限控制支持多个角色,多个角色是 OR 关系,用户只需拥有其中一个角色即可。
@AuthenticationPrincipal获取当前登录用户信息获取当前用户信息直接访问当前登录用户的详细信息,简化了获取用户信息的操作。

八、拦截器相关注解 

在 Spring MVC 中,拦截器(Interceptor) 用于在请求到达控制器之前、执行完控制器之后、以及请求完成之后,执行一些预处理或后处理操作。拦截器通常用于实现功能,例如 权限校验日志记录性能监控 等。与拦截器相关的注解主要是通过 配置拦截器来控制其行为,而不是直接通过注解实现。不过,Spring 提供了一些与拦截器配置相关的注解和接口,常见的包括 HandlerInterceptor 接口以及相关的配置注解。

1. @Component

作用

@Component 注解用于将拦截器类标记为 Spring 的 Bean,使其可以被 Spring 容器管理,并通过 Java 配置或 XML 配置进行注册。

特点
  • 通过 @Component 将拦截器类加入到 Spring 容器中,确保拦截器能够在应用启动时被扫描到。
示例代码
@Component
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Before handler method");
        return true;
    }
}

详细解释

  • @Component:将 MyInterceptor 类注册为 Spring 的 Bean,使它能够被 Spring 容器自动管理。
  • 通过实现 HandlerInterceptor 接口,MyInterceptor 类可以对 HTTP 请求进行拦截,执行预处理逻辑。

 这里注解@Component的作用是将  类MyInterceptor(三个拦截器方法preHandle和postHandle和afterCompletion所在的类) 注册为 Spring 的 Bean,这样确保在对HTTP请求进行拦截的时候这个类能被扫描到执行预处理。


2. @Configuration

作用

@Configuration 注解用于定义一个配置类,Spring 会将此类作为配置类进行处理。通过该配置类,我们可以注册拦截器。

特点
  • 该注解可以结合 WebMvcConfigurer 接口,用于配置拦截器、视图解析器等。
示例代码
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor).addPathPatterns("/**");
    }
}

详细解释

  • @Configuration:标记 WebConfig 为配置类。
  • addInterceptors():通过 WebMvcConfigurer 接口的方法,将自定义的拦截器注册到 Spring 的拦截器链中。
  • addPathPatterns("/**"):表示拦截所有路径下的请求。

3. @Order

作用

@Order 注解用于指定多个拦截器的执行顺序。顺序值越小,拦截器的优先级越高,先被执行。

特点
  • 可以控制拦截器的顺序,确保某些拦截器优先执行。
示例代码
@Component
@Order(1)  // 优先级高
public class FirstInterceptor implements HandlerInterceptor {
    // 拦截器代码
}

@Component
@Order(2)  // 优先级较低
public class SecondInterceptor implements HandlerInterceptor {
    // 拦截器代码
}

详细解释

  • @Order(1)FirstInterceptor 的优先级为 1,表示它会先于其他拦截器执行。
  • @Order(2)SecondInterceptor 的优先级为 2,表示它在 FirstInterceptor 之后执行。
注解作用示例解释
@Component将拦截器类注册为 Spring Bean将拦截器类标记为 @Component,使其被 Spring 容器管理。
@Configuration标记配置类,通常用于注册拦截器使用 @Configuration 结合 addInterceptors() 方法配置拦截器。
@Order定义多个拦截器的执行顺序@Order(1) 优先级高,@Order(2) 优先级低。

九、跨域相关注解 

在 Web 开发中,跨域(CORS,Cross-Origin Resource Sharing) 是一个安全策略,限制网页从不同的域名、协议或端口加载资源。为了允许跨域请求,Spring 提供了几种注解来简化跨域资源共享的配置。

1. @CrossOrigin

作用

@CrossOrigin 注解用于允许跨域请求。它可以作用在 控制器类控制器方法 上,用于定义允许来自哪些域的请求可以访问资源,并且可以设置请求的方法、头部、凭证等参数。

特点
  • 可以在类或方法上标注,灵活地控制哪些资源允许被跨域访问。
  • 支持详细配置,包括允许的源(域名)、HTTP 方法、请求头、凭证等。
示例代码
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://example.com", maxAge = 3600)
public class MyController {

    @GetMapping("/data")
    public String getData() {
        return "This is some data";
    }
}

详细解释

  • @CrossOrigin(origins = "http://example.com"):允许来自 http://example.com 这个源的跨域请求访问该控制器的方法。
  • maxAge = 3600:在 3600 秒(即 1 小时)内缓存跨域请求的结果,避免每次请求都进行跨域验证。
  • @CrossOrigin 可以配置以下参数:
    • origins:允许哪些域可以访问资源,如 http://example.com,也可以设置为 * 以允许所有域访问。
    • methods:允许的 HTTP 方法,如 GETPOST 等。
    • allowedHeaders:允许的请求头。
    • exposedHeaders:哪些响应头可以暴露给客户端。
    • allowCredentials:是否允许发送凭证(如 Cookies),默认为 false

2. @Configuration 配置跨域

作用

在全局配置类中,通过 WebMvcConfigurer 接口配置跨域规则,可以在一个地方集中管理跨域设置,适合需要全局配置跨域请求的场景。

特点
  • 适合全局配置,所有路径或某些指定的路径都可以统一设置跨域规则。
  • 更灵活,适用于需要为多个控制器或整个应用启用跨域的情况。
示例代码
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")  // 允许所有路径
                .allowedOrigins("http://example.com")  // 允许的域
                .allowedMethods("GET", "POST")  // 允许的 HTTP 方法
                .allowCredentials(true)  // 允许携带凭证
                .maxAge(3600);  // 跨域请求的缓存时间
    }
}

详细解释

  • addCorsMappings():通过这个方法为所有路径 /** 启用跨域请求。
  • allowedOrigins("http://example.com"):仅允许来自 http://example.com 的请求跨域访问。
  • allowedMethods("GET", "POST"):只允许 GETPOST 方法的跨域请求。
  • allowCredentials(true):允许客户端发送 Cookies 等凭证信息。
  • maxAge(3600):缓存跨域请求的验证结果,减少跨域请求时的重复检查。

3. @CrossOrigin 与全局配置的区别

  • @CrossOrigin 注解:适用于控制器类或方法级别的跨域配置,通常用于局部配置某个控制器允许跨域请求,灵活性高,但只影响单个控制器或方法。
  • 全局配置:通过实现 WebMvcConfigurer 接口进行跨域配置,适合全局管理跨域请求。可以为整个应用或多个控制器统一设置跨域规则。


注解/配置作用适用场景示例解释
@CrossOrigin控制器类或方法级别的跨域请求配置局部控制器或方法需要允许跨域请求允许来自指定域名、方法的跨域请求,适用于单个控制器的配置。
@Configuration 配置跨域全局跨域请求配置全局管理跨域请求,适合大规模应用通过配置类实现全局的跨域控制,适用于需要为整个应用启用跨域。
  • @CrossOrigin 是最常用的注解,允许在控制器类或方法上灵活地设置跨域规则。
  • 如果需要全局配置跨域规则,可以通过 WebMvcConfigurer 接口进行集中管理。

十、总结 

注解类型注解作用说明
核心控制器注解@Controller, @RestController定义类为控制器,处理 HTTP 请求。@Controller 返回视图,@RestController 返回 JSON、XML 等数据格式。
请求映射注解@RequestMapping, @GetMapping, @PostMapping将 HTTP 请求映射到控制器的方法上。根据 URL 和请求方法(如 GET、POST)将请求映射到对应的方法。
跨域相关注解@CrossOrigin允许跨域请求访问资源。用于处理跨域资源共享,配置允许的域、HTTP 方法等。
拦截器相关方法preHandle, postHandle, afterCompletion处理请求前后的操作。preHandle 预处理,postHandle 方法后处理,afterCompletion 完成请求后的清理工作。
拦截器配置注解@Configuration注册拦截器、配置请求拦截行为。用于通过实现 WebMvcConfigurer 配置拦截器。
安全和认证相关注解@PreAuthorize, @Secured检查用户是否有权限访问控制器方法。进行安全验证,确保用户具备访问资源的权限。
请求参数绑定注解@RequestParam, @PathVariable, @RequestBody, @ModelAttribute将请求中的数据绑定到控制器方法参数。提取 URL 参数、表单数据或 JSON 数据,并绑定到控制器方法参数。
响应相关注解@ResponseBody将控制器方法返回值作为 HTTP 响应体返回。将 Java 对象直接转换为 JSON、XML 等格式并返回。
会话和请求作用域注解@RequestScope, @SessionScope控制 Bean 在请求或会话期间的生命周期。@RequestScope 管理请求期间的 Bean 生命周期,@SessionScope 管理会话期间的 Bean 生命周期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值