-
在所有執(zhí)行http請(qǐng)求之前,記錄http請(qǐng)求的url,method,ip,類方法,參數(shù)
查看全部 -
用logger的方式打印日志
查看全部 -
pointcut 定義在公用的log()上
查看全部 -
提取公用部分
查看全部 -
AOP統(tǒng)一處理請(qǐng)求日志
查看全部 -
pop? oop
查看全部 -
跳過(guò)測(cè)試打包
查看全部 -
批量測(cè)試結(jié)果
查看全部 -
SpringBoot應(yīng)用創(chuàng)建
使用ideal 中的springboot插件
訪問(wèn)https://start.spring.io??
根據(jù)網(wǎng)站的指引創(chuàng)建好工程,然后打包下載,最后導(dǎo)入ideal/eclipse
SpringBoot應(yīng)用啟動(dòng)
a. ideal直接點(diǎn)運(yùn)行按鈕
b. 到項(xiàng)目跟路徑,運(yùn)行命令 mvn spring-boot:run?
b. 首先打包 mvn clean package , 然后運(yùn)行生成的jar文件 java -jar ./target/xxx.jar?
項(xiàng)目部署時(shí)使用這種方式
自定義配置屬性
定義我們的配置
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: 最少發(fā)${limit.minMoney}元
讀取我們的自定義配置到程序中
單一配置直接使用 @Value("${param name}")
public class MyController {
@Value("${limit.minMoney}")
private BigDecmal minMoney;
// ...?
}
如果是很多的配置且配置之間有一定關(guān)系,我們可以使用配置類, 針對(duì)上面limit下的配置
limit下面是一組相關(guān)的配置可以看做一個(gè)類里面的成員屬性
@Component
@ConfigurationProperties(prefix="limit") // 指定要加載配置的前綴
public class LimitConfig { // 然后在其它類中注入該類就可以
// 屬性名稱和配置名稱一致
private BigDecimal minMoney;
private BigDecimal maxMoney;
private String description;
// getter/setter?
}
加載不同的配置 application-{profiles}.properties?
有以下幾個(gè)配置文件,其中2個(gè)對(duì)應(yīng)開(kāi)發(fā)、生產(chǎn)配置文件
application.yml
spring:
? profiles:
? ? active: dev
application-dev.yml
application-prod.yml
除了在application.yml中使用 spring.profiles.active=dev 指定要加載配置的后綴外
還可以在項(xiàng)目打包成jar后啟動(dòng)時(shí)在命令行帶入?yún)?shù)來(lái)指定要加載的配置文件的后綴
mvn clean package
java -jar -Dspring.profiles.active=prod xxx.jar? -Dspring.profiles.active=prod指定要加載的配置文件的后綴
Controller使用
@Controller + @ResponseBody = @RestController 后面一個(gè)注解的作用等于使用前面2個(gè)注解
@GetMapping/@PostMapping/@RequestMapping?
@GetMapping({"hello","hi"}) - 多個(gè)訪問(wèn)地址對(duì)應(yīng)一個(gè)方法,更多屬性使用提示去看 ...?
@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持久化接口標(biāo)準(zhǔn),實(shí)現(xiàn)這一接口的有Hibernate/TopLink?
紅包小案例
RESTful API設(shè)計(jì) (案例來(lái)源慕課網(wǎng))
GET /luckymoneys 獲取紅包列表
POST /luckymoneys 創(chuàng)建一個(gè)紅包
GET /luckymoneys/{id} 通過(guò)ID查詢紅包
PUT /luckymoneys/{id} 通過(guò)ID更新紅包
引入2個(gè)依賴, springboot已經(jīng)為我們指定了版本, 需要在引入時(shí)指定版本
groupId: org.springframework.boot
artifactId: spring-boot-starter-data-jpa
groupId: mysql
artifactId: mysql-connector-java
寫(xiě)配置
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 // 自增長(zhǎng)
private Integer id;
private BigDecimal money;
private String producer;
private String consumer;
// constructor
// getter/setter
}
Controller
Dao
// JpaRepository<數(shù)據(jù)庫(kù)表實(shí)體類, 主鍵數(shù)據(jù)類型> , 只要接口
public interface XxxRepository extends JpaRepository<Luckymoney,Integer> {
// ...?
}
事務(wù)管理
首先需要明確的是事務(wù)指的是數(shù)據(jù)庫(kù)的事務(wù)不是程序的功能,事務(wù)是數(shù)據(jù)庫(kù)提供的能力,springboot只是
對(duì)數(shù)據(jù)庫(kù)的事務(wù)操作做了統(tǒng)一處理,因?yàn)槭聞?wù)的處理都是固定的、重復(fù)
@Transactional 用于開(kāi)啟springboot的事務(wù)管理,可以用在類、方法上
表單驗(yàn)證
@Valid BindingResult ; BindingResult - 用于接收參數(shù)校驗(yàn)結(jié)果 ; @Valid 加在被校驗(yàn)的參數(shù)上面?
以及在實(shí)體類加入的一些校驗(yàn)注解: @Min ... ; 實(shí)體類的屬性上面加上一些校驗(yàn)注解,用于對(duì)前端傳入的參數(shù)做校驗(yàn)
XxxController
method(@Valid MyEntity entity, BindingResult bindingResult){...}
AOP 編程
誤區(qū):AOP 編程不是只在java里面提出來(lái)的,AOP 是一種編程范式
// 以記錄日志為例,某個(gè)方法調(diào)用前和調(diào)用后需要記錄日志
@Component?
@Aspect
public class MyAspect {
@Pointcut("execution(public * com.**.MyController.*(..)") // MyController中所有方法都加上日志記錄
public void log(){}
// 當(dāng)然下面2個(gè)方法都可以直接使用切入點(diǎn)表達(dá)式 @Before("execution(public * com.**.MyController.*(..)")
// 但是問(wèn)題就來(lái)了,目標(biāo)方法一致切入點(diǎn)表達(dá)式相同,這樣會(huì)是的后期要修改切入點(diǎn)表達(dá)式時(shí)就得修改2處,
// 為了修改方便建議使用上面的方式: 1. 先直接定義一個(gè)切入點(diǎn)@Poincut,當(dāng)然需要提供一個(gè)空方法 2. 直接對(duì)這個(gè)空方法增強(qiáng)就行,等價(jià)于增強(qiáng)目標(biāo)方法
@Before("log()")??
public void doBefore(JoinPoint joinPoint){
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();? // 這樣就可以拿到 request 對(duì)象了,然后就可以騷操作了
logger.info("-------------before invoke ... ");
}
@After("log()")? // @Before("execution(public * com.**.MyController.*(..)")
public void doAfter(){
logger.info("-------------after invoke ... ");
}
// 注解上參數(shù)說(shuō)明 --- returning : 返回的參數(shù),指的是被增強(qiáng)的方法的返回值,有時(shí)候需要關(guān)注方法的返回值 ; pointcut : 切入點(diǎn)表達(dá)式
@AfterReturning(returning="object",pointcut="log()") // 需要關(guān)注方法的返回值時(shí)可以使用該注解
public void doAfterReturning(Object object){
logger.info("response={}",object); // 這樣會(huì)把 object 加入到{}中,最后輸出到日志
}
}
統(tǒng)一異常處理
對(duì)于前后端分離數(shù)據(jù)交互使用JSON的情況下,不能直接回傳異常信息,這會(huì)導(dǎo)致回傳的數(shù)據(jù)/異常不是自己想要的結(jié)構(gòu),導(dǎo)致前端接收回傳數(shù)據(jù)時(shí)還
需要做適配,正確的做法是:統(tǒng)一所有回傳數(shù)據(jù)的格式,如:這樣便可以對(duì)異常做統(tǒng)一處理,因此后臺(tái)需要封裝異常信息并統(tǒng)一格式
{
flag:true/false,
msg:"成功/異常信息",
reqData: ... ,
resData: ...
}
當(dāng)然以上只對(duì)返回的格式做出了統(tǒng)一
// 對(duì)異常統(tǒng)一做處理
@ControllerAdvice
public class ExceptionHandle {
@ExceptionHandler(value=Exception.class) // 需要被捕獲的異常
@ResponseBody // 沒(méi)有使用@RestController 時(shí)就需要使用@ResponseBody來(lái)注明該方法返回到前端的數(shù)據(jù)是JSON?
public Object handle(Exception e){
// 這里處理異常,返回規(guī)定的格式到前端,同時(shí)對(duì)不同的異常做不同的處理
// 建議如果是業(yè)務(wù)上會(huì)引發(fā)的異常需要自定義異常
if(e instanceof MyException1){
// ...?
}else if(e instanceof MyException2){
// ...
}
}
}
注:代碼中定義的標(biāo)志、信息等等我們需要統(tǒng)一起來(lái),修改代碼時(shí)就不需要全文查找(統(tǒng)一維護(hù)必不可少)
要點(diǎn):
統(tǒng)一向前端返回的結(jié)果的數(shù)據(jù)格式
使用拋出異常+異常統(tǒng)一處理的方式保證業(yè)務(wù)邏輯不重復(fù)
根據(jù)業(yè)務(wù)場(chǎng)景需要自定義自己的異常
代碼中出現(xiàn)的標(biāo)志、信息等等統(tǒng)一管理
單元測(cè)試經(jīng)驗(yàn)
@AutoConfigureMockMvc 和 MockMvc 的使用實(shí)現(xiàn)對(duì)controller測(cè)試
maven clean package -Dmaven.test.skip=true 打包時(shí)跳過(guò)單元測(cè)試
查看全部 -
throw 繼承RuntimeException()里面會(huì)統(tǒng)一處理異常message
controller也不catch統(tǒng)一交給使用@controlleradvice注解的類進(jìn)行處理
使用@controlleradvice的方法要使用@ExceptionHandler(value寫(xiě)對(duì)應(yīng)要catch的異常)
查看全部 -
捕獲異常類的寫(xiě)法:
查看全部 -
代碼地址。
查看全部 -
第2章 2-1
查看全部 -
課程介紹入門(mén)學(xué)習(xí)!
查看全部 -
課程介紹!
查看全部
舉報(bào)