在日常开发中,我们的项目难免会出现各种错误,这时候就要求我们开发人员对这些错误进行集中处理,对不同的错误进行处理,并且将对应的错误详情返回到前端,然后后台可将错误记录到本地本地还是数据库看自己选择,这里是利用log4j记录到本地这样的好处这样不仅能快速找出错误的地方,将提示更人性化。同时也是一个项目不可缺少的一个模块。
废话不多说,开始操作
tip:开始之前,先导入aop和log4j依赖
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-logging
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-starter-log4j
1.3.8.RELEASE
1.创建一个返回体报文的实体类
package com.zfsh.result;
/**
* 创建一个返回体报文的实体类
* */
public class Result {
// error_code 状态值:0 极为成功,其他数值代表失败
private Integer status;
// error_msg 错误信息,若status为0时,为success
private String msg;
// content 返回体报文的出参,使用泛型兼容不同的类型
private T data;
public Integer getStatus() {
return status;
}
public void setStatus(Integer code) {
this.status = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData(Object object) {
return data;
}
public void setData(T data) {
this.data = data;
}
public T getData() {
return data;
}
@Override
public String toString() {
return "Resut [status=" + status + ", msg=" + msg + ", data=" + data + "]";
}
}
2.创建一个工具类,方便之后调用
package com.zfsh.util;
import com.zfsh.result.ExceptionEnum;
import com.zfsh.result.Result;
public class ResultUtil {
/**
* 返回成功,传入返回体具体出參
* @param object
* @return
*/
public static Result success(Object object){
Result result = new Result();
result.setStatus(0);
result.setMsg("success");
result.setData(object);
return result;
}
/**
* 提供给部分不需要出參的接口
* @return
*/
public static Result success(){
return success(null);
}
/**
* 自定义错误信息
* @param code
* @param msg
* @return
*/
public static Result error(Integer code,String msg){
Result result = new Result();
result.setStatus(code);
result.setMsg(msg);
result.setData(null);
return result;
}
/**
* 返回异常信息,在已知的范围内
* @param exceptionEnum
* @return
*/
public static Result error(ExceptionEnum exceptionEnum){
Result result = new Result();
result.setStatus(exceptionEnum.getCode());
result.setMsg(exceptionEnum.getMsg());
result.setData(null);
return result;
}
}
3.创建一个枚举类,来记录一些我们已知的错误信息
package com.zfsh.result;
//创建一个枚举类,来记录一些我们已知的错误信息
public enum ExceptionEnum {
UNKNOW_ERROR(-1,"未知错误"),
USER_NOT_FIND(-101,"用户不存在"),
;
private Integer code;
private String msg;
ExceptionEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
4.创建DescribeException来获取错误实体
package com.zfsh.exception;
import com.zfsh.result.ExceptionEnum;
public class DescribeException extends RuntimeException {
private Integer code;
/**
* 继承exception,加入错误状态值
* @param exceptionEnum
*/
public DescribeException(ExceptionEnum exceptionEnum) {
super(exceptionEnum.getMsg());
this.code = exceptionEnum.getCode();
}
/**
* 自定义错误信息
* @param message
* @param code
*/
public DescribeException(String message, Integer code) {
super(message);
this.code = code;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
5.创建ExceptionHandle来定义错误并将错误信息记录到本地
package com.zfsh.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.zfsh.result.ExceptionEnum;
import com.zfsh.result.Result;
import com.zfsh.util.ResultUtil;
@ControllerAdvice
public class ExceptionHandle {
private final static Logger LOGGER = LoggerFactory.getLogger(ExceptionHandle.class);
/**
* 判断错误是否是已定义的已知错误,不是则由未知错误代替,同时记录在log中
* @param e
* @return
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Result exceptionGet(Exception e){
if(e instanceof DescribeException){
DescribeException MyException = (DescribeException) e;
return ResultUtil.error(MyException.getCode(),MyException.getMessage());
}
LOGGER.error("[系统异常]{}",e);
return ResultUtil.error(ExceptionEnum.UNKNOW_ERROR);
}
}
6.完成,另附上log4j.properties的配置(需在src/main/resource目录下创建,并在application.properties中指定log4j)
application.properties中引入下面这段代码
#引入log4j配置
logging.config=src/main/resources/log4j.properties
log4j.properties:
log4j.rootLogger=INFO, CONSOLE, ROLLING_FILE, DAILY_ROLLING_FILE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=<%d>[%5p] %m - %c%n
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.File=./logs/client.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=20000KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=100
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
#log4j.appender.ROLLING_FILE.layout.ConversionPattern=<%d>[%5p] %c - %m%n
log4j.appender.ROLLING_FILE.layout.ConversionPattern=%d %c [%t] (%F:%L) %-5p --> %m%n
log4j.appender.DAILY_ROLLING_FILE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DAILY_ROLLING_FILE.File=./logs/client
log4j.appender.DAILY_ROLLING_FILE.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.DAILY_ROLLING_FILE.Append=true
log4j.appender.DAILY_ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.DAILY_ROLLING_FILE.layout.ConversionPattern=%d %c [%t] (%F:%L) %-5p --> %m%n
7.到此已经完成,接下里开始测试
新建一个controller,故意制造一个错误
@RequestMapping("null")
@ResponseBody
public String nullPointer() {
int i = 9/0;
return "error";
}