SpringBoot中的注解详解(一)

一、@RestController、@RequestMapping

1、@RestController注解

@RestController注解是SpringMVC中的一个组合注解,用于标记一个类为控制器类。它实际上是@Controller和@ResponseBody注解的组合,表示该类中的所有方法都会返回JSON、XML等格式的数据,而不是视图页面。

使用方式:
  1. 在需要处理HTTP请求的类上添加@RestController注解。

  2. 在类中定义处理HTTP请求的方法,并使用@RequestMapping或者其派生注解(如@GetMapping,@PostMapping等)来映射请求路径。

示例:

java 复制代码
@RestController
@RequestMapping("/book")
public class BookController {

    @Autowired
    private BookService bookService;

    @GetMapping
    public Result list(String keyword,
                       Integer categoryId){
        List<Book> books = bookService.list(keyword, categoryId);
        return Result.success(books);
    }

    @GetMapping("/{id}")
    public Result get(@PathVariable("id") Integer id){
        Book book = bookService.get(id);
        return Result.success(book);
    }

    @PostMapping
    public Result add(@RequestBody Book book){
        bookService.add(book);
        return Result.success();
    }
    @PutMapping
    public Result update(@RequestBody Book book){
        bookService.update(book);
        return Result.success();
    }

    @DeleteMapping("/{ids}")
    public Result delete(@PathVariable("ids") List<Integer> ids){
        bookService.delete(ids);
        return Result.success();
    }
}
使用场景:
  • 当需要创建RESTful API时,使用@RestController注解来标记控制器类。

  • 适用于返回JSON、XML等数据格式的API开发。

  • 通常放在项目的controller包下,与处理HTTP请求相关的类放在一起。

底层原理:
java 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
    @AliasFor(annotation = Controller.class)
	String value() default "";
}
  1. @RestController注解实际上是@Controller和@ResponseBody注解的组合。

    • @Controller:标记该类为一个控制类,Spring容器会扫描并注册该类。

    • @ResponseBody:表示该类中的所有方法返回的数据都会直接写入HTTP响应体中,而不是解析为视图页面。

  2. SpringMVC会使用RequestMappingHandlerMapping来扫描带有@Controller注解的类,并将这些类中的方法与URL映射起来。

  3. 当请求到达时,RequestMappingHandlerAdapter会调用相应的处理器方法,并将返回值转换为响应体中的数据。

@RestController 注解的底层原理
  • Spring 容器启动 :Spring 容器启动时,会扫描带有 @Configuration 注解的类。

  • 解析 @Configuration 类中的 @Bean 方法 :解析这些类中的 @Bean 方法,创建并注册 Bean 到容器。

  • 扫描带有 @ComponentScan 的包 :扫描配置中指定的包,发现带有 @RestController 注解的类。

  • 创建并注册 Controller 到容器:创建并注册这些 Controller 到容器。

  • 创建代理对象:如果需要,创建代理对象以确保线程安全和依赖注入。

  • 请求到达 DispatcherServlet :当请求到达时,DispatcherServlet 会调用 RequestMappingHandlerMapping

  • 查找匹配的 HandlerMethodRequestMappingHandlerMapping 会查找匹配的 HandlerMethod

  • 调用 RequestMappingHandlerAdapterDispatcherServlet 调用 RequestMappingHandlerAdapter 来执行 Controller 方法。

  • 返回值处理 :通过 @ResponseBody 注解,将返回值写入 HTTP 响应体。

2、@RequestMapping注解

@RequestMapping注解用于映射HTTP请求到控制器类或方法上。它可以放在类级别或方法级别,用于指定请求的URL路径、HTTP方法、请求参数等

使用方法:
  • 在类级别使用@RequestMapping注解,指定该类的所有方法的公共路径前缀。

  • 在方法级别使用@RequestMapping注解,指定具体的请求路径和HTTP方法。

java 复制代码
@RestController
@RequestMapping("/book")
public class BookController {

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public Book getBook(@PathVariable Long id) {
        // 处理获取书籍的逻辑
        return new Book(id, "Spring Boot in Action");
    }

    @RequestMapping(method = RequestMethod.POST)
    public Book createBook(@RequestBody Book book) {
        // 处理创建书籍的逻辑
        return book;
    }
}
使用场景:
  1. 当需要将HTTP请求映射到控制器类或方法上时,使用@RequestMapping注解。

  2. 适用于处理各种HTTP方法(GET、POST、PUT、DELETE 等)的请求。

  3. 通常放在控制器类或方法上,与处理HTTP请求相关的类和方法放在一起。

底层原理:
java 复制代码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
    String name() default "";
    @AliasFor("path")
	String[] value() default {};
    @AliasFor("value")
	String[] path() default {};
    RequestMethod[] method() default {};
    String[] params() default {};
    String[] headers() default {};
    String[] consumes() default {};
    String[] produces() default {};
}
  1. @RequestMapping注解被RequestMappingHandlerMapping处理,该类负责将请求URL映射到相应的控制器方法。

  2. @RequestMappingHandlerMapping会扫描带有@Controller注解的类,并将这些类中的方法与URL映射起来。

  3. 当请求到达时,DispatcherServlet会根据请求URL和HTTP方法找到对应的处理器方法,并调用RequestMappingHandlerAdapter来执行该方法。

  4. RequestMappingHandlerAdapter会处理方法参数的绑定、方法的调用以及返回值的处理。

@RequestMapping 注解的底层原理
  • 请求到达 DispatcherServlet :当请求到达时,DispatcherServlet 会调用 RequestMappingHandlerMapping

  • 查找匹配的 HandlerMethodRequestMappingHandlerMapping 会查找匹配的 HandlerMethod,首先匹配类级别的 @RequestMapping,然后匹配方法级别的 @RequestMapping

  • 找到匹配的 HandlerMethod :找到匹配的 HandlerMethod 后,DispatcherServlet 调用 RequestMappingHandlerAdapter

  • 调用 Controller 方法RequestMappingHandlerAdapter 调用 Controller 方法,处理方法参数(如 @PathVariable, @RequestBody 等)。

  • 执行 Controller 方法:执行 Controller 方法。

  • 返回值处理 :通过 @ResponseBody 注解,将返回值写入 HTTP 响应体。

总结:

@RestController 注解
  • 功能:标记一个类为控制器类,所有方法返回 JSON、XML 等数据。

  • 使用方式 :在类上添加 @RestController 注解,类中定义处理 HTTP 请求的方法。

  • 使用场景:创建 RESTful API,返回数据格式的 API 开发。

  • 放置位置 :通常放在 controller 包下。

  • 底层原理 :组合了 @Controller@ResponseBody 注解,Spring MVC 会扫描并注册该类,处理请求并返回数据。

@RequestMapping 注解
  • 功能:映射 HTTP 请求到控制器类或方法上。

  • 使用方式 :在类或方法上添加 @RequestMapping 注解,指定请求路径和 HTTP 方法。

  • 使用场景:处理各种 HTTP 方法的请求。

  • 放置位置:通常放在控制器类或方法上。

  • 底层原理 :被 RequestMappingHandlerMapping 处理,将请求 URL 映射到相应的控制器方法,DispatcherServlet 调用 RequestMappingHandlerAdapter 执行方法。


二、@GetMapping、@PostMapping、@PutMapping、@DeleteMapping("/{ids}")

1、@GetMapping、@PostMapping、@PutMapping、@DeleteMapping("/{ids}") (Controller层)

注解概述:
  • 注解类型:这些注解属于Spring框架中的控制器注解,用于定义HTTP请求映射。

  • 功能:

    1. @GetMapping:映射HTTP GET请求到特定的处理方法上。

    2. @PostMapping:映射HTTP POST请求到特定的处理方法上。

    3. @PutMapping:映射HTTP PUT请求到特定的处理方法上。

    4. **@DeleteMapping:**映射HTTP DELETE请求到特定的处理方法上。

  • 使用方法:这些注解通常用于SpringMVC或SpringBoot的控制器类中的方法上,以指定该方法处理HTTP请求类型和路径。

使用场景:
  1. @GetMapping:适用于获取资源信息的场景,如查询数据。

  2. @PostMapping:适用于创建新资源的场景,如提交表单数据。

  3. @PutMapping:适用于更新现有资源的场景,如修改用户信息。

  4. @DeleteMapping:适用于删除资源的场景,如删除用户记录。

  5. 这些注解应放置在控制器类的方法上,通常用于@Controller或@RestController注解的类中。

底层原理:
  • 注解解析 :Spring框架在启动时会扫描带有@Controller@RestController注解的类,并解析其中的方法上的这些注解。

  • 请求映射 :Spring MVC通过RequestMappingHandlerMapping将这些注解映射到具体的处理器方法上。

  • 请求处理:当接收到HTTP请求时,Spring MVC会根据请求的URL和HTTP方法找到对应的处理器方法,并调用该方法处理请求。

小结:

  • 类型:方法注解

  • 位置:基于SpringMVC的RESTful开发控制器方法定义上方

  • 作用:设置当前控制器方法请求访问路径与请求动作,每种对应一个请求

  • 动作,例如@GetMapping对应GET请求

  • 属性:value(默认):请求访问路径

2、@PathVariable、@RequestBody 、@RequestParam、

@PathVariable:
  • 功能:用于从URL模板中提取变量值,并将其绑定到方法参数上。

  • 使用场景:适用于需要从URL路径中获取动态部分的场景,如获取某个用户的详细信息。

  • 作用:绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应

  • 用于从URL路径中获取数据,通常用于处理RESTful风格的请求。

    可以将URL中的占位符部分提取为方法参数,用于标识资源的唯一标识符。

    可以指定参数名称、正则表达式等属性。

    适用于获取URL中的动态参数,如用户ID、商品ID等。

    示例: @GetMapping("/users/{id}") public String getUser(@PathVariable("id") int userId) { ... }

@RequestBody:
  • 功能:用于将HTTP请求体中的数据绑定到方法的参数上。

  • 使用场景:适用于需要接收客户端发送的JSON、XML等格式的数据的场景,如创建或更新资源

  • 作用:将JSON数据映射到形参的实体类对象中

    设置控制器方法返回值作为响应体返回给客户端,无需解析,Spring MVC会将返回的对象转换为JSON格式的响应体,并设置正确的响应头

  • 适用于处理复杂的数据结构,可以将请求体中的数据映射到对象或集合类型的参数上。

    示例: @PostMapping("/users") public String createUser(@RequestBody User user) { ... }

@RequestParam:
  • 功能:用于从HTTP请求的查询参数中提取值,并将其绑定到方法参数上。

  • 使用场景:适用于需要从URL查询参数中获取值的场景,如分页查询

  • 用于从请求参数中获取数据,通常用于处理GET请求或POST请求的表单数据。

    可以获取请求URL中的查询参数或POST请求中的表单参数。

    可以指定参数名称、是否必需、默认值等属性。

    适用于获取简单的请求参数,如字符串、数字等。

    示例: @GetMapping("/users") public String getUser(@RequestParam("id") int userId) { ... }

java 复制代码
	/**
     * 根据书籍 ID 获取书籍详情。
     * @param id 从 URL 中提取书籍 ID
     * @return 返回包含书籍详情的 Result 对象
     */
    @GetMapping("/{id}") // 映射 GET 请求到该方法,路径参数为 id
    public Result get(@PathVariable("id") Integer id){
        Book book = bookService.get(id);
        return Result.success(book);
    }

	// 更新书籍信息
    // @RequestBody:从请求体中读取 Book 对象
    @PutMapping
    public Result update(@RequestBody Book book){
        bookService.update(book);
        return Result.success();
    }

  /**
     *  用于处理分页查询请求
     *  指定了该方法处理HTTP GET请求,并且要求请求中必须包含pageNum 和 pageSize两个查询参数
     * @param pageNum 请求的页码,从请求的查询参数中提取名为pageNum的参数,并将其绑定到方法参数pageNum上
     * @param pageSize 页的大小,从请求的查询参数中提取名为pageSize的参数,并将其绑定到方法参数pageSize上
     * @param publisher 出版社信息,从请求的查询参数中提取名为publisher的参数,并将其绑定到方法参数publisher上
     * @return : 将查询结果封装到Result对象中,并返回给客户端。
     */
    @GetMapping(params = {"pageNum", "pageSize"})
    public Result pageQuery(@RequestParam("pageNum") int pageNum,
                            @RequestParam("pageSize") int pageSize,
                            @RequestParam("publisher") String publisher){
        // 调用bookService的pageQuery方法,传入分页参数和版本社名称,获取分页查询结果
        Page<Book> page = bookService.pageQuery(pageNum, pageSize, publisher);
        return Result.success(page);
    }

请简述 @RequestBody @RequestParam @PathVariable的区别

  1. 3个注解它们都是Spring MVC框架中常用的注解,用于从HTTP请求中获取数据。

  2. @RequestParam 用于获取请求参数中的数据 , @RequestBody 用于获取请求体中的数据 , @PathVariable 用于获取URL路径中的数据

  3. 它们分别适用于不同的场景和数据来源,可以根据具体的业务需求选择适合的注解来获取HTTP请求中的数据。

三、@RestControllerAdvice、@ExceptionHandler(Exception.class) (exception包)

@RestControllerAdvice:

  • 功能:用于定义全局异常类,可以处理所有带有@Controller@RestController注解的控制器类中抛出的异常。

  • 使用场景:统一处理应用中所有控制器的异常,提供一致的错误响应格式。

  • 类型: 类注解

  • 位置:Rest风格开发的控制器增强类定义上方

  • 作用:为Rest风格开发的控制器类做增强

  • 说明:此注解自带@ResponseBody注解与@Component注解,具备对应的功能

@ExceptionHandler(Exception.class) :

  • 功能:用于定义处理特定异常的方法,方法参数为需要处理的异常类型。

  • 使用方法:放置在方法声明上,方法参数为需要处理的异常类型。

  • 使用场景:适用于需要针对异常类型进行处理的场景。

  • 通常放置在@RestControllerAdvice注解的类中的方法上。

  • 类型: 方法注解

  • 位置:专用于异常处理的控制器方法上方

  • 作用:设置指定异常的处理方案,功能等同于控制器方法,出现异常后终止原始控制器执行,并转入当前方法执行

  • 说明:此类方法可以根据处理的异常不同,制作多个方法分别处理对应的异常

java 复制代码
package com.briup.demo.exception;

import com.briup.demo.response.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @author 35329
 *
 * 全局处理异常处理器
 *
 * 两大作用:
 * 1)统一对Controller中抛出的业务异常进行
 * 降低代码的冗余。
 * 2)程序中可能出现的异常到返回给前端之前的最后一道屏障。
 * 能够正常提供服务的最后一道屏障。
 * 控制程序不会直接向前端返回内部的逻辑错误。
 *
 * 具体的实施方法
 * 1、在类上添加注解:@RestControllerAdvice
 * 添加了该注解之后,在这个类中方法的返回值就和Controller中的方法一样
 * 直接作为返回前端的响应报文体部的数据
 *
 * 2、定义一个统一处理异常的方法
 * 在该方法上添加该注解:@ExceptionHandler
 * 在改注解中配置value属性值,指定要拦截的异常类型。
 * 实际开发中,通常都会设置为异常体系的最高级别类型:Exception
 *
 * 如果需要对异常对象进行直接处理
 * 可以在方法中定义一个Exception类型的参数,
 * 只要我们定义了这个参数,Spring框架在调用该方法的时候,
 * 就会把底层上抛的异常作为参数传递
 *
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public Result handle(Exception e){
        // 需要对异常的具体类型进行判断:
        // 1、对自己主动抛出的业务类型异常
        // 2、其他所有未知的运行时异常
        if (e instanceof BookException){
            return Result.failure(e.getMessage());
        }
        return Result.failure("服务器繁忙,请稍后重试");
    }

}
相关推荐
颜淡慕潇15 分钟前
【K8S系列】kubectl describe pod显示ImagePullBackOff,如何进一步排查?
后端·云原生·容器·kubernetes
TheITSea25 分钟前
云服务器宝塔安装静态网页 WordPress、VuePress流程记录
java·服务器·数据库
AuroraI'ncoding33 分钟前
SpringMVC接收请求参数
java
Clarify1 小时前
docker部署go游戏服务器(进阶版)
后端
九圣残炎1 小时前
【从零开始的LeetCode-算法】3354. 使数组元素等于零
java·算法·leetcode
IT书架1 小时前
golang面试题
开发语言·后端·golang
天天扭码2 小时前
五天SpringCloud计划——DAY1之mybatis-plus的使用
java·spring cloud·mybatis
程序猿小柒2 小时前
leetcode hot100【LeetCode 4.寻找两个正序数组的中位数】java实现
java·算法·leetcode
机器之心2 小时前
全球十亿级轨迹点驱动,首个轨迹基础大模型来了
人工智能·后端
不爱学习的YY酱2 小时前
【操作系统不挂科】<CPU调度(13)>选择题(带答案与解析)
java·linux·前端·算法·操作系统