构建项目

pom.xml增加Druid依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
配置数据源
配置application.yml
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8
username: root
password: 123456
#配置监控统计拦截的filters
filters: stat,wall,log4j
#最大活跃数
maxActive: 20
#初始化数量
initialSize: 1
#最大连接等待超时时间
maxWait: 60000
#打开PSCache,并指定每个连接PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
#通过connectionProperties属性打开mergeSql功能
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
minldle: 1
timeBetweenEvictionRunsMillis: 60000
minEvictableldleTimeMillis: 300000
validationQuery: select 1 from dual
testWhiledle: true
testOnBorrow: false
testOnReturn: false
jpa:
properties:
hibernate:
show_sql: true
format_sql: true
mvc:
view:
prefix: /WEB-INF/views/
suffix: .jsp
创建数据表结构
DROP TABLE IF EXISTS `t_logger_info`;
CREATE TABLE `t_logger_info` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`client_ip` varchar(50) DEFAULT NULL COMMENT '客户端请求ip',
`uri` varchar(200) DEFAULT NULL COMMENT '客户端请求路径',
`log_type` varchar(50) DEFAULT NULL COMMENT '终端请求方式:普通请求,ajax请求',
`log_method` varchar(50) DEFAULT NULL COMMENT '请求方式method:get,post',
`param_data` varchar(500) DEFAULT NULL COMMENT '请求参数内容json',
`session_id` varchar(100) DEFAULT NULL COMMENT '请求接口唯一session标识',
`log_time` varchar(100) DEFAULT NULL COMMENT '请求时间',
`return_time` varchar(50) DEFAULT NULL COMMENT '接口返回时间',
`return_data` varchar(500) DEFAULT NULL COMMENT '接口返回数据json',
`http_status_code` varchar(10) DEFAULT NULL COMMENT '接口返回状态代码',
`time_consuming` int DEFAULT NULL COMMENT '耗时',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
创建实体
package com.gala.log.entity;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "t_logger_info")
public class LoggerInfo {
private Long id; // 主键
private String clientIp; // 客户端请求ip
private String uri; // 客户端请求路径
private String logType; // 终端请求方式:普通请求ajax请求
private String logMethod; // 请求方式method:getpost
private String paramData; // 请求参数内容json
private String sessionId; // 请求接口唯一session标识
private String logTime; // 请求时间
private String returnTime; // 接口返回时间
private String returnData; // 接口返回数据json
private String httpStatusCode; // 接口返回状态代码
private Integer timeConsuming; // 耗时
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getClientIp() {
return clientIp;
}
public void setClientIp(String clientIp) {
this.clientIp = clientIp;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getLogType() {
return logType;
}
public void setLogType(String logType) {
this.logType = logType;
}
public String getLogMethod() {
return logMethod;
}
public void setLogMethod(String logMethod) {
this.logMethod = logMethod;
}
public String getParamData() {
return paramData;
}
public void setParamData(String paramData) {
this.paramData = paramData;
}
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public String getLogTime() {
return logTime;
}
public void setLogTime(String logTime) {
this.logTime = logTime;
}
public String getReturnTime() {
return returnTime;
}
public void setReturnTime(String returnTime) {
this.returnTime = returnTime;
}
public String getReturnData() {
return returnData;
}
public void setReturnData(String returnData) {
this.returnData = returnData;
}
public String getHttpStatusCode() {
return httpStatusCode;
}
public void setHttpStatusCode(String httpStatusCode) {
this.httpStatusCode = httpStatusCode;
}
public Integer getTimeConsuming() {
return timeConsuming;
}
public void setTimeConsuming(Integer timeConsuming) {
this.timeConsuming = timeConsuming;
}
}
创建JPA
package com.gala.log.jpa;
import java.io.Serializable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import com.gala.log.entity.LoggerInfo;
public interface LoggerInfoDao extends JpaRepository<LoggerInfo, Long>, JpaSpecificationExecutor<LoggerInfo>, Serializable {
}
创建日志拦截器
自定义SpringMVC拦截器需要实现HandlerIntercptor接口,并且实现内部的三个方法。
package com.gala.jpa.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class LoggerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
拦截器内无法通过SpringBean的方式注入LoggerDao
工具类WebApplicationContextUtils可以通过HttpServletRequest请求对象的上下文(ServetCotext)获取Spring管理的Bean
private <T> T getDAO(Class<T> clazz,HttpServletRequest request) {
BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
return factory.getBean(clazz);
}
记录请求日志
加入FastJson、HttpServet依赖
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
- 在preHandle方法内创建LoggerEntity实体,并记录一些必要参数后将实体写入到当前请求对象HttpServletRequest内
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 创建日志实体
LoggerInfo logger = new LoggerInfo();
// 获取请求sessionId
String sessionId = request.getRequestedSessionId();
// 请求路径
String url = request.getRequestURI();
// 获取请求参数信息
String paramData = JSON.toJSONString(request.getParameterMap(), SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue);
// 设置客户端IP
logger.setClientIp(LoggerUtils.getCliectIp(request));
// 设置请求方法
logger.setLogMethod(request.getMethod());
// 设置请求类型
logger.setLogType(LoggerUtils.getRequestType(request));
// 设置请求参数内容
logger.setParamData(paramData);
// 设置请求地址
logger.setUri(url);
// 设置sessionId
logger.setSessionId(sessionId);
// 设置请求开始时间
request.setAttribute(LOGGER_SEND_TIME, System.currentTimeMillis());
request.setAttribute(LOGGER_ENTITY, logger);
return true;
}
- 当用户发送请求时在进入SpringMVC的控制器之前会进入preHandle方法,接着会进入对应springMVC控制器方法的方法,在最后渲染视图即将返回前台的时候开始执行afterCompletion方法。
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
//获取请求错误码
int status = response.getStatus();
//当前时间
long currentTime = System.currentTimeMillis();
//请求开始时间
long time = Long.valueOf(request.getAttribute(LOGGER_SEND_TIME).toString());
//获取本次请求日志实体
LoggerInfo loggerEntity = (LoggerInfo) request.getAttribute(LOGGER_ENTITY);
//设置请求时间差
loggerEntity.setTimeConsuming(Integer.valueOf((currentTime - time)+""));
//设置返回时间
loggerEntity.setReturnTime(currentTime + "");
//设置返回错误码
loggerEntity.setHttpStatusCode(status+"");
//设置返回值
loggerEntity.setReturnData(JSON.toJSONString(request.getAttribute(LoggerUtils.LOGGER_RETURN),
SerializerFeature.DisableCircularReferenceDetect,
SerializerFeature.WriteMapNullValue));
//执行将日志写入数据库
LoggerInfoDao loggerDAO = getDAO(LoggerInfoDao.class,request);
loggerDAO.save(loggerEntity);
}
编写控制器
package com.gala.log.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSONObject;
import com.gala.log.util.LoggerUtils;
@RestController
@RequestMapping(value = "/index")
public class IndexController {
@RequestMapping(value = "/login", method = RequestMethod.GET)
public JSONObject login(HttpServletRequest request, String name) throws Exception {
JSONObject obj = new JSONObject();
obj.put("msg", "用户:" + name + ",登录成功。");
// 将返回值写入到请求对象中
request.setAttribute(LoggerUtils.LOGGER_RETURN, obj);
return obj;
}
}
配置拦截器
package com.gala.log;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.gala.log.interceptor.LoggerInterceptor;
@Configuration
public class LoggerConfguration implements WebMvcConfigurer {
/**
* 将拦截器配置到SpringBoot中
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoggerInterceptor()).addPathPatterns("/**");
}
}
运行项目
访问地址:http://127.0.0.1:8080/index/login?name=admin


网友评论