一、常用基础注解
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-注解开发-注解介绍的基础内容,感谢阅读。