-
在所有執行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
查看全部 -
課程介紹入門學習!
查看全部 -
課程介紹!
查看全部
舉報