建立一个全局异常处理类:GlobalExceptionHandler
package com.hll.demo.handler;
import...
import com.hll.demo.exception.MyException;
import com.hll.demo.model.JsonResult;
/**
* 异常处理拦截器
* @author hll
* @date 2018年5月25日
*/
@CrossOrigin
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
private static final String logExceptionFormat = "Capture Exception By GlobalExceptionHandler: Code: %s Detail: %s";
private static Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
//运行时异常
@ExceptionHandler(RuntimeException.class)
public String runtimeExceptionHandler(RuntimeException ex) {
return exceptionFormat(1, ex);
}
//空指针异常
@ExceptionHandler(NullPointerException.class)
public String nullPointerExceptionHandler(NullPointerException ex) {
return exceptionFormat(2, ex);
}
//类型转换异常
@ExceptionHandler(ClassCastException.class)
public String classCastExceptionHandler(ClassCastException ex) {
return exceptionFormat(3, ex);
}
//IO异常
@ExceptionHandler(IOException.class)
public String iOExceptionHandler(IOException ex) {
return exceptionFormat(4, ex);
}
//未知方法异常
@ExceptionHandler(NoSuchMethodException.class)
public String noSuchMethodExceptionHandler(NoSuchMethodException ex) {
return exceptionFormat(5, ex);
}
//数组越界异常
@ExceptionHandler(IndexOutOfBoundsException.class)
public String indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
return exceptionFormat(6, ex);
}
//400错误
@ExceptionHandler({HttpMessageNotReadableException.class})
public String requestNotReadable(HttpMessageNotReadableException ex) {
System.out.println("400..requestNotReadable");
return exceptionFormat(7, ex);
}
//400错误
@ExceptionHandler({TypeMismatchException.class})
public String requestTypeMismatch(TypeMismatchException ex) {
System.out.println("400..TypeMismatchException");
return exceptionFormat(8, ex);
}
//400错误
@ExceptionHandler({MissingServletRequestParameterException.class})
public String requestMissingServletRequest(MissingServletRequestParameterException ex) {
System.out.println("400..MissingServletRequest");
return exceptionFormat(9, ex);
}
//405错误
@ExceptionHandler({HttpRequestMethodNotSupportedException.class})
public String request405(HttpRequestMethodNotSupportedException ex) {
return exceptionFormat(10, ex);
}
//406错误
@ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
public String request406(HttpMediaTypeNotAcceptableException ex) {
System.out.println("406...");
return exceptionFormat(11, ex);
}
//500错误
@ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
public String server500(RuntimeException ex) {
System.out.println("500...");
return exceptionFormat(12, ex);
}
//栈溢出
@ExceptionHandler({StackOverflowError.class})
public String requestStackOverflow(StackOverflowError ex) {
return exceptionFormat(13, ex);
}
//其他错误
@ExceptionHandler({Exception.class})
public String exception(Exception ex) {
return exceptionFormat(14, ex);
}
//自定义异常捕获
@ExceptionHandler({MyException.class})
public String myException(MyException ex) {
System.out.println("1111111111111111111");
return exceptionFormat(999, ex);
}
private String exceptionFormat(Integer code, T ex) {
log.error(String.format(logExceptionFormat, code, ex.getMessage()));
return JsonResult.failed(code, ex.getMessage());
}
}
建立JsonResult:
@Data 注解是 Lombok 项目的注解,不用手动的去添加setter,getter
package com.hll.demo.model;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import lombok.Data;
@Data
public class JsonResult {
private int code; //返回码 非0即失败
private String msg; //消息提示
private Map data; //返回的数据
public JsonResult(){};
public JsonResult(int code, String msg, Map data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public static String success() {
return success(new HashMap<>(0));
}
public static String success(Map data) {
return JSON.toJSONString(new JsonResult(0, "解析成功", data));
}
public static String failed() {
return failed("解析失败");
}
public static String failed(String msg) {
return failed(-1, msg);
}
public static String failed(int code, String msg) {
return JSON.toJSONString(new JsonResult(code, msg, new HashMap<>(0)));
}
}
自定义一个自己的异常类:MyException
package com.hll.demo.exception;
/**
* 自定义异常
* @author hll
* @date 2018年5月25日
*/
public class MyException extends Exception {
private static final long serialVersionUID = 1L;
private String code;
private String msg;
public MyException() {}
public MyException(String code, String msg) {
this.code = code;
this.msg = msg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
application.yml配置
#引入日志配置文件
#===================================== log =============================
logging:
config: classpath:logback-boot.xml
log配置文件
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) (%file:%line\)- %m%npattern>
<charset>UTF-8charset>
encoder>
appender>
<appender name="syslog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${catalina.base}/mylog/sys.logFile>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${catalina.base}/mylog/sys.%d.%i.logfileNamePattern>
<maxHistory>30maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>1KBmaxFileSize>
timeBasedFileNamingAndTriggeringPolicy>
rollingPolicy>
<encoder>
<pattern>
%d %p (%file:%line\)- %m%n
pattern>
<charset>UTF-8charset>
encoder>
appender>
<root level="info">
<appender-ref ref="STDOUT" />
root>
<logger name="com.hll.demo" level="DEBUG">
<appender-ref ref="syslog" />
logger>
configuration>
开始测试:LogTestController
package com.hll.demo.controller;
import java.util.HashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.hll.demo.exception.MyException;
import com.hll.demo.model.JsonResult;
/**
* 日志测试controller
* @author hll
* @date 2018年5月26日
*/
@RestController
public class LogTestController {
protected static Logger logger = LoggerFactory.getLogger(LogTestController.class);
@RequestMapping("/logtest")
public JsonResult Test(@RequestParam(value = "role") Integer role) throws Exception {
logger.info("访问了controller");
int i = role;
//Exception异常会自动拦截,这里只是做个测试自定义异常
if (i<0) {
//int j = i / 0;
throw new MyException("999", "异常");
} else {
return new JsonResult(200, "成功", new HashMap<>(0));
}
}
}
打开浏览器输入地址:http://localhost:8080/demo/logtest
在tomcat路径下,会有mylog文件夹,查看里面的日志会看到下面的信息,该Controller有个必填的请求参数,如果没写就会有Required Integer parameter ‘role’ is not present
在tomcat路径下,会有mylog文件夹,查看里面的日志会看到下面的信息
打开浏览器输入地址:http://localhost:8080/demo/logtest?role=-1
接着测试,role为-1时就会进自定义异常
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.hllgroupId>
<artifactId>demoartifactId>
<version>0.0.1-SNAPSHOTversion>
<packaging>warpackaging>
<name>demoname>
<description>Demo project for Spring Bootdescription>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.13.RELEASEversion>
<relativePath/>
parent>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-freemarkerartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jta-narayanaartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.47version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.16.8version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
项目中的ServletInitializer类,springboot本身是直接通过main方法启动自带的tomcat运行项目的。如果想通过自己的tomcat启动springboot项目。建立一个ServletInitializer类:
然后就可以和普通的web项目一样启动起来了。
package com.hll.demo;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
/**
* @author hll
* @date 2018年6月15日
*/
public class ServletInitializer extends SpringBootServletInitializer{
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(DemoApplication.class);
}
}