常用注解 Mybatis @Param 在Mybatis代理模式的时候,用于传递各种参数的时候,给参数起别名
例子:
接口:
1 2 3 4 5 6 public interface EmpMapper { List<Emp> findByDeptnoAndSal (@Param("deptno") int deptno,@Param("sal") double sal) ; List<Emp> findByDeptnoAndSal4 (@Param("empa") Emp empa,@Param("empb") Emp empb) ; }
mapper映射文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="com.msb.mapper.EmpMapper" > <select id ="findByDeptnoAndSal" resultType ="emp" > </select > <select id ="findByDeptnoAndSal4" resultType ="emp" > select * from emp where deptno =#{param1.deptno} and sal >= #{param2.sal} </select > </mapper >
测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class Test1 { public static void main (String[] args) { SqlSession sqlSession = SqlSessionUtil.getSqlSession(true ); EmpMapper mapper = sqlSession.getMapper(EmpMapper.class); Emp emp = mapper.getByEmpno(7902 ); System.out.println(emp); List<Emp> emps2 = mapper.getByDeptnoAndSal(10 , 1500 ); for (Emp em:emps2) { System.out.println(em); } Emp condition=new Emp (); condition.setDeptno(10 ); condition.setSal(1500.0 ); List<Emp> emps3 = mapper.getByDeptnoAndSal2(condition); for (Emp em:emps3) { System.out.println(em); } Emp condition1=new Emp (); condition1.setDeptno(10 ); Emp condition2=new Emp (); condition2.setSal(1500.0 ); List<Emp> emps4 = mapper.getByDeptnoAndSal3(condition1,condition2); for (Emp em:emps4) { System.out.println(em); } sqlSession.close(); } }
@Select ,@Update ,@Insert,@Delete 1 2 3 4 5 6 7 8 9 10 11 public interface DeptMapper { Dept findDeptByDeptno (int deptno) ; @Select("select * from dept where deptno =#{deptno}") Dept findByDeptno (int deptno) ; @Update("update dept set dname =#{dname}, loc =#{loc} where deptno =#{deptno}") int updateDept (Dept dept) ; @Insert("insert into dept values(DEFAULT,#{dname},#{loc})") int addDept (Dept dept) ; @Delete("delete from dept where deptno =#{deptno}") int removeDept (int deptno) ; }
Spring @Component @Component注解的作用:简化了applicationContext.xml中对这个创建对象的配置 ,而创建对象这件事还是spring来管理。
帮我们构建对象,默认的名字就是类名的首字母小写: UserServiceImpl —-》 userServiceImpl
我们也可以指定对象的名字:通过传入参数的形式:@Component(“usi”)
需要注意的是,任何注解想要生效,必须对这个注解进行扫描:
注解在哪个包下?要想找到这些注解,需要将注解所在的包进行扫描:设置需要扫描的包,如果需要扫描多个包,包路径之间使用逗号分隔。并且需要在applicationContext.xml中添加context命名空间(每个命名空间需要添加三行)。顺序不能乱,中间不能间隔。context命名空间去spring文档中找,随便粘贴一个过来改一改就行
1 2 3 4 5 6 7 8 9 10 11 12 13 <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:context ="http://www.springframework.org/schema/context" xsi:schemaLocation ="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd" > <context:component-scan base-package ="com.msb.service,com.msb.mapper" > </context:component-scan > </beans >
@Component注解的子注解 下面@Repository、@Service、@Controller、@Configuration都是@Component注解的子注解,作用相同:创建对象。主要的区别是语义上的区别,不同的注解放在不同层的类中。但是不按照语义去做,非把@Service用在持久层,也是有效果的。但是这样却是不规范的。
注解名称
解释
@Component
实例化Bean,默认名称为类名收字母变小写。支持自定义名称
@Repository
@Component子标签。作用和@Component一样。用在持久层
@Service
@Component子标签。作用和@Component一样。用在业务层
@Controller
@Component子标签。作用和@Component一样。用在控制器层
@Configuration
@Component子标签。作用和@Component一样。用在配置类上,以后结合SpringBoot使用。
属性注入相关的注解
注解名称
解释
@Autowired
自动注入。默认byType,如果多个同类型bean,使用byName。spring的注解。
@Resource
非Spring注解。默认byName,如果没找到,使用byType。JDK中javax包的注解,一般不用,用spring的注解
@Value
给普通数据类型(八种基本数据类型+String)属性赋值。spring的注解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Service("usi") public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; }
普通数据类型的属性的赋值 @Value注解 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Component public class Person { @Value("18") private int age; @Value("lili") private String name; @Override public String toString () { return "Person{" + "age=" + age + ", name='" + name + '\'' + '}' ; } }
在applicationContext.xml中配置扫描注解所在的包:
1 2 3 4 5 6 7 8 9 10 11 12 13 <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:context ="http://www.springframework.org/schema/context" xsi:schemaLocation ="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd" > <context:component-scan base-package ="com.msb.test" > </context:component-scan > </beans >
但是上面的写法,将属性值写死了,我们一般不这样用,我们都是配合属性文件来使用,@Value
最大的作用就是读取配置文件,后续配合配置中心(如Nacos)来使用,现在先学习用法即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:context ="http://www.springframework.org/schema/context" xsi:schemaLocation ="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd" > <context:component-scan base-package ="com.msb.service,com.msb.mapper,com.msb.test" > </context:component-scan > <context:property-placeholder location ="classpath:a.properties" > </context:property-placeholder > </beans >
@RunWith() // RunWith、ContextConfiguration这些注解不用扫描,@RunWith就会自动去构建测试类对象 @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration() // 启动时加载的配置文件,里面要包含classpath
@ContextConfiguration(locations = “classpath:applicationContext.xml”)
@Transactional() 可以通过参数配置注解。
1 Transactional(propagation=Propagation.REQUIRED)
Service 方法上在需要添加事务的方法上加入事务注解,如需配置属性在参数位置设置即可
PS:如果很多方法都需要事务处理,那么可以直接将这个注解放在类上,代表这个类的所有方法都被事务管控。
@CrossOrigin Spring Framework 4.2 GA为CORS提供了第一类支持,使您比通常的基于过滤器的解决方案更容易和更强大地配置它。所以springMVC的版本要在4.2或以上版本才支持@CrossOrigin
你可以向@RequestMapping注解处理程序方法添加一个@CrossOrigin注解,以便启用CORS(默认情况下,@CrossOrigin允许在@RequestMapping注解中指定的所有源和HTTP方法):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @RestController @RequestMapping("/account") public class AccountController { @CrossOrigin @GetMapping("/{id}") public Account retrieve (@PathVariable Long id) { } @DeleteMapping("/{id}") public void remove (@PathVariable Long id) { } }
其中@CrossOrigin中的2个参数:origins: 允许可访问的域列表、maxAge:准备响应前的缓存持续的最大时间(以秒为单位)。 为整个controller启用@CrossOrigin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @CrossOrigin(origins = "http://domain2.com", maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController { @GetMapping("/{id}") public Account retrieve (@PathVariable Long id) { } @DeleteMapping("/{id}") public void remove (@PathVariable Long id) { } }
在这个例子中,对于retrieve()和remove()处理方法都启用了跨域支持,还可以看到如何使用@CrossOrigin属性定制CORS配置。
SpringMVC @Controller 放入到Spring MVC容器中
@RequestMapping() @RequestMapping(value={“/first2”,”/first02”})
在Spring MVC中支持Ant风格的映射路径写法。所谓的Ant风格就是支持三种特殊的符号:
符号
解释
?
匹配任意单字符
*
匹配0或者任意数量的字符
**
匹配0或者更多数量的目录
简写方式 Spring MVC 框架针对不同请求方式提供了5个专门请求方式的注解
@PostMapping(“/first”)
等效于 @RequestMapping(value = “/first”,method = RequestMethod.POST)
@GetMapping(“/first”)
等效于 @RequestMapping(value = “/first”,method = RequestMethod.GET)
@DeleteMapping(“/first”)
等效于 @RequestMapping(value = “/first”,method = RequestMethod.DELETE)
@PutMapping(“/first”)
等效于 @RequestMapping(value = “/first”,method = RequestMethod.PUT)
@PatchMapping(“/first”)
等效于 @RequestMapping(value = “/first”,method = RequestMethod.PATCH)
params属性 params属性类型是String[],表示请求中必须包含指定名称的请求参数。
1 2 3 4 @RequestMapping(value="/testParam",params = {"name"}) public String testParam () { return "/first.jsp" ; }
headers属性类型是String[],表示请求头中必须包含指定的请求头参数。
1 2 3 4 @RequestMapping(value="/testHeaders",headers = "Cookie11") public String testHeaders () { return "/first.jsp" ; }
@RequestParam 注解的使用 1)name:当请求参数名和控制单元参数名不对应时,可以使用name指定请求参数名。这样方法参数就可以不与请求参数对应了。
1 2 3 4 5 6 7 8 9 @Controller public class MyController { @RequestMapping("/testParam1") public String testParam1 (@RequestParam(name="name") String username) { System.out.println(username); return "/index.jsp" ; } }
含义:接收前台名字为name的参数的值赋值给username参数。
如访问: http://localhost:8080/demo01/testParam1?name=zs后台即可接受到。
(2)value:是name属性的别名。功能和name属性相同。之所以再次设置一个和name属性相同的value,是因为在Java注解中,当需要设置value属性,且只需要设置value属性时可以省略value属性名,这样写起来更加简单。
下面代码和上面(1)中的代码完全相同
1 2 3 4 5 6 7 8 @Controller public class MyController { @RequestMapping("/testParam1") public String testParam1 (@RequestParam("name") String username) { System.out.println(username); return "/index.jsp" ; } }
(3)defaultValue:默认值。表示当请求参数中没有这个参数时给与的默认值。
1 2 3 4 5 @RequestMapping("/testParam2") public String testParam2 (@RequestParam(defaultValue="lili") String name,@RequestParam(defaultValue = "18") Integer age) { System.out.println(name + "----" + age); return "/index.jsp" ; }
在浏览器地址栏输入:http://localhost:8080/demo01/testParam2 会在控制台打印:
(4)required:boolean类型,表示请求中是否必须包含参数。
1 2 3 4 5 @RequestMapping("/testParam3") public String testParam3 (@RequestParam(required = true) String name) { System.out.println(name); return "/index.jsp" ; }
(2)在使用List进行接收时,必须在参数前面添加@RequestParam注解,注解中内容就是请求参数名
1 2 3 4 5 @RequestMapping("/testParam5") public String testParam5 (@RequestParam("hobby") List hobbies) { System.out.println(hobbies); return "/index.jsp" ; }
使用@DateTimeFormat自定义时间格式,定义前端要传过来的格式。
控制单元:
1 2 3 4 5 @RequestMapping("/test7") public String test7 (@DateTimeFormat(pattern = "yyyy-MM-dd") java.util.Date date) { System.out.println(date); return "/index.jsp" ; }
访问:http://localhost:8080/demo01/test7?date=2022-5-6即可。
小提示:
需要注意的是,当使用了@DateTimeFormat以后默认的时间格式就不能使用了。
如果你传过来的Date是要给对象的,那么@DateTimeFormat也可以写在JavaBean的属性上面。
在HTTP协议中,请求头参数会有很多。如果希望接收请求头数据可以使用@RequestHeader进行接收。
1 2 3 4 5 @RequestMapping("/test10") public String test10 (@RequestHeader String Accept) { System.out.println(Accept); return "/index.jsp" ; }
@ResponseBody注解 该注解用于将 控制单元 的方法返回的对象,通过适当的 转换器转换为指定格式后,写入到 Response 对象的 body 数据区。
返回的数据不是 html 标签的页面,而是其他某种格式的数据时(如普通文本、 json、xml 等)使用(通常用于ajax 请求 )。
@ResponseBody注解是类或方法级注解。
直接在方法上添加上@ResponseBody,Spring MVC会把返回值设置到响应流中。
1 2 3 4 5 @RequestMapping("/demo1") @ResponseBody public String demo1 () { return "msbyjx" ; }
很明显text/html;charset=ISO-8859-1中编码是不支持中文的。所以返回值中包含中文,打印在浏览器中会出现乱码。
想要改变@ResonseBody注解的响应内容类型(Content-Type)只能通过@RequestMapping的produces属性进行设置。
1 2 3 4 5 @RequestMapping(value="/demo1",produces = "text/html;charset=utf-8") @ResponseBody public String demo1 () { return "作为msbyjx" ; }
响应json数据 @ResponseBody注解可以把控制单元返回值自动转换为json格式的数据(json对象)。
主要完成下面几个事情:
(1)判断返回值是否为JavaBean、JavaBean数组、List、Map等满足键值对的类型。
(2)如果满足键值对类型,会使用Jackson把对象转换为JSON数据,设置到响应流中。同时会设置响应内容类型(Content-Type)为application/json;charset=utf-8
因为Spring MVC默认使用Jackson作为JSON转换工具,把java对象进行json转化,所以必须保证项目中存在Jackson的依赖,在pom.xml中加入下面依赖:
1 2 3 4 5 <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-databind</artifactId > <version > 2.15.2</version > </dependency >
案例:返回值是否为JavaBean类型,会使用Jackson把对象转换为JSON数据
编写javabean:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package com.msb.pojo;import java.util.Date;public class Student { private int id; private String name; private Date date; public Student () { } public int getId () { return id; } public void setId (int id) { this .id = id; } public String getName () { return name; } public void setName (String name) { this .name = name; } public Date getDate () { return date; } public void setDate (Date date) { this .date = date; } }
在控制类中编写控制单元。
1 2 3 4 5 6 7 8 9 @RequestMapping(value="/demo2") @ResponseBody public Student demo2 () { Student s = new Student (); s.setId(17 ); s.setName("丽丽" ); s.setDate(new Date ()); return s; }
@RestController @RestController = @Controller + @ResponseBody
当类上使用的是@RestController而不是@Controller时,控制单元方法不再需要写@ResponseBody(也不能写@ResponseBody),Spring MVC在解析控制单元方法时会自动带有@ResponseBody注解。
所以:@RestController写起来更加简单了。
但是需要注意:
一旦类上使用了@RestController,所有控制单元返回都是普通文本或XML或JSON数据,而无法实现页面跳转功能了。
所以:只要类中有一个方法是希望实现页面跳转功能,类上就不能使用@RestController。只有类中所有的方法都是返回普通文本或JSON或XML的情况才能使用@RestController注解。
@RequestBody注解 @RequestBody注解底层依赖的依然是Jackson工具包,其作用是把客户端传递过来的请求体中JSON或XML数据转换为Map、类、List<类>、List等类型。或者我们需要的参数是对象就在对象前加入这个注解。
使用@RequestBody注解需要导入依赖:
1 2 3 4 5 <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-databind</artifactId > <version > 2.15.2</version > </dependency >
@PathVariable 1 2 3 4 5 6 7 8 9 10 11 @Controller public class MyController5 { @RequestMapping(value="/user/{id}") public User selectOneUser (@PathVariable Integer id) { User user = new User (); return user; } }
HTTP协议中支持很多种请求方式,除了GET和POST还有PUT和DELETE等,restful中要求使用不同的请求方式来标记对资源的操作方式,达到调用不同的后台功能方法来处理请求的目的。
具体的请求方式根据接口对资源的操作决定,增post 删delete 改put 查get
1 2 3 4 5 6 在 Restful 风格中,现有规定如下: GET(SELECT):从服务器查询,可以在服务器通过请求的参数区分查询的方式。 POST(CREATE):在服务器端新建一个资源,调用 insert 操作。 PUT(UPDATE):在服务器端更新资源,调用 update 操作。 PATCH(UPDATE):在服务器端更新资源(客户端提供改变的属性)。(目前 jdk7 未实现,tomcat7不支持)。 DELETE(DELETE):从服务器端删除资源,调用 delete 语句。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @GetMapping("/user/{id}") public String selUser (@PathVariable Integer id) { System.out.println("用户ID为:" +id); return "/success.jsp" ; } @DeleteMapping("/user/{id}") public String delUser (@PathVariable Integer id) { System.out.println("用户ID为:" +id); return "/success.jsp" ; } @PostMapping("/user/{id}/{name}/{age}") public String addUser (@PathVariable Integer id,@PathVariable String name,@PathVariable Integer age) { System.out.println("id = " + id + ", name = " + name + ", age = " + age); return "/success.jsp" ; } @PutMapping("/user/{id}/{name}") public String updateUser (@PathVariable Integer id,@PathVariable String name) { System.out.println("id = " + id + ", name = " + name); return "/success.jsp" ; }
这样请求方式+路径参数即可确定要访问的具体的控制单元。
@ExceptionHandler 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Controller public class MyController9 { @RequestMapping(value="/testexcep") public String testexcep () throws IOException { System.out.println("进入控制单元testexcep" ); int num = 10 / 0 ; return "/index.jsp" ; } @ExceptionHandler(value = {ArithmeticException.class, NullPointerException.class}) public String myexception () { return "redirect:/error.jsp" ; } }
上面的方式,配置在控制器类中,只有当前这个控制器类的控制单元出现异常时才能执行,其他类的控制单元出现异常不能执行。
每个控制器类中可以有多个处理异常的方法,每个方法上面只需要有@ExceptionHandler,千万别添加了@RequestMapping注解。
@ControllerAdvice 全局配置方式,对所有控制单元的所有方法都生效。因为@ControllerAdvice已经继承了@Component注解,所以类上只添加这个注解就可以了。
不需要在添加@Controller注解了。
1 2 3 4 5 6 7 @ControllerAdvice public class MyExceptionController { @ExceptionHandler(value = ArithmeticException.class) public String myexception () { return "/error.jsp" ; } }
小提示:
如果配置了局部异常处理器和全局异常处理器,优先匹配局部异常处理器。
SpringDoc @Tag 1 2 @Tag :作用-用在请求的类上,说明该类的作用 配置参数name="该类对应的模块名字 " tags="说明该类的作用,对模块进行描述"
1 @Tag(name = "用户模块管理", description = "用户接口")
@Operation 1 2 @Operation:作用-用在请求的方法上,说明方法的作用 配置参数summary="说明方法的作用"
1 @Operation(summary="用户模块-根据用户id查询用户信息")
@Parameters 1 2 3 4 5 6 @Parameters :作用-用在请求的方法上,对请求的参数(方法的形参)进行说明,是一个复合注解,里面包含了多个@Parameter 子注解。 @Parameter :用在 @Parameters 注解中,指定一个请求参数的配置信息 注解的属性介绍:(配置参数) name:参数名 value:参数的汉字说明、解释 required :参数是否必须传
如果方法是一个参数,可以直接使用@Parameter注解:
1 2 3 4 @Parameter(name="uid",description ="查询参数用户id",required = true) public User select (@PathVariable Integer uid) { return userService.findOneUser(uid); }
如果多个参数,可以使用@Parameters,如:
1 2 3 4 5 @Parameters({ @Parameter(name="mobile",description="手机号",required=true), @Parameter(name="password",description="密码",required=true), @Parameter(name="age",description="年龄",required=true) })
@ApiResponses 1 2 3 4 5 @ApiResponses :用于请求的方法上,表示一组响应,,是一个复合注解,里面包含了多个@ApiResponse 子注解。 @ApiResponse :用在@ApiResponses 中,一般用于表达一个错误的响应信息 code:数字,例如400 message:信息,例如"请求参数没填好" response:抛出异常的类
1 2 3 4 @ApiResponses ({ @ApiResponse (code=400, message="请求参数没填好" ), @ApiResponse(code=404 , message="请求路径没有或页面跳转路径不对" ) })
@Schema 用在模型类上,对模型类做注释; 用在属性上,对属性做注释 ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package com.msb.pojo; import io.swagger.v3.oas.annotations.media.Schema;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@NoArgsConstructor @AllArgsConstructor @Data @Schema (description = "用户实体类" )public class User { @Schema (description = "用户id主键" ) private Integer uid; @Schema (description = "用户名字" ) private String uname; @Schema (description = "账户密码" ) private String pwd; @Schema (description = "真实名字" ) private String realname; @Schema (description = "身份标识" ) private Integer identity; }
SpringBoot事务控制 @Transactional(propagation= Propagation.REQUIRED) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override @Transactional(propagation= Propagation.REQUIRED) public int deleteUserById (Integer uid) { int num = userMapper.delete(uid); int a = 1 /0 ; return num; } }
启动服务器,测试,发现程序报错,数据库数据没有被删除,证明事务加入成功,非常简单的操作!在service层每个增删改方法前都加入@Transactional(propagation = Propagation.REQUIRED)注解即可。
SpringBoot异常处理 @ExceptionHandler 实现局部异常处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Controller public class MyController { @RequestMapping("/test1") @ResponseBody public String test01 () { System.out.println("test1---" ); int a = 1 /0 ; return "test01" ; } @ExceptionHandler(value = {java.lang.ArithmeticException.class}) public String myexceptionhandler () { System.out.println("异常处理逻辑代码。。" ); return "myerror" ; } }
上面这种处理方式属于局部处理方式,只对当前MyController控制单元中的异常生效,所以我们需要加入全局异常处理:
@ControllerAdvice、@ExceptionHandler实现全局异常处理 创建com.msb.exceptionhandler包,加入异常处理类,使用@ControllerAdvice、@ExceptionHandler注解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package com.msb.exceptionhandler;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(value = {java.lang.ArithmeticException.class}) public String myexceptionhandler () { System.out.println("异常处理逻辑代码。。" ); return "myerror" ; } }
重启服务器访问发现:这样不同的控制单元都可以处理异常了
@Configuration,@Bean 1 2 3 4 5 6 7 8 9 10 11 @Configuration public class GlobalExceptionHandler2 { @Bean public SimpleMappingExceptionResolver getSME () { SimpleMappingExceptionResolver sme = new SimpleMappingExceptionResolver (); Properties p = new Properties (); p.put("java.lang.ArithmeticException" ,"myerror" ); sme.setExceptionMappings(p); return sme; } }
上面的配置类等效之前的xml配置:
SpringBoot数据校验validation validation校验相关的注解
注解
功能
@AssertFalse
可以为null,如果不为null的话必须为false
@AssertTrue
可以为null,如果不为null的话必须为true
@DecimalMax
设置不能超过最大值
@DecimalMin
设置不能超过最小值
@Digits
设置必须是数字且数字整数的位数和小数的位数必须在指定范围内
@Future
日期必须在当前日期的未来
@Past
日期必须在当前日期的过去
@Max
最大不得超过此最大值
@Min
最大不得小于此最小值
@NotNull
不能为null,可以是空
@Min
最大不得小于此最小值
@Pattern
必须满足指定的正则表达式
@Size
集合、数组、map等的size()值必须在指定范围内
@Email
必须是email格式
@Length
长度必须在指定范围内
@NotBlank
字符串不能为null,字符串trim()后也不能等于“”
@NotEmpty
不能为null,集合、数组、map等size()不能为0;字符串trim()后可以等于“”
@Range
值必须在指定范围内
@URL
必须是一个URL
校验注解的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 public class User { @NotBlank(message = "用户名不能为空!") private String userName; @NotBlank(message = "用户密码不能为空!") @Length(min = 6, max = 10,message = "密码长度至少6位但不超过10位!") private String userPwd; }
校验注解配置好了,如何在校验环境生效呢?需要结合下面的接口方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package com.msb.controller;import com.msb.pojo.User;import jakarta.validation.Valid;import org.springframework.web.bind.annotation.*;@RestController public class MyController { @PostMapping("/user") public int save (@RequestBody @Valid User user) { System.out.println("进入save方法" ); return 0 ; } }
SpringBoot的Bean管理 @Configuration和@Bean 1 2 3 4 5 6 7 8 9 10 11 12 13 @Configuration public class MyConfig { @Bean("s") public Student getStudent () { Student s = new Student (); s.setId(1 ); s.setName("zs" ); return s; } }
@Qualifier 1 2 3 4 5 6 7 8 9 10 11 12 @SpringBootTest class SpringBootM10ApplicationTests { @Autowired @Qualifier("s2") private Student stu; @Test void contextLoads () { System.out.println(stu); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @Configuration public class MyConfig { @Bean("s2") public Student getStudent2 (Clazz c) { Student s = new Student (); s.setId(2 ); s.setName("ls" ); s.setC(c); return s; } @Bean("cla") public Clazz getCla () { Clazz c = new Clazz (); c.setId(1 ); c.setName("java406班" ); return c; } @Bean("cla2") public Clazz getCla () { Clazz c = new Clazz (); c.setId(1001 ); c.setName("java班级" ); return c; } }
MyBatis-Plus @TableName(),@TableField() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @NoArgsConstructor @AllArgsConstructor @Data @TableName("t_user") public class User { @TableField(exist = false) private Integer a; @TableField("uid") private Integer id; private String uname; private String pwd; private String realname; private Integer identity; }
SpringBoot实现SpringAOP 1、aop切面
1 2 3 4 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-aop</artifactId > </dependency >
2、在主类上加上
1 @EnableAspectJAutoProxy(exposeProxy = true)
加上之后可以获取当前类的代理对象
开启Spring AOP代理的创建 :使得Spring容器中的所有bean都能被AOP代理。
@RestControllerAdvice 是一个复合注解,它是 @ControllerAdvice 和 @ResponseBody 的结合体。
@ControllerAdvice:该注解的作用是为所有的 @RequestMapping 处理方法提供通用的异常处理和数据绑定等增强功能。 @ResponseBody:该注解的作用是将响应格式从对象转换为JSON格式返回。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @RestControllerAdvice @Slf4j public class GlobalExceptionHandler { @ExceptionHandler(BusinessException.class) public BaseResponse<?> businessExceptionHandler(BusinessException e) { log.error("business error:{}" , e.getMessage()); return ResultUtils.error(e.getCode(), e.getMessage()); } @ExceptionHandler(RuntimeException.class) public BaseResponse<?> runtimeExceptionHandler(RuntimeException e) { log.error("RuntimeException" , e); return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "系统错误" ); } }
Dubbo-Cloud @Refrence @Reference 是 Dubbo 框架中的一个注解,用于注入远程服务的引用。在分布式系统中,服务消费者通过 RPC(远程过程调用)方式与服务提供者进行通信。@Reference 注解可以帮助服务消费者获取服务提供者的实例,并调用其方法。
@EnableDiscoveryClient @EnableDiscoveryClient和@EnableEurekaClient共同点就是:都是能够让注册中心能够发现,扫描到改服务。
记得配置扫包路径
不同点:@EnableEurekaClient只适用于Eureka作为注册中心,@EnableDiscoveryClient 可以是其他注册中心。
SpringSecurity @Secured 通常用于放在控制器方法上,专门用于判断是否具有角色的,参数要以ROLE_开头
理解 @PreAuthorize 和 @PostAuthorize 注解 @PreAuthorize
和 @PostAuthorize
是 Spring Security 提供的两种方法级安全注解,用于在方法调用前后进行权限验证。
@PreAuthorize 详解 @PreAuthorize
表示在方法执行前 进行权限检查,只有通过检查的方法才会被执行。这是最常用的安全注解。
特点:
执行时机 :方法调用前进行权限验证
常用性 :大多数情况下使用这个注解就足够了
参数 :接受一个 SpEL (Spring Expression Language) 表达式
表达式示例: 1 2 3 4 5 6 7 8 @PreAuthorize("hasRole('ADMIN')") // 必须有ADMIN角色才能访问 public void adminMethod() {...} @PreAuthorize("hasPermission(#id, 'read')") // 必须有对指定ID的read权限 public void readData(Long id) {...} @PreAuthorize("#user.name == authentication.name") // 只能操作自己的用户数据 public void updateUser(User user) {...}
@PostAuthorize 详解 @PostAuthorize
表示在方法执行后 进行权限检查,可以基于方法返回值进行验证。
特点:
执行时机 :方法执行后进行权限验证
使用场景 :需要基于返回结果进行验证的情况
参数 :同样接受 SpEL 表达式,可以引用返回值
表达式示例: 1 2 @PostAuthorize("returnObject.owner == authentication.name") // 只能返回属于自己的对象 public Data getData() {...}
与 access() 方法的关系 在 Spring Security 配置中,access()
方法也用于权限控制,如:
1 .antMatchers("/admin/**").access("hasRole('ADMIN')")
@PreAuthorize
和 @PostAuthorize
的参数与 access()
方法参数取值相同,都是使用 SpEL 表达式,支持相同的安全表达式如:
hasRole('ROLE')
hasAuthority('AUTH')
hasPermission(target, permission)
principal
, authentication
等内置对象
启用方法安全 要使用这些注解,需要在配置类上添加 @EnableGlobalMethodSecurity
:
1 2 3 4 5 @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { // ... }
SpringCloud Euraka @EnableDiscoveryClient 代表我当前这个微服务是一个服务的消费者 调用别的服务
@EnableEurekaServer 代表我们当前这个springboot的项目 作为一个服务注册中心
@EnableEurekaClient 代表我们这个项目是作为服务的提供者,根据配置会注册到注册中心上
Feign @EnableFeignClients 代表这个项目是可以通过Feign来调用远端的服务的项目
@FeignClient 这个在接口上添加注解,代表这个接口调用的远端的服务的地址
@FeignClient(name = “ldx-order”,fallback = OrderApiClientFallBack.class)