基于Spring Boot+JPA,使用AOP打印请求日志功能
2019-08-27 本文已影响0人
bearPotMan
用过Spring的朋友应该多多少少都知道AOP(即面向切面),本篇文章我们就来实战如何使用AOP打印请求日志功能
!
一、简单web项目
1.创建项目
使用 IDEA 工具创建一个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.创建数据库
create database spring_boot_aop;
这里我们先不创建表,因为我们用了spring-data-jpa
,后面我们用它来创建表。
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语句(正式环境还是不要用)
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.启动项目
完成以上几个步骤之后,我们启动项目来创建对应的 user 表。
启动项目,如果控制台能看到如下日志即表明项目没有问题,表创建成功!
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 或相似工具,请求接口测试!
下面是我本地调试结果的截图(图比较多,请耐心查看)
-
注册【成功】
aop-register.png -
注册【失败】
aop-register-repeat.png -
登录【账号错误】
aop-login-phoneerror.png -
登录【密码错误】
aop-login-pwderror.png -
登录【成功】
aop-login-success.png
好,接口基本上都是没有问题的!下面就进入我们今天的主题[废话真多,我还以为要结束了呢~]:使用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());
// 参数
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))
通过上述步骤,我们已经实现了基本功能,好了,今天就到此位置了!
结束语:
完整代码已提交至 Github,可结合本文使用!