分2小结分析,这篇文章先展示代码,下篇文章讲解代码
异常实体类
/**
* 所有的sql错误操作记录 实体类。
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LogSqlError implements Serializable {
/**
* 编号
*/
@Id(keyType = KeyType.Auto)
private Long id;
/**
* sql语句
*/
private String sqlText;
/**
* 访问人
*/
private String userId;
/**
* 访问IP
*/
private String userIp;
/**
* 耗时
*/
private String errorType;
/**
* 访问地址
*/
private String url;
/**
* 执行时间
*/
private Date createDate;
}
配置文件application.properties
server.port=9001
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mysqllog?serverTimezone=UTC&useUnicode=true@characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#mybatis.mapper-locations =classpath:/mappers/*.xml
mybatis-flex.mapper-locations=classpath:/mappers/*.xml
mybatis-flex.configuration.call-setters-on-nulls=true
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis数据库索引(默认为0)
spring.redis.database=1
# Redis服务器连接密码(默认为空)
spring.redis.password=123456
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1ms
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=5000ms
#配置不需要拦截的接口 放行 用,分割 配置文件集合是这样定义的
#fx.lists=/helloDm/**,/reg/**
fx.lists=/helloDm/**
mapper层
@Mapper
@Repository
public interface LogSqlErrorMapper extends BaseMapper<LogSqlError> {
}
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.LogSqlErrorMapper">
</mapper>
service层
public interface LogSqlErrorService extends IService<LogSqlError> {
}
service的实现类
@Service
public class LogSqlErrorServiceImpl extends ServiceImpl<LogSqlErrorMapper, LogSqlError> implements LogSqlErrorService {
}
controller层
@RestController
@RequiredArgsConstructor
@RequestMapping("log")
public class LogController {
private final LogSqlErrorService logSqlErrorService;
@PostMapping("saveErrorLog")
public BaseResponse<LogSqlError> saveError(@RequestBody LogSqlError logSqlError){
boolean save = logSqlErrorService.save(logSqlError);
if(!save){
return ResultUtils.error(ErrorCode.NULL_ERROR);
}
return ResultUtils.success(logSqlError);
}
}
捕获异常类 具体怎么捕获看【模式一】2全局异常处理
/**
* @Description: 捕获异常
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@SneakyThrows
//捕获自定义异常
@ExceptionHandler(BusinessException.class)
public BaseResponse businessException(BusinessException e, HttpServletRequest request) {
log.error("BusinessException:" + e.getMessage(), e);
//post请求
//1, 得到URL对象
URL url = new URL("http://10.11.6.88:9001/log/saveErrorLog");
//2, 打开连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//3, 设置提交类型
conn.setRequestMethod("POST");
conn.setRequestProperty("content-Type", "application/json; charset=utf-8");
//4, 设置允许写出数据,默认是不允许 false
conn.setDoOutput(true);
conn.setDoInput(true);//当前的连接可以从服务器读取内容, 默认是true
//5, 获取向服务器写出数据的流
OutputStream os = conn.getOutputStream();
String sqlText = e.getMessage();
if (sqlText.contains("@")) {
sqlText = sqlText.split("@")[1];
}
LogSqlError logErrorInfo = new LogSqlError();
logErrorInfo.setSqlText(sqlText);
logErrorInfo.setCreateDate(new Date());
logErrorInfo.setUrl(request.getRequestURI());
logErrorInfo.setErrorType("BusinessException");
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if("0:0:0:0:0:0:0:1".equals(ip)){//本地运行会出现这个情况,如果部署到公网上就不会是0:0:0:0:0:0:0:1 会显示本机公网的ip 这里就是本地电脑先写本地
ip = "127.0.0.1";
}
logErrorInfo.setUserIp(ip);
ObjectMapper objectMapper = new ObjectMapper();
String jsonlog = objectMapper.writeValueAsString(logErrorInfo);//实体类转成json
//参数是键值队 , 不以"?"开始
os.write(jsonlog.getBytes());
os.flush();
//6, 获取响应的数据
//得到服务器写回的响应数据
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
String str = br.readLine();
JSONObject json = JSONObject.parseObject(str);
System.out.println("响应内容为: " + json);
return ResultUtils.error(e.getCode(), e.getMessage(), e.getDescription());
}
@SneakyThrows
//捕获所有运行时异常
@ExceptionHandler(RuntimeException.class)
public BaseResponse runtimeExceptionException(RuntimeException e, HttpServletRequest request) {
log.error("RuntimeException", e);
//post请求
//1, 得到URL对象
URL url = new URL("http://10.11.6.88:9001/log/saveErrorLog");
//2, 打开连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//3, 设置提交类型
conn.setRequestMethod("POST");
conn.setRequestProperty("content-Type", "application/json; charset=utf-8");
//4, 设置允许写出数据,默认是不允许 false
conn.setDoOutput(true);
conn.setDoInput(true);//当前的连接可以从服务器读取内容, 默认是true
//5, 获取向服务器写出数据的流
OutputStream os = conn.getOutputStream();
String sqlText = e.getMessage();
if (sqlText.contains("@")) {
sqlText = sqlText.split("@")[1];
}
LogSqlError logErrorInfo = new LogSqlError();
logErrorInfo.setSqlText(sqlText);
logErrorInfo.setCreateDate(new Date());
logErrorInfo.setUrl(request.getRequestURI());
logErrorInfo.setErrorType("RuntimeException");
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if("0:0:0:0:0:0:0:1".equals(ip)){//本地运行会出现这个情况,如果部署到公网上就不会是0:0:0:0:0:0:0:1 会显示本机公网的ip 这里就是本地电脑先写本地
ip = "127.0.0.1";
}
logErrorInfo.setUserIp(ip);
ObjectMapper objectMapper = new ObjectMapper();
String jsonlog = objectMapper.writeValueAsString(logErrorInfo);//实体类转成json
//参数是键值队 , 不以"?"开始
os.write(jsonlog.getBytes());
os.flush();
//6, 获取响应的数据
//得到服务器写回的响应数据
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
String str = br.readLine();
JSONObject json = JSONObject.parseObject(str);
System.out.println("响应内容为: " + json);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, e.getMessage());
}
/**
* sql 语句格式化,将参数与语句拼接成完成sql
*
* @param sql 语句
* @param params 参数
* @return 完整语句
*/
private String prepareSql(String sql, List<Object> params) {
if (params == null || params.size() == 0) {
return sql;
}
StringBuilder sb = new StringBuilder();
int paramIndex = 1;
int placeholderIndex = sql.indexOf('?');
while (placeholderIndex != -1) {
sb.append(sql, 0, placeholderIndex);
sb.append(getParamValue(params.get(paramIndex - 1)));
sql = sql.substring(placeholderIndex + 1);
placeholderIndex = sql.indexOf('?');
paramIndex++;
}
sb.append(sql);
return sb.toString();
}
private String getParamValue(Object param) {
if (param == null) {
return "NULL";
} else if (param instanceof String) {
return "'" + param.toString() + "'";
} else {
return param.toString();
}
}
}