Spring MVC-注解开发-注解介绍

零、本文纲要

  • 一、常用基础注解
  1. @Controller
  2. @RequestMapping
  3. @RequestParam
  4. @InitBinder
    4.1 补充:@DateTimeFormat
  5. @ControllerAdvice
  6. @RequestHeader
  7. @CookieValue
  8. @ModelAttribute
  9. @SessionAttribute和@SessionAttributes
  10. @ExceptionHandler
  • 二、JSON数据交互相关注解
  1. @RequestBody
  2. @ResponseBody
  • 三、Rest风格URL请求相关注解
  1. @PathVariable
  • 四、跨域访问
  1. @CrossOrigin
    1.1 补充:跨域访问

一、常用基础注解

1. @Controller

作用:此注解用用于修饰表现层控制器的注解

2. @RequestMapping

作用:用于建立请求URL和处理请求方法之间的对应关系

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {

    //给请求URL提供一个名称
    String name() default "";

    //用于指定请求的URL,在配置此属性时,写不写/都是可以的
    @AliasFor("path")
    String[] value() default {};

    //用于指定请求的URL,在配置此属性时,写不写/都是可以的
    @AliasFor("value")
    String[] path() default {};

    //method:用于指定请求的方式。
    //它支持RequestMethod枚举指定的:GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE这些类型
    RequestMethod[] method() default {};

    //用于指定限制请求参数的条件
    //例如:params = {"accountName"},表示请求参数必须有accountName
    String[] params() default {};

    //用于指定限制请求消息头的条件
    //例如:headers = "content-type=text/*"
    String[] headers() default {};

    //用于指定可以接收的请求正文类型
    //consumes = {"text/plain", "application/*"}
    String[] consumes() default {};

    //用于指定可以生成的响应正文类型
    //produces = {"text/plain", "application/*"}
    String[] produces() default {};

}

常见的衍生注解,用于Rest风格开发。如下:
Ⅰ @GetMapping
Ⅱ @PostMapping
Ⅲ @PutMapping
Ⅳ @DeleteMapping
Ⅴ @PatchMapping

3. @RequestParam

作用:此注解是从请求正文中获取请求参数,给控制器方法形参赋值的

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {

    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    //当为true时,参数没有值会报错;false则非必须
    boolean required() default true;

    //在参数没有值时的默认值
    String defaultValue() default ValueConstants.DEFAULT_NONE;

}

4. @InitBinder

作用:用于初始化表单请求参数的数据转换器,用于参数映射

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InitBinder {
    //用于指定给哪些参数做数据绑定,如果没有指定,则对所有参数生效
    String[] value() default {};

}

Ⅰ 使用案例

在对应的Controller类中添加如下代码:

//初始化数据转换器
@InitBinder(value = {"user", "product"})
public void dateBinder(WebDataBinder dataBinder){
    dataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
}

注意:此种使用方式仅对该Controller类内的方法起到转换绑定作用。
如需对所有Controller类的方法进行增强,可以配和@ControllerAdvice注解一起使用。

4.1 补充:@DateTimeFormat

作用:日期类型数据转换器,用于日期类型参数绑定

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
public @interface DateTimeFormat {
    //是国际标准的(short date, short time)格式
    //具体为:MM/dd/yyyy HH:mm 
    //如:5/15/2022 20:57
    String style() default "SS";

    //默认不指定,指定则覆盖style属性,默认提供了三种形式的ISO格式
    ISO iso() default ISO.NONE;

    //自定义日期属性
    String pattern() default "";

    //枚举指定ISO日期格式
    enum ISO {

        /**
         * The most common ISO Date Format {@code yyyy-MM-dd},
         * e.g. "2000-10-31".
         */
        DATE,

        /**
         * The most common ISO Time Format {@code HH:mm:ss.SSSXXX},
         * e.g. "01:30:00.000-05:00".
         */
        TIME,

        /**
         * The most common ISO DateTime Format {@code yyyy-MM-dd'T'HH:mm:ss.SSSXXX},
         * e.g. "2000-10-31T01:30:00.000-05:00".
         * <p>This is the default if no annotation value is specified.
         */
        DATE_TIME,

        /**
         * Indicates that no ISO-based format pattern should be applied.
         */
        NONE
    }

}

使用方式

Ⅰ 首先添加@EnableWebMvc注解

@Configuration
@ComponentScan("com.stone.controller")
@EnableWebMvc //开启Spring对注解MVC的支持
public class SpringMvcConfiguration implements WebMvcConfigurer {...}

Ⅱ 在需要绑定参数的属性上添加注解

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
private Date updateTime;

5. @ControllerAdvice

作用:用于给控制器提供一个增强的通知,以保证可以在多个控制器之间实现增强共享。

可以配合以下三个注解来用:
@InitBinder
@ExceptionHandler
@ModelAttribute

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
    
    //用于指定对哪些包下的控制器进行增强
    @AliasFor("basePackages")
    String[] value() default {};

    //用于指定对哪些包下的控制器进行增强
    @AliasFor("value")
    String[] basePackages() default {};

    //可以通过指定类的字节码的方式来指定增强作用范围
    Class<?>[] basePackageClasses() default {};

    //用于指定特定的类型提供增强
    Class<?>[] assignableTypes() default {};

    //用于指定给特定注解提供增强
    Class<? extends Annotation>[] annotations() default {};
}

使用方式

@ControllerAdvice注解不写其属性,则表示对所有的Controller类进行通知增强

@ControllerAdvice
public class InitBinderAdvice {
    @InitBinder("user")
    public void dateBinder(WebDataBinder dataBinder){
        dataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
    }
}

6. @RequestHeader

作用:此注解是从请求消息头中获取消息头的值,并把值赋给控制器方法形参

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestHeader {

    //用于指定请求消息头的名称
    @AliasFor("name")
    String value() default "";

    //用于指定请求消息头的名称
    @AliasFor("value")
    String name() default "";

    //用于指定是否必须有此消息头。当取默认值时,没有此消息头会报错
    boolean required() default true;

    //用于指定消息头的默认值
    String defaultValue() default ValueConstants.DEFAULT_NONE;
}

使用方法

@RequestMapping("/useRequestHeader")
public String useRequestHeader(@RequestHeader(value="Accept-Language", 
    required=false)String requestHeader){...}

7. @CookieValue

作用:此注解是从请求消息头中获取Cookie的值,并把值赋给控制器方法形参

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CookieValue {

    //用于指定cookie的名称
    @AliasFor("name")
    String value() default "";

    //用于指定cookie的名称
    @AliasFor("value")
    String name() default "";

    //用于指定是否必须有此消息头。当取默认值时,没有此消息头会报错
    boolean required() default true;

    //用于指定消息头的默认值
    String defaultValue() default ValueConstants.DEFAULT_NONE;
}

使用方式

@RequestMapping("/useCookieValue")
public String
useCookieValue(@CookieValue(value="JSESSIONID",
    required=false) String cookieValue){...}

8. @ModelAttribute

作用:它可以用于修饰方法,或者是参数;
当修饰方法时,表示【执行控制器方法之前】,被此注解修饰的方法都会执行;
当修饰参数时,用于获取指定的数据给参数赋值。

@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ModelAttribute {

    //当注解写在方法上,则表示存入时的名称。(值是方法的返回值)
    //当注解写在参数上,可以从ModelMap、Model、Map中的获取数据。(前提是之前存入过)
    //指定的是存入时的key
    @AliasFor("name")
    String value() default "";

    //和value的作用是一样的
    @AliasFor("value")
    String name() default "";

    //用于指定是否支持数据绑定
    boolean binding() default true;

}

使用方式

Model是spring提供的一个接口,该接口有一个实现类ExtendedModelMap。该类继承了ModelMap,而ModelMap就是LinkedHashMap子类。

//方式一:使用Model对象存储数据
@ModelAttribute
public void showModel(String username, Model model) {
    username = "prefix_" + username;
    model.addAttribute("username", username);
}

//方式二:通过返回值存储,需手动指定key
@ModelAttribute("username")
public String showModel(String username, Model model) {
    username = "prefix_" + username;
    return username;
}

//获取数据
@RequestMapping("/testModelAttribute")
public String testModelAttribute(@ModelAttribute("username") String username) {...}

使用场景:
由于此方法会在所有Controller方法执行之前执行,所以可以提前对获取到的参数做处理。
但是,也是因为所有的方法执行之前执行,使用的时候要【选择性的使用】。

9. @SessionAttribute和@SessionAttributes

作用:此注解是用于让开发者和ServletAPI进行解耦,让开发者可以无需使用HttpSession的getAttribute方法即可从会话域中获取数据。

注意:
没有使用此注解时,当我们在控制器方法形参中加入Model或者ModelMap类型参数时,默认是存入【请求域】的。
但当控制器上使用了此注解,就会往【会话域】中添加数据,【请求域】中仍然会存储。

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SessionAttribute {
    //用于指定在会话域中数据的名称
    @AliasFor("name")
    String value() default "";

    //用于指定在会话域中数据的名称
    @AliasFor("value")
    String name() default "";

    //用于指定是否必须从会话域中获取到数据。默认值是true,表示如果指定名称不存在会报错。
    boolean required() default true;
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface SessionAttributes {
    //指定可以存入会话域中的名称
    @AliasFor("names")
    String[] value() default {};

    //指定可以存入会话域中的名称
    @AliasFor("value")
    String[] names() default {};

    //指定可以存入会话域中的数据类型
    Class<?>[] types() default {};
}

使用方式

注意:
没有使用此注解时,当我们在控制器方法形参中加入Model或者ModelMap类型参数时,默认是存入【请求域】的。
但当控制器上使用了此注解,就会往【会话域】中添加数据,【请求域】中仍然会存储。
web的知识点:【会话域】存储的内容是会话共享的,而【请求域】中的内容仅当前请求有效。

@Controller
@SessionAttributes(value = {"username"})
public class SessionAttributesController{

    //把数据存入SessionAttribute
    @RequestMapping("/testPut")
    public void testPut(Model model){
        model.addAttribute("username", "泰斯特");
    }

    //获取数据
    @RequestMapping("/testGet")
    public void testGet(ModelMap model){
        model.get("username");
    }

    //清空 Spring MVC 的 Session ,同时清除对应键的 HttpSession 内容
    //但是通过request.getSession.setAttribute () 方式添加的内容不会被清除掉
    @RequestMapping("/testClean")
    public void complete(SessionStatus sessionStatus){
        //手动清除SessionAttributes
        sessionStatus.setComplete();
    }

    @RequestMapping("/testSessionAttribute")
    public void testSessionAttribute(@SessionAttribute("username")String username){
        ////已经被清除,无法获取username的值
        sout(username);
    }

}

注意:@SessionAttributes注解作用在类上,@SessionAttribute作用在请求参数位置,两者一般是配合使用的。

10. @ExceptionHandler

作用:用于注释方法,表明当前方法是控制器执行产生异常后的处理方法

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
    //指定用于需要捕获的异常类型
    Class<? extends Throwable>[] value() default {};
}

使用方法

通常配合@ControllerAdvice注解一起使用,表示对所有的Controller类生效。

@Slf4j
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@ResponseBody
public class GlobalExceptionHandler {
    /**
     * 异常处理方法
     * @param e 异常对象
     * @return 结果信息
     */
    @ExceptionHandler(Exception.class)
    public R<String> exceptionHandler(Exception e){
        log.info(e.getMessage());
        return R.error(e.getMessage());
    }
}

二、JSON数据交互相关注解

1. @RequestBody

作用:用于获取全部的请求体

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {
    //用于指定是否必须有请求体
    boolean required() default true;

}

使用方式

注意:默认接收到的JSON数据格式是字符串类型的,如果需要封装成指定类型需要用到第三方组件。

@RequestMapping("/useRequestBody")
public void useRequestBody(@RequestBody(required=false) String body){
    System.out.println(body);
}

使用第三方组件封装JSON字符串成指定类型,导入如下依赖:
Ⅰ jackson-core
Ⅱ jackson-databind
Ⅲ jackson-annotations

2. @ResponseBody

作用:用于用流输出响应正文

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {

}

使用方式

//方式一
@RequestMapping("useResponseBody")
public @ResponseBody String useResponseBody(String name){
    return "success";
}

//方式二
@RequestMapping("useResponseBody")
@ResponseBody
public String useResponseBody(String name){
    return "success";
}

//方式三
//直接写在Controller类上
//@RestController = @Controller + @ResponseBody

补充:@RestControllerAdvice = @ControllerAdvice + @ResponseBody

三、Rest风格URL请求相关注解

1. @PathVariable

作用:是springmvc框架支持rest风格url的标识,可以用于获取请求url映射中占位符对应的值。

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {
    //指定url映射中占位符的名称
    @AliasFor("name")
    String value() default "";

    //指定url映射中占位符的名称
    @AliasFor("value")
    String name() default "";

    //用于指定是否必须有此占位符。当取默认值时,没有会报错。
    boolean required() default true;
}

使用方式

@RequestMapping("/usePathVariable/{id}")
public void usePathVariable(@PathVariable("id") Integer id){
    sout(id);
}

四、跨域访问

1. @CrossOrigin

作用:此注解用于指定是否支持跨域访问

1.1 补充:跨域访问

发起请求的资源所在域不同于该请求所指向资源所在的域,包含:协议、主机、端口,此三个有任意一个不一致,则称为跨域访问。
但是,包括CSS、图片、JavaScript 脚本以及其它类资源,即使没有使用@CrossOrigin也能够被跨域访问加载。

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {

    @Deprecated
    String[] DEFAULT_ORIGINS = { "*" };

    @Deprecated
    String[] DEFAULT_ALLOWED_HEADERS = { "*" };

    @Deprecated
    boolean DEFAULT_ALLOW_CREDENTIALS = false;

    @Deprecated
    long DEFAULT_MAX_AGE = 1800;

    //"*"代表所有域的请求都支持
    @AliasFor("origins")
    String[] value() default {};

    //"*"代表所有域的请求都支持
    @AliasFor("value")
    String[] origins() default {};

    //允许请求头中的header,默认都支持
    String[] allowedHeaders() default {};

    //响应头中允许访问的header,默认为空
    String[] exposedHeaders() default {};

    //用于指定支持的HTTP请求方式列表
    RequestMethod[] methods() default {};

    //是否允许cookie随请求发送,使用时必须指定具体的域
    String allowCredentials() default "";

    //预请求的结果的有效期,默认值是:1800秒 (30分钟)
    long maxAge() default -1;

}

使用方式

@RestController
@CrossOrigin
public class CrossOriginController {
    @RequestMapping("/useCrossOrigin")
    public String useCrossOrigin() {
        return "success";
    }
}

五、结尾

以上即为Spring MVC-注解开发-注解介绍的基础内容,感谢阅读。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容