【模式一】3.1把报错信息存入数据库

分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();
        }
    }
}

在这里插入图片描述

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值