SpringBoot 전역 이상 을 우아 하 게 처리 하 는 방법
15430 단어 springboot전체 국면이상 하 다
이 글 은 주로 SpringBoot 프로젝트 의 전체적인 이상 처 리 를 소개 한다.
SpringBoot 전역 이상 준비
설명:프로젝트 를 직접 가 져 오 려 면 끝까지 뛰 어 내 려 링크 를 통 해 프로젝트 코드 를 다운로드 할 수 있 습 니 다.
개발 준비
환경 요구
JDK:1.8
SpringBoot:1.5.17.RELEASE
우선 Maven 의 의존:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.17.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.41</version>
</dependency>
</dependencies>
설정 파일 은 기본적으로 변경 할 필요 가 없습니다.전역 이상 처 리 는 코드 에서 만 이 루어 지면 됩 니 다.코드 작성
SpringBoot 의 프로젝트 는 이미 어느 정도 이상 처 리 를 했 지만 우리 개발 자 에 게 는 적합 하지 않 을 수 있 습 니 다.따라서 우 리 는 이러한 이상 을 통일 적 으로 포착 하고 처리 해 야 합 니 다.SpringBoot 에는 Controller Advice 의 설명 이 있 습 니 다.이 주 해 를 사용 하면 전체 이상 캡 처 를 열 었 음 을 표시 합 니 다.우 리 는 하나의 방법 으로 ExceptionHandler 주 해 를 사용 한 다음 에 캡 처 이상 유형 을 정의 하면 이 캡 처 이상 을 통일 적 으로 처리 할 수 있 습 니 다.
우 리 는 아래 의 이 예시 에 근거 하여 이 주해 가 어떻게 사용 되 는 지 보 자.
예제 코드:
@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(value =Exception.class)
public String exceptionHandler(Exception e){
System.out.println(" ! :"+e);
return e.getMessage();
}
}
상술 한 예 에서 우 리 는 포획 한 이상 에 대해 간단 한 2 차 처 리 를 하고 이상 한 정 보 를 되 돌려 준다.비록 이런 것 은 우리 가 이상 한 원인 을 알 수 있 지만 많은 상황 에서 말하자면 인성 화 되 지 않 고 우리 의 요구 에 부합 되 지 않 을 수도 있다.그러면 우 리 는 사용자 정의 이상 류 와 매 거 진 류 를 통 해 우리 가 원 하 는 데 이 터 를 실현 할 수 있 습 니 다.
사용자 정의 기본 인터페이스 클래스
먼저 기본 인터페이스 클래스 를 정의 합 니 다.사용자 정의 오류 설명 매 거 진 클래스 는 이 인 터 페 이 스 를 실현 해 야 합 니 다.
코드 는 다음 과 같 습 니 다:
public interface BaseErrorInfoInterface {
/** */
String getResultCode();
/** */
String getResultMsg();
}
사용자 정의 매 거 진 클래스그리고 나 서 우 리 는 매 거 진 종 류 를 사용자 정의 하고 이 인 터 페 이 스 를 실현 합 니 다.
코드 는 다음 과 같 습 니 다:
public enum CommonEnum implements BaseErrorInfoInterface {
//
SUCCESS("200", " !"),
BODY_NOT_MATCH("400"," !"),
SIGNATURE_NOT_MATCH("401"," !"),
NOT_FOUND("404", " !"),
INTERNAL_SERVER_ERROR("500", " !"),
SERVER_BUSY("503"," , !")
;
/** */
private String resultCode;
/** */
private String resultMsg;
CommonEnum(String resultCode, String resultMsg) {
this.resultCode = resultCode;
this.resultMsg = resultMsg;
}
@Override
public String getResultCode() {
return resultCode;
}
@Override
public String getResultMsg() {
return resultMsg;
}
}
사용자 정의 이상 클래스그리고 우 리 는 우리 가 발생 한 업무 이상 을 처리 하기 위해 이상 종 류 를 사용자 정의 하고 있 습 니 다.
코드 는 다음 과 같 습 니 다:
public class BizException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
*
*/
protected String errorCode;
/**
*
*/
protected String errorMsg;
public BizException() {
super();
}
public BizException(BaseErrorInfoInterface errorInfoInterface) {
super(errorInfoInterface.getResultCode());
this.errorCode = errorInfoInterface.getResultCode();
this.errorMsg = errorInfoInterface.getResultMsg();
}
public BizException(BaseErrorInfoInterface errorInfoInterface, Throwable cause) {
super(errorInfoInterface.getResultCode(), cause);
this.errorCode = errorInfoInterface.getResultCode();
this.errorMsg = errorInfoInterface.getResultMsg();
}
public BizException(String errorMsg) {
super(errorMsg);
this.errorMsg = errorMsg;
}
public BizException(String errorCode, String errorMsg) {
super(errorCode);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public BizException(String errorCode, String errorMsg, Throwable cause) {
super(errorCode, cause);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public String getMessage() {
return errorMsg;
}
@Override
public Throwable fillInStackTrace() {
return this;
}
}
사용자 정의 데이터 형식참고 로 데이터 전송 형식 을 정의 합 니 다.
코드 는 다음 과 같 습 니 다:
public class ResultBody {
/**
*
*/
private String code;
/**
*
*/
private String message;
/**
*
*/
private Object result;
public ResultBody() {
}
public ResultBody(BaseErrorInfoInterface errorInfo) {
this.code = errorInfo.getResultCode();
this.message = errorInfo.getResultMsg();
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
/**
*
*
* @return
*/
public static ResultBody success() {
return success(null);
}
/**
*
* @param data
* @return
*/
public static ResultBody success(Object data) {
ResultBody rb = new ResultBody();
rb.setCode(CommonEnum.SUCCESS.getResultCode());
rb.setMessage(CommonEnum.SUCCESS.getResultMsg());
rb.setResult(data);
return rb;
}
/**
*
*/
public static ResultBody error(BaseErrorInfoInterface errorInfo) {
ResultBody rb = new ResultBody();
rb.setCode(errorInfo.getResultCode());
rb.setMessage(errorInfo.getResultMsg());
rb.setResult(null);
return rb;
}
/**
*
*/
public static ResultBody error(String code, String message) {
ResultBody rb = new ResultBody();
rb.setCode(code);
rb.setMessage(message);
rb.setResult(null);
return rb;
}
/**
*
*/
public static ResultBody error( String message) {
ResultBody rb = new ResultBody();
rb.setCode("-1");
rb.setMessage(message);
rb.setResult(null);
return rb;
}
@Override
public String toString() {
return JSONObject.toJSONString(this);
}
}
사용자 정의 전역 이상 처리 클래스마지막 으로 전역 이상 처 리 를 사용자 정의 하 는 클래스 를 만 들 고 있 습 니 다.
코드 는 다음 과 같 습 니 다:
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
*
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = BizException.class)
@ResponseBody
public ResultBody bizExceptionHandler(HttpServletRequest req, BizException e){
logger.error(" ! :{}",e.getErrorMsg());
return ResultBody.error(e.getErrorCode(),e.getErrorMsg());
}
/**
*
* @param req
* @param e
* @return
*/
@ExceptionHandler(value =NullPointerException.class)
@ResponseBody
public ResultBody exceptionHandler(HttpServletRequest req, NullPointerException e){
logger.error(" ! :",e);
return ResultBody.error(CommonEnum.BODY_NOT_MATCH);
}
/**
*
* @param req
* @param e
* @return
*/
@ExceptionHandler(value =Exception.class)
@ResponseBody
public ResultBody exceptionHandler(HttpServletRequest req, Exception e){
logger.error(" ! :",e);
return ResultBody.error(CommonEnum.INTERNAL_SERVER_ERROR);
}
}
여기 서 우 리 는 전체 이상 처리 기능 의 실현 과 테스트 에 만 사용 되 기 때문에 여기 서 우 리 는 하나의 실체 류 와 하나의 제어 층 류 를 추가 하면 된다.실체 류
또 만능 사용자 표(^^)
코드 는 다음 과 같 습 니 다:
public class User implements Serializable{
private static final long serialVersionUID = 1L;
/** */
private int id;
/** */
private String name;
/** */
private int age;
public User(){
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return JSONObject.toJSONString(this);
}
}
컨트롤 러 제어 층컨트롤 층 이쪽 도 간단 합 니 다.Restful 스타일 로 이 루어 진 CRUD 기능 을 사용 합 니 다.다른 것 은 제 가 일부러 이상 을 만들어 서 이 이상 을 포착 하고 처리 하도록 했 습 니 다.이 이상 중 에는 사용자 정의 이상 던 지기 도 있 고 빈 포인터 의 이상 던 지기 도 있 습 니 다.물론 예측 할 수 없 는 이상 던 지기 도 있 습 니 다.(여 기 는 형식 변환 이상 으로 대체 합 니 다)코드 작성 을 마 친 후에 이 이상 이 캡 처 되 어 처리 되 는 지 확인 하 겠 습 니 다!
코드 는 다음 과 같 습 니 다:
@RestController
@RequestMapping(value = "/api")
public class UserRestController {
@PostMapping("/user")
public boolean insert(@RequestBody User user) {
System.out.println(" ...");
// !
if(user.getName()==null){
throw new BizException("-1"," !");
}
return true;
}
@PutMapping("/user")
public boolean update(@RequestBody User user) {
System.out.println(" ...");
// ,
String str=null;
str.equals("111");
return true;
}
@DeleteMapping("/user")
public boolean delete(@RequestBody User user) {
System.out.println(" ...");
// ,
Integer.parseInt("abc123");
return true;
}
@GetMapping("/user")
public List<User> findByUser(User user) {
System.out.println(" ...");
List<User> userList =new ArrayList<>();
User user2=new User();
user2.setId(1L);
user2.setName("xuwujing");
user2.setAge(18);
userList.add(user2);
return userList;
}
}
앱 입구일반적인 SpringBoot 프로젝트 와 거의 같 습 니 다.
코드 는 다음 과 같 습 니 다:
@SpringBootApplication
public class App
{
public static void main( String[] args )
{
SpringApplication.run(App.class, args);
System.out.println(" ...");
}
}
기능 테스트우 리 는 이 프로그램 을 성공 적 으로 시작 한 후에 Postman 도 구 를 사용 하여 인터페이스 테스트 를 진행 했다.
우선 프로그램 이 정상적으로 작 동 하 는 지 확인 하고 GET 방식 으로 요청 합 니 다.
GET http://localhost:8181/api/user
다음 매개 변 수 를 되 돌려 줍 니 다:
{"id":1,"name":"xuwujing","age":18}
예제 그림:
프로그램 이 정상적으로 돌아 오 는 것 을 볼 수 있 습 니 다.사용자 정의 전역 이상 에 영향 을 주지 않 았 습 니 다.
그리고 사용자 정의 이상 이 정확하게 포착 되 고 처 리 될 수 있 는 지 다시 한번 테스트 해 봅 시다.
POST 방식 으로 요청
POST http://localhost:8181/api/user
Body 매개 변 수 는:
{"id":1,"age":18}
다음 매개 변 수 를 되 돌려 줍 니 다:
{"code":"-1","message":"사용자 이름 이 비어 있 으 면 안 됩 니 다!","result":null}
예제 그림:
우리 가 던 진 이상 을 데이터 로 밀봉 한 후 이상 을 되 돌려 주 는 것 을 알 수 있다.
그리고 빈 포인터 이상 이 정확하게 포착 되 고 처 리 될 수 있 는 지 다시 한번 테스트 해 보 자.사용자 정의 전역 이상 에서 우 리 는 빈 포인터 의 이상 처 리 를 정의 하 는 것 외 에 최고 단계 중 하나 인 Exception 이상 도 정의 합 니 다.그러면 빈 포인터 이상 이 발생 한 후에 어떤 것 을 우선 사용 하 시 겠 습 니까?여기 테스트 해 보 겠 습 니 다.
PUT 방식 으로 요청 합 니 다.
PUT http://localhost:8181/api/user
Body 매개 변 수 는:
{"id":1,"age":18}
다음 매개 변 수 를 되 돌려 줍 니 다:
{"code":"400","message":"요청 한 데이터 형식 이 맞지 않 습 니 다!","result":null}
예제 그림:
우 리 는 빈 지침 으로 돌아 가 는 이상 관 리 를 통 해 전체 이상 처리 하위 클래스 의 이상 을 우선 처리 할 수 있 음 을 알 수 있다.
이 이상 이 잡 힐 수 있 는 지 없 는 지 확인 해 보 자.
DELETE 방식 으로 요청 합 니 다.
DELETE http://localhost:8181/api/user
Body 매개 변 수 는:
{"id":1}
다음 매개 변 수 를 되 돌려 줍 니 다:
{"code":"500","message":"서버 내부 오류!","result":null}
전역 이상 처리 클래스 의 Exception 이상 처 리 를 사용자 정의 하 는 방법 을 사용 한 것 을 볼 수 있 습 니 다.
여기까지 테스트 가 끝 났 습 니 다.참고 로 전체 이상 처 리 는 상기 데이터 형식 을 처리 할 수 있 는 것 외 에 페이지 의 점프 도 처리 할 수 있 습 니 다.새로 추 가 된 이상 방법의 반환 처리 에 이 점프 경 로 를 입력 하고 Response Body 주 해 를 사용 하지 않 으 면 됩 니 다.세심 한 학생 들 은 GlobalException Handler 류 에서 Controller Advice 주해 가 아 닌 Controller Advice 주 해 를 사용 하 는 것 을 발견 할 수 있 습 니 다.RestController Advice 주 해 를 사용 하면 데 이 터 를 자동 으로 JSON 형식 으로 변환 합 니 다.이런 것 은 Controller 와 RestController 와 유사 하기 때문에 우 리 는 전체적인 이상 처 리 를 사용 한 후에 유연 한 선택 처 리 를 할 수 있 습 니 다.
기타
SpringBoot 의 우아 한 전역 이상 처리 에 관 한 글 은 여기까지 입 니 다.만약 타당 하지 않 으 면 지적 을 환영 합 니 다!
항목 주소
SpringBoot 전역 이상 처리 프로젝트 주소:
https://github.com/xuwujing/springBoot-study/tree/master/springboot-exceptionHandler
SpringBoot 전체 집합 주소:
https://github.com/xuwujing/springBoot-study
총결산
이상 은 이 글 의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가 치 를 가지 기 를 바 랍 니 다.여러분 의 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin Springboot -- 파트 14 사용 사례 REST로 전환하여 POST로 JSON으로 전환前回 前回 前回 記事 の は は で で で で で で を 使っ 使っ 使っ て て て て て リクエスト を を 受け取り 、 reqeustbody で 、 その リクエスト の ボディ ボディ を を 受け取り 、 関数 内部 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.