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("服务器繁忙,请稍后重试");
    }

}
相关推荐
一只叫煤球的猫5 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
bobz9655 小时前
tcp/ip 中的多路复用
后端
bobz9655 小时前
tls ingress 简单记录
后端
皮皮林5516 小时前
IDEA 源码阅读利器,你居然还不会?
java·intellij idea
你的人类朋友6 小时前
什么是OpenSSL
后端·安全·程序员
bobz9657 小时前
mcp 直接操作浏览器
后端
前端小张同学9 小时前
服务器部署 gitlab 占用空间太大怎么办,优化思路。
后端
databook9 小时前
Manim实现闪光轨迹特效
后端·python·动效
武子康10 小时前
大数据-98 Spark 从 DStream 到 Structured Streaming:Spark 实时计算的演进
大数据·后端·spark
该用户已不存在10 小时前
6个值得收藏的.NET ORM 框架
前端·后端·.net