文章目录
Controller层常使用的注解
类位置
@Controller
@Controller定义一个Controller控制器
- 在Spring MVC 中,控制器Controller 负责
处理
由DispatcherServlet 分发的请求- 前端调用接口请求最先到达
DispatcherServlet
,DispatcherServlet 根据请求路径的url找对应的Controller控制器类 @Controller
的作用: 此时就是把这个类定义为控制器,DispatcherServlet 分发请求到这些控制器类中,找对应URL的控制器- 没有@Controller就不是控制器,请求就不会扫描这个类,就识别不到更不用说调用了
- 前端调用接口请求最先到达
- DispatcherServlet 把用户请求的数据经过
业务处理层
处理之后封装成一个Model
,然后再把该Model 返回给对应的View
进行展示- DispatcherServlet (分发) => Controller(调用) => Service(业务处理层) => Model(返回数据) => Controller(return) => View (前端展示)
- 在Spring MVC 中提供了一个非常简便的定义Controller控制器 的方法,你无需继承特定的类或实现特定的接口
- 只需使用
@Controller
标记一个类是Controller,这样的Controller 就能被外界访问到。
仅仅使用@Controller是不能算一个完整的控制器类的,只能说一半一半
- @Controller就只是一个干干净净的注解,不会出现
/root/usr
这样的URL - 完整的控制器要配合
@RequestMapping("/root")
这样的注解才完整,才能被请求的那个URL精确找到类所在位置
@Controller
@RequestMapping("/action")
public class ActionController {}
@RequestMapping
RequestMapping
是一个用来处理请求地址映射
的注解,可用于类或方法上。
用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
- 前端请求URL,被哪一个@RequestMapping匹配上了
- 这个@RequestMapping注解对应的类就会被用来处理这个请求
RequestMapping注解有
六个属性
[常用的只是value、method]
value
: 指定请求的实际地址,默认一个可以不写value;
//设置value的值和path的值具有同等的作用
@RequestMapping("/action")
@RequestMapping(path = "/action")
@RequestMapping(value = {"/hello", "/world", "/action"})
@RequestMapping("/action/{name}")
public String hello(@PathVariable("name") String username) {
// => /action/{name}配合@PathVariable使用
//如果username改成name与参数一致,@PathVariable可以不跟("name")
}
method
: 指定请求的method类型, GET、POST、PUT、DELETE等;
@RequestMapping(value="/action", method=RequestMethod.GET)
@RequestMapping(value="/action", method=RequestMethod.POST)
consumes
: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
- 只有当请求头中
Content-Type
的值与指定可消费(设置)的类型中有相同的时候,请求才会被匹配。 - 如果某个处理方法只允许接收JSON格式的请求数据,则可以通过设置consumes属性进行限定
@RequestMapping(value = "/pets", consumes="application/json")
public void addPet(@RequestBody Pet pet) {}
produces
: 它的作用是指定返回值类型,不但可以设置返回值类型还可以设定返回值的字符编码
- 仅当request请求头中的(Accept)类型中包含该指定类型才返回;
- 如果你想限定方法返回值的数据类型,则可以通过produes属性进行指定;
@RequestMapping(value="/add",produces= {
"application/json;charset=utf-8"
})
@ResponseBody//表示返回的值为字符串,不经过视图解析器
public User add(User user){
//如果不加ResponseBody只加了produces
//就会出现错误,因为不加ResponseBody的json返回值会经过视图解析器
//导致的结果就是:
//它以为你返回的这个数据是一个,以这个返回值为名称的html等前端页面文件,就会加载不了
}
- 一般来说这个属性不用
params
: 请求路径中必须携带的参数有哪些,如果没有请求参数就会出错400。
- 只有符合URL规则且有指定参数的请求才会映射到当前的方法上
@RequestMapping(value = "/demo",params = "token=123")
public String params(){
return "params handler";
}
http://localhost:8080/demo?token=123
headers
: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
//有个方法就要用到header的一个值,就要你请求头有这个值才行
@RequestMapping(value = "/demo",headers={
"context-type=text/plain","context-type=text/html"
})
public String header(){
return "headers handler";
}
细分还有@PostMapping、@GetMapping,格式差不多
@PostMapping("/wordTJBB")
@RestController
@RestController=@Controller+@ResponseBody
- 一个可以被扫描到的控制器且返回值不会经过视图解析器的json数据
@Api
@Api
使用在类上,表明是swagger资源
- @API拥有两个属性:value、tags
tags
–表示说明 => 用这一个就行了value
–也是说明,基本用tags替代description
–详细说明(已经弃用)
@Api(tags = {"标题名称"}, description = "说明")
public class WordPoiController{}
@Slf4j
@Slf4j是用作日志输出的,一般会在项目每个类的开头加入该注解
- 如果不写下面这段代码,并且想用log
- 就可以用@Slf4来代替;这样就省去这段很长的代码。
private final Logger logger = LoggerFactory.getLogger(当前类名.class);
@Slf4j
public class QueryBillController {
public String getBills() {
log.info("进入账单查询接口");
}
配合依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.12</version>
</dependency>
一个简单的log4j2.xml(配详细点的去网上找)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout charset="UTF-8" pattern="%d %highlight{[%-5p]} %style{%c}{cyan} : %m%n"/>
</Console>
<RollingFile name="File" fileName="log/dz/error.log"
filePattern="log/dz/%d{yyyy-MM-dd}-error-%i.log">
<Filters>
<ThresholdFilter level="ERROR"></ThresholdFilter>
</Filters>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="100M"></SizeBasedTriggeringPolicy>
</Policies>
<PatternLayout pattern="%d [%-5p] %c - %m%n"/>
</RollingFile>
</Appenders>
<Loggers>
<root level="info">
<AppenderRef ref="CONSOLE"/>
<AppenderRef ref="File"/>
</root>
</Loggers>
</configuration>
@RefreshScope
SpringCloud 使用 @RefreshScope注解,实现配置文件的动态加载。
经过@RefreshScope注解修饰的bean,将被RefreshScope进行代理
用来实现配置、实例热加载
,即当配置变更时可以在不重启应用的前提下刷新bean中相关的属性值。
-
修改配置文件后,不重启应用。
-
在需要读取配置文件的地方添加
@RefreshScope
注解 -
配合nacos等配置中心就可以随时修改刷新
-
然后在重新发送请求controller层,发现配置文件的更新已经生效了。
- 可以使用
@ConfigurationProperties(prefix = "egb.activity")
- 或
@Value("${egb.activity.ossBucketName:false}")
- 配置属性
- 可以使用
@ConfigurationProperties(prefix = "egb.activity")
@Component
@RefreshScope
public class ActivityProperties {
/**
* OSS存储桶 -> 配置在yml的egb.activity
*/
@Value("${egb.activity.ossBucketName:false}")
private String ossBucketName;
/**
* OSS请求地址 -> 配置在yml的egb.activity
*/
private String ossDownloadUrl;
}
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Scope("refresh")
@Documented
public @interface RefreshScope {
/**
* @see Scope#proxyMode()
* @return proxy mode
*/
ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
}
方法位置
@ResponseBody
@ResponseBody是作用于返回数据的时候,不是指请求开始的时候一定要json的参数
@ResponseBody的作用其实是将java对象转为json格式的数据。
- @responseBody注解的作用: 将controller的方法
返回的对象
通过适当的转换器转换为指定的格式之后,写入到response对象的body区
,通常用来返回JSON数据或者是XML数据。 注意
:在使用此注解之后不会再走视图处理器(不会去调用打开任何一个html文件),而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。注意
:在使用@RequestMapping
后,返回值通常解析为跳转路径
(打开新的html文件),但是加上@ResponseBody
后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中(返回数据,而不是返回新的页面)。
@ResponseBody
public RModel generateFile(){}
警告
: 这个是@ResponseBody
(控制返回数据),有一个相似的叫@RequestBody
是控制请求时的参数的
注意: @ResponseBody的底层逻辑
- 请求方法返回时,调用了fastjson等json转化工具,将String、Object、实体类等对象转化为json字符串,json字符串
序列化
为二进制,通过网络传输到目标位置,反序列化
为json字符串,供目标使用
@ApiOperation
swagger接口文档
- @ApiOperation(value = “接口说明”, httpMethod = “接口请求方式”, response = “接口返回参数类型”, notes = “接口发布说明”)
@ApiOperation(value = "导出统计报表")
@PostMapping("/wordTJBB")
public RModel getXZQDMByName(){
//一般用这一个就行了,如下图
//什么请求前面也有显示,什么参数点进去也可以看
}
@Before
@Before: 前置通知, 在方法执行之前执行
package com.spring.aop;
@Component
public class xxx{
public int add(int i, int j) {
int result = i + j;
return result;
}
}
@Aspect
@Component
public class LogProxy {
@Before("execution(public int com.spring.aop.*(int, int))")
public void beforMethod(JoinPoint point){
}
}
@After
@After: 后置通知, 在方法执行之后执行 。
package com.spring.aop;
@Component
public class xxx{
public int add(int i, int j) {
int result = i + j;
return result;
}
}
@Aspect
@Component
public class LogProxy {
@After("execution(public int com.spring.aop.*(int, int))")
public void afterMethod(JoinPoint point){
}
}
待更新
:
@GlobalTransactional
@Transactional
@Around
@Around注解可以用来在调用一个具体方法前和调用后来完成一些具体的任务。
变量位置
@Autowired
@Qualifier
@Resource
参数位置
@RequestBody
@RequestBody
的作用其实是将json格式的数据转为java对象
。
一个接受参数的位置只能出现一个
@RequestBody
,因为一个json格式可以包含无限的数据,没必要也不可以
在参数中出现多个@RequestBody注解
public RModel getFileUrl(@RequestBody String str){
//因为只有一个@RequestBody注解,所以参数名称就很随意了
//只要参数里有json格式的数据,而且json格式的也只会有一个
//有多个json的你也传不过来,直接报错
//被赋值到这个参数里
}
注意: @RequestBody的底层逻辑
- json字符串
序列化
为二进制,通过网络传输到目标位置,反序列化
为json字符串,@RequestBody再调用了fastjson等json转化工具,将json字符串转化为了指定类型的对象 => String、Object、自定义实体类,然后传到方法的参数中
@RequestParam
@RequestParam
:将请求参数绑定到你控制器的方法参数上(是springmvc中接收普通参数的注解)
注意
: 请不要老想着用@RequestParam
去接受json格式的数据
想用json的数据直接用@RequestBody
//如果想同时用json和普通的参数:
//URL用这样的请求格式:http://localhost:8080/test?name=123
//URL中拼接普通的参数 => 请求体中用contentType:"application/json"
//传json数据
- 语法:
@RequestParam(
value=”参数名”,required=”true/false”,defaultValue=””
)
value
:参数名required
:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。defaultValue
:默认参数值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,就使用默认值
@RequestMapping("test")
public ModelAndView test1(@RequestParam("name")String name){}
http://localhost:8080/test?name=123
@RequestParam
用来处理 Content-Type 为application/x-www-form-urlencoded
编码的内容,Content-Type默认为该属性。
再次警告
: 不要拿@RequestParam
注解去想着接受json的对象,他就是用来接受普通的参数的,想接受json可以使用@RequestBody
注解
@PathVariable
@NotNull 等校验注解
@NotNull 被注释的元素不能为null
@AssertTrue 被注释的元素必须为true
@AssertFalse 被注释的元素必须为false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max,min) 被注释的元素的大小必须在指定的范围内。
@Digits(integer,fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式。
@Email 被注释的元素必须是电子邮件地址
@Length 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串必须非空
@Range 被注释的元素必须在合适的范围内
@Valid
@PostMapping("/create")
public void create (@RequestBody @Valid User query) {
}
用于验证注解是否符合要求,直接加在变量User 之前,在变量中添加验证信息的要求,当不符合要求时就会在方法中返回message 的错误提示信息。
public class User {
private String id;
@NotBlank(message = "密码不能为空")
private String password;
}
@NotBlank
注解所指的 password 字段,表示验证密码不能为空,如果为空的话,上面 Controller 中的 create 方法会将message 中的"密码不能为空"返回。
限制 | 说明 |
---|---|
@Null | 限制只能为null |
@NotNull | 限制必须不为null |
@AssertFalse | 限制必须为false |
@AssertTrue | 限制必须为true |
@DecimalMax(value) | 限制必须为一个不大于指定值的数字 |
@DecimalMin(value) | 限制必须为一个不小于指定值的数字 |
@Digits(integer,fraction) | 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction |
@Future | 限制必须是一个将来的日期 |
@Max(value) | 限制必须为一个不大于指定值的数字 |
@Min(value) | 限制必须为一个不小于指定值的数字 |
@Past | 限制必须是一个过去的日期 |
@Pattern(value) | 限制必须符合指定的正则表达式 |
@Size(max,min) | 限制字符长度必须在min到max之间 |
@Past | 验证注解的元素值(日期类型)比当前时间早 |
@NotEmpty | 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) |
@NotBlank | 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格 |
验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式 |