全局异常是入门案例
背景: 比如我们代码里面出现重复的异常需要捕获,每次都要重复写代码,有没有可以解决的办法,就诞生了全局异常捕获。
首先对相关注解说明:
/**
* 1. ControllerAdvice 的一个辅助类,最常用的就是作为全局异常处理的切面类
* 2.可以指定扫描范围,是指扫描包的范围
* 3.约定了几种可行的返回值,如果是直接返回 model 类的话,需要使用 @ResponseBody 进行 json 转换
* 返回 String,表示跳到某个 view
* 返回 modelAndView
* 返回 model + @ResponseBody
*/
示例代码
1.首先写个可以产生异常的代码,存在算术异常
@RestController
public class ExceptionController {
@RequestMapping("/exceptionHandler")
public String exceptionHandler(@RequestParam("i") int i){
int j = 0/i;
System.out.println(j);
return "访问成功";
}
}
2.捕获异常,并返回json信息给前端
@ControllerAdvice(basePackages = "com.learn.seckill.controller")
public class ControllerException {
//ExceptionHandler 捕获什么样的异常,这样定义
@ExceptionHandler(RuntimeException.class)
//返回json信息
@ResponseBody
public Map<String, Object> exceptionHandler(Exception e) {
Map<String, Object> map = new HashMap<String, Object>();
// 判断异常是否为算术异常,其他异常根据业务去捕获
if (e instanceof ArithmeticException) {
map.put("errorCode", "101");
map.put("errorMsg", "算术异常");
}
return map;
}
}
Lombok使用
背景:在实体类使用getter和setter方法,但是看起来一点也不简洁,lombok使用字节码技术,在编译的时候去生成相应的方法
1.引入依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2.使用响应的注解
/**
* 为类字段生成getter和setter,
* toString,
* 有参和无参构造函数
*/
@ToString
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
}
3.验证结果(1.可以反编译的时候,可以看到生成的文件2.在其他层验证)
1.反编译
public class User {
private String name;
private int age;
public String toString() {
return (new StringBuilder()).append("User(name=").append(getName()).append(", age=")
.append(getAge()).append(")").toString();
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public User() {
}
}
2…在其他层验证
@RestController
@Slf4j
public class LombokController {
@RequestMapping("/getUser")
public Map<String, Object> getUser() {
Map<String, Object> map = new HashMap<>();
User user = new User("leiLi",20);
log.info(user.toString());
user.setAge(30);
log.info(user.toString());
map.put("userInfo",user);
return map;
}
}
log4j做aop日志处理
1.首先排除其他日志,引入依赖
<!-- 排除其他日志 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- springboot-log4j -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
<!-- springboot-aspect 技术 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
配置日志
#log4j.rootLogger=CONSOLE,info,error,DEBUG
log4j.rootLogger=info,error,CONSOLE,DEBUG
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
log4j.logger.info=info
log4j.appender.info=org.apache.log4j.DailyRollingFileAppender
log4j.appender.info.layout=org.apache.log4j.PatternLayout
log4j.appender.info.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
log4j.appender.info.datePattern='.'yyyy-MM-dd
log4j.appender.info.Threshold = info
log4j.appender.info.append=true
#log4j.appender.info.File=/home/admin/pms-api-services/logs/info/api_services_info
log4j.appender.info.File=/Users/dddd/Documents/testspace/pms-api-services/logs/info/api_services_info
log4j.logger.error=error
log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.layout=org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
log4j.appender.error.datePattern='.'yyyy-MM-dd
log4j.appender.error.Threshold = error
log4j.appender.error.append=true
#log4j.appender.error.File=/home/admin/pms-api-services/logs/error/api_services_error
log4j.appender.error.File=/Users/dddd/Documents/testspace/pms-api-services/logs/error/api_services_error
log4j.logger.DEBUG=DEBUG
log4j.appender.DEBUG=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DEBUG.layout=org.apache.log4j.PatternLayout
log4j.appender.DEBUG.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
log4j.appender.DEBUG.datePattern='.'yyyy-MM-dd
log4j.appender.DEBUG.Threshold = DEBUG
log4j.appender.DEBUG.append=true
#log4j.appender.DEBUG.File=/home/admin/pms-api-services/logs/debug/api_services_debug
log4j.appender.DEBUG.File=/Users/dddd/Documents/testspace/pms-api-services/logs/debug/api_services_debug
用aop统一处理web日志,记录每个方法相关记录
@Aspect
@Component
public class WebLogAspect {
private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
@Pointcut("execution(public * com.learn.seckill.controller.*.*(..))")
public void webLog() {
}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable{
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 记录下请求内容
logger.info("URL : " + request.getRequestURL().toString());
logger.info("HTTP_METHOD : " + request.getMethod());
logger.info("IP : " + request.getRemoteAddr());
Enumeration<String> enu = request.getParameterNames();
while (enu.hasMoreElements()) {
String name = (String) enu.nextElement();
logger.info("name:{},value:{}", name, request.getParameter(name));
}
}
@AfterReturning(returning = "ret", pointcut = "webLog()")
public void doAfterReturning(Object ret) throws Throwable {
// 处理完请求,返回内容
logger.info("RESPONSE : " + ret);
}
}