-
在所有执行http请求之前,记录http请求的url,method,ip,类方法,参数
查看全部 -
用logger的方式打印日志
查看全部 -
pointcut 定义在公用的log()上
查看全部 -
提取公用部分
查看全部 -
AOP统一处理请求日志
查看全部 -
pop oop
查看全部 -
跳过测试打包
查看全部 -
批量测试结果
查看全部 -
SpringBoot应用创建
使用ideal 中的springboot插件
访问https://start.spring.io
根据网站的指引创建好工程,然后打包下载,最后导入ideal/eclipse
SpringBoot应用启动
a. ideal直接点运行按钮
b. 到项目跟路径,运行命令 mvn spring-boot:run
b. 首先打包 mvn clean package , 然后运行生成的jar文件 java -jar ./target/xxx.jar
项目部署时使用这种方式
自定义配置属性
定义我们的配置
application.properties
server.port=8080
server.servlet.context-path=/luckymoney
application.yml
server:
port: 8080
servlet:
context-path: /luckymoney
limit:
minMoney: 1
maxMoney: 999
description: 最少发${limit.minMoney}元
读取我们的自定义配置到程序中
单一配置直接使用 @Value("${param name}")
public class MyController {
@Value("${limit.minMoney}")
private BigDecmal minMoney;
// ...
}
如果是很多的配置且配置之间有一定关系,我们可以使用配置类, 针对上面limit下的配置
limit下面是一组相关的配置可以看做一个类里面的成员属性
@Component
@ConfigurationProperties(prefix="limit") // 指定要加载配置的前缀
public class LimitConfig { // 然后在其它类中注入该类就可以
// 属性名称和配置名称一致
private BigDecimal minMoney;
private BigDecimal maxMoney;
private String description;
// getter/setter
}
加载不同的配置 application-{profiles}.properties
有以下几个配置文件,其中2个对应开发、生产配置文件
application.yml
spring:
profiles:
active: dev
application-dev.yml
application-prod.yml
除了在application.yml中使用 spring.profiles.active=dev 指定要加载配置的后缀外
还可以在项目打包成jar后启动时在命令行带入参数来指定要加载的配置文件的后缀
mvn clean package
java -jar -Dspring.profiles.active=prod xxx.jar -Dspring.profiles.active=prod指定要加载的配置文件的后缀
Controller使用
@Controller + @ResponseBody = @RestController 后面一个注解的作用等于使用前面2个注解
@GetMapping/@PostMapping/@RequestMapping
@GetMapping({"hello","hi"}) - 多个访问地址对应一个方法,更多属性使用提示去看 ...
@PathVariable/@RequestParam
ClassName
@GetMapping("/hello/{id}")
method(@PathVariable("id") Integer id){...}
ClassName
@GetMapping("/hello")
method(@RequestMapping(value="id",required=false,defaultValue="0") Integer mid){...}
spring-data-jpa
jpa持久化接口标准,实现这一接口的有Hibernate/TopLink
红包小案例
RESTful API设计 (案例来源慕课网)
GET /luckymoneys 获取红包列表
POST /luckymoneys 创建一个红包
GET /luckymoneys/{id} 通过ID查询红包
PUT /luckymoneys/{id} 通过ID更新红包
引入2个依赖, springboot已经为我们指定了版本, 需要在引入时指定版本
groupId: org.springframework.boot
artifactId: spring-boot-starter-data-jpa
groupId: mysql
artifactId: mysql-connector-java
写配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/luckymoney
username:root
password:XXX
jpa:
hibernate:
ddl-auto: update
show-sql: true
@Entity
public class Luckymoney {
@Id // 主键
@GenerateValue // 自增长
private Integer id;
private BigDecimal money;
private String producer;
private String consumer;
// constructor
// getter/setter
}
Controller
Dao
// JpaRepository<数据库表实体类, 主键数据类型> , 只要接口
public interface XxxRepository extends JpaRepository<Luckymoney,Integer> {
// ...
}
事务管理
首先需要明确的是事务指的是数据库的事务不是程序的功能,事务是数据库提供的能力,springboot只是
对数据库的事务操作做了统一处理,因为事务的处理都是固定的、重复
@Transactional 用于开启springboot的事务管理,可以用在类、方法上
表单验证
@Valid BindingResult ; BindingResult - 用于接收参数校验结果 ; @Valid 加在被校验的参数上面
以及在实体类加入的一些校验注解: @Min ... ; 实体类的属性上面加上一些校验注解,用于对前端传入的参数做校验
XxxController
method(@Valid MyEntity entity, BindingResult bindingResult){...}
AOP 编程
误区:AOP 编程不是只在java里面提出来的,AOP 是一种编程范式
// 以记录日志为例,某个方法调用前和调用后需要记录日志
@Component
@Aspect
public class MyAspect {
@Pointcut("execution(public * com.**.MyController.*(..)") // MyController中所有方法都加上日志记录
public void log(){}
// 当然下面2个方法都可以直接使用切入点表达式 @Before("execution(public * com.**.MyController.*(..)")
// 但是问题就来了,目标方法一致切入点表达式相同,这样会是的后期要修改切入点表达式时就得修改2处,
// 为了修改方便建议使用上面的方式: 1. 先直接定义一个切入点@Poincut,当然需要提供一个空方法 2. 直接对这个空方法增强就行,等价于增强目标方法
@Before("log()")
public void doBefore(JoinPoint joinPoint){
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest(); // 这样就可以拿到 request 对象了,然后就可以骚操作了
logger.info("-------------before invoke ... ");
}
@After("log()") // @Before("execution(public * com.**.MyController.*(..)")
public void doAfter(){
logger.info("-------------after invoke ... ");
}
// 注解上参数说明 --- returning : 返回的参数,指的是被增强的方法的返回值,有时候需要关注方法的返回值 ; pointcut : 切入点表达式
@AfterReturning(returning="object",pointcut="log()") // 需要关注方法的返回值时可以使用该注解
public void doAfterReturning(Object object){
logger.info("response={}",object); // 这样会把 object 加入到{}中,最后输出到日志
}
}
统一异常处理
对于前后端分离数据交互使用JSON的情况下,不能直接回传异常信息,这会导致回传的数据/异常不是自己想要的结构,导致前端接收回传数据时还
需要做适配,正确的做法是:统一所有回传数据的格式,如:这样便可以对异常做统一处理,因此后台需要封装异常信息并统一格式
{
flag:true/false,
msg:"成功/异常信息",
reqData: ... ,
resData: ...
}
当然以上只对返回的格式做出了统一
// 对异常统一做处理
@ControllerAdvice
public class ExceptionHandle {
@ExceptionHandler(value=Exception.class) // 需要被捕获的异常
@ResponseBody // 没有使用@RestController 时就需要使用@ResponseBody来注明该方法返回到前端的数据是JSON
public Object handle(Exception e){
// 这里处理异常,返回规定的格式到前端,同时对不同的异常做不同的处理
// 建议如果是业务上会引发的异常需要自定义异常
if(e instanceof MyException1){
// ...
}else if(e instanceof MyException2){
// ...
}
}
}
注:代码中定义的标志、信息等等我们需要统一起来,修改代码时就不需要全文查找(统一维护必不可少)
要点:
统一向前端返回的结果的数据格式
使用抛出异常+异常统一处理的方式保证业务逻辑不重复
根据业务场景需要自定义自己的异常
代码中出现的标志、信息等等统一管理
单元测试经验
@AutoConfigureMockMvc 和 MockMvc 的使用实现对controller测试
maven clean package -Dmaven.test.skip=true 打包时跳过单元测试
查看全部 -
throw 继承RuntimeException()里面会统一处理异常message
controller也不catch统一交给使用@controlleradvice注解的类进行处理
使用@controlleradvice的方法要使用@ExceptionHandler(value写对应要catch的异常)
查看全部 -
捕获异常类的写法:
查看全部 -
代码地址。
查看全部 -
第2章 2-1
查看全部 -
课程介绍入门学习!
查看全部 -
课程介绍!
查看全部
举报