示例
项目结构
.
├── build.gradle
└── src
└── main
├── java
│ └── hello
│ ├── Application.java
│ ├── BaseResponse.java
│ ├── CustomExceptionHandler.java
│ ├── Greeting.java
│ ├── GreetingController.java
│ └── ex
│ ├── CustomException01.java
│ └── CustomException02.java
└── resources
build.gradle
buildscript {
repositories {
maven { url 'http://mirrors.cloud.tencent.com/nexus/repository/maven-public/' }
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile group: 'org.projectlombok', name: 'lombok', version: '1.18.0'
}
自定义异常
package hello.ex;
public class CustomException01 extends RuntimeException {
}
package hello.ex;
public class CustomException02 extends RuntimeException {
}
BaseResponse 类
package hello;
import lombok.Data;
import java.io.Serializable;
@Data
public class BaseResponse implements Serializable {
private Boolean success;
private String msg;
private Object result;
public static BaseResponse success(String msg, Object result) {
return new BaseResponse(true, msg, result);
}
public static BaseResponse fail(String msg, Object result) {
return new BaseResponse(false, msg, result);
}
private BaseResponse(Boolean isSuccess, String msg, Object result) {
this.success = isSuccess;
this.msg = msg;
this.result = result;
}
}
Greeting 类
package hello;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Greeting {
private long id;
private String content;
}
Application 类:程序主入口
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
GreetingController 类
package hello;
import hello.ex.CustomException01;
import hello.ex.CustomException02;
import org.springframework.web.bind.annotation.*;
@RestController
public class GreetingController {
@RequestMapping(value = "/greeting1")
public BaseResponse greeting1(@RequestParam(value="name", defaultValue="World") String name,
@RequestParam(value="raiseEx", defaultValue="false") Boolean raiseEx) {
if(raiseEx) {
throw new CustomException01();
}
return BaseResponse.success("", new Greeting(1L, String.format("Hello, %s! This is greeting1", name)));
}
@RequestMapping(value = "/greeting2")
public BaseResponse greeting2(@RequestParam(value="name", defaultValue="World") String name,
@RequestParam(value="raiseEx", defaultValue="false") Boolean raiseEx) {
if(raiseEx) {
throw new CustomException02();
}
return BaseResponse.success("", new Greeting(2L, String.format("Hello, %s! This is greeting2", name)));
}
}
CustomExceptionHandler 类:使用 @ExceptionHandler 处理controller抛出的异常
package hello;
import hello.ex.CustomException01;
import hello.ex.CustomException02;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import java.util.Set;
@ControllerAdvice // 注意,这个必须有,用于声明是对 controller 控制器的增强。
public class CustomExceptionHandler {
@ExceptionHandler({CustomException01.class,})
public ResponseEntity<Object> handleCustomException01Exception(CustomException01 ex, WebRequest request) throws Exception {
return new ResponseEntity<>(BaseResponse.fail("CustomException01异常", null), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler({CustomException02.class,})
@ResponseBody
@ResponseStatus(value = HttpStatus.BAD_REQUEST) // 自定义 HTTP 响应状态码
public final BaseResponse handleCustomException02Exception(CustomException02 ex, WebRequest request) throws Exception {
return BaseResponse.fail("CustomException02异常", null);
}
}
是的,@ExceptionHandler
要和@ControllerAdvice
配合使用。
注意,同一个Exception不能被多次ExceptionHandler,否则会启动程序时会报错。
运行示例
浏览器请求http://127.0.0.1:8080/greeting1
, 响应体:
{"success":true,"msg":"","result":{"id":1,"content":"Hello, World! This is greeting1"}}
浏览器请求http://127.0.0.1:8080/greeting1?raiseEx=true
,响应400 Bad Request, 响应体:
{"success":false,"msg":"CustomException01异常","result":null}
浏览器请求http://127.0.0.1:8080/greeting2
,响应体:
{"success":true,"msg":"","result":{"id":2,"content":"Hello, World! This is greeting2"}}
浏览器请求http://127.0.0.1:8080/greeting2?raiseEx=true
,响应400 Bad Request, 响应体:
{"success":false,"msg":"CustomException02异常","result":null}