用過Spring的朋友應(yīng)該多多少少都知道AOP(即面向切面)耀怜,本篇文章我們就來實戰(zhàn)如何使用AOP打印請求日志功能
!
一茶宵、簡單web項目
1.創(chuàng)建項目
使用 IDEA 工具創(chuàng)建一個Spring Initializr項目危纫,選擇
Web>Spring Web Starter
SQL>Spring Data JPA
SQL>MySQL Driver
Developer Tools>Lombok
這幾個組件。
2.基本依賴
<dependencies>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mysql --->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- 方便部分編碼 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
3.創(chuàng)建數(shù)據(jù)庫
create database spring_boot_aop;
這里我們先不創(chuàng)建表,因為我們用了spring-data-jpa
种蝶,后面我們用它來創(chuàng)建表契耿。
4.配置文件application.yml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/spring_boot_aop?characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
# update: 沒有表就新建,有表則更新
ddl-auto: update
# 控制臺顯示sql語句(正式環(huán)境還是不要用)
show-sql: true
5.實體類
@Data
@Entity
@Table(name = "aop_user")
public class User {
@Id
@GeneratedValue
private Long id;
private String phone;
private String password;
private Date createTime;
private Date updateTime;
}
6.啟動項目
完成以上幾個步驟之后蛤吓,我們啟動項目來創(chuàng)建對應(yīng)的 user 表宵喂。
啟動項目,如果控制臺能看到如下日志即表明項目沒有問題会傲,表創(chuàng)建成功锅棕!
Hibernate: create table aop_user (id bigint not null, create_time datetime, password varchar(255), phone varchar(255), update_time datetime, primary key (id)) engine=MyISAM
Hibernate: create table hibernate_sequence (next_val bigint) engine=MyISAM
Hibernate: insert into hibernate_sequence values ( 1 )
7.repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByPhone(String phone);
}
8.service & Impl
UserService
public interface UserService {
/**
* 注冊
*
* @param phone
* @param password
* @return
*/
Result register(String phone, String password);
/**
* 登錄
*
* @param phone
* @param password
* @return
*/
Result login(String phone, String password);
}
UserServiceImpl
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
/**
* 注冊
*
* @param phone
* @param password
* @return
*/
@Override
public Result register(String phone, String password) {
User byPhone = userRepository.findByPhone(phone);
if (byPhone != null) {
return ResultUtil.error(ResultEnum.REGISTER_ERROR);
}
User user = new User();
user.setPhone(phone);
user.setPassword(getMd5(phone, password));
userRepository.save(user);
return ResultUtil.success();
}
/**
* 登錄
*
* @param phone
* @param password
* @return
*/
@Override
public Result login(String phone, String password) {
User user = userRepository.findByPhone(phone);
if (user == null) {
return ResultUtil.error(ResultEnum.ACCOUNT_ERROR);
}
String md5 = getMd5(phone, password);
if (!md5.equals(user.getPassword())) {
return ResultUtil.error(ResultEnum.PASSWORD_ERROR);
}
UserVO userVO = new UserVO();
userVO.setUserId(user.getId());
userVO.setPhone(user.getPhone());
return ResultUtil.success(userVO);
}
// md5加密
public String getMd5(String phone, String password) {
String salt = "^#)$^&$$!~@+(,.';-`";
byte[] bytes = new StringBuilder(phone).append(password).append(salt).toString().getBytes();
String md5DigestAsHex = DigestUtils.md5DigestAsHex(bytes);
return md5DigestAsHex;
}
}
9.controller
@RestController
public class UserController {
@Autowired
private UserService userService;
/**
* 注冊
*
* @param phone
* @param password
* @return
*/
@PostMapping("/register")
public Result register(String phone, String password) {
return userService.register(phone, password);
}
/**
* 登錄
*
* @param phone
* @param password
* @return
*/
@PostMapping("/login")
public Result login(String phone, String password) {
return userService.login(phone, password);
}
}
10.重啟項目,檢測接口是否可用
使用 Postman 或相似工具淌山,請求接口測試裸燎!
下面是我本地調(diào)試結(jié)果的截圖(圖比較多,請耐心查看)
-
注冊【成功】
-
注冊【失敗】
-
登錄【賬號錯誤】
-
登錄【密碼錯誤】
-
登錄【成功】
好泼疑,接口基本上都是沒有問題的德绿!下面就進入我們今天的主題[廢話真多,我還以為要結(jié)束了呢~]:使用AOP打印請求日志退渗!
二移稳、加入AOP
1.切面類
@Component
@Aspect
@Slf4j
public class LogAspect {
@Pointcut("execution(public * com.bpm.aop.web.*.*(..))")
public void log(){
}
@Before("log()")
public void doBefore(JoinPoint joinPoint){
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// url
log.info("url={}", request.getRequestURL());
// method(Get/Post...)
log.info("method={}", request.getMethod());
// ip
log.info("ip={}", request.getRemoteAddr());
// 類方法
log.info("class_method={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
// 參數(shù)
log.info("args={}", Arrays.asList(joinPoint.getArgs()));
}
@AfterReturning(returning = "resp", pointcut = "log()")
public void doAfter(Object resp) {
log.info("response={}", resp);
}
}
2.重啟項目,請求接口会油,查看日志
2019-08-27 10:22:14.350 INFO 20636 --- [nio-8081-exec-3] com.bpm.aop.aspect.LogAspect : url=http://localhost:8081/login
2019-08-27 10:22:14.350 INFO 20636 --- [nio-8081-exec-3] com.bpm.aop.aspect.LogAspect : method=POST
2019-08-27 10:22:14.350 INFO 20636 --- [nio-8081-exec-3] com.bpm.aop.aspect.LogAspect : ip=0:0:0:0:0:0:0:1
2019-08-27 10:22:14.350 INFO 20636 --- [nio-8081-exec-3] com.bpm.aop.aspect.LogAspect : class_method=com.bpm.aop.web.UserController.login
2019-08-27 10:22:14.350 INFO 20636 --- [nio-8081-exec-3] com.bpm.aop.aspect.LogAspect : args=[17694870628, 123456]
Hibernate: select user0_.id as id1_0_, user0_.create_time as create_t2_0_, user0_.password as password3_0_, user0_.phone as phone4_0_, user0_.update_time as update_t5_0_ from aop_user user0_ where user0_.phone=?
2019-08-27 10:22:14.353 INFO 20636 --- [nio-8081-exec-3] com.bpm.aop.aspect.LogAspect : response=Result(code=0, message=成功, data=User(id=1, phone=17694870628, password=8913dbaa6619b17369f3b85464a883d8, createTime=2019-08-27 10:06:53.0, updateTime=null))
通過上述步驟个粱,我們已經(jīng)實現(xiàn)了基本功能,好了翻翩,今天就到此位置了都许!
結(jié)束語:
完整代碼已提交至 Github,可結(jié)合本文使用嫂冻!