SpringBoot 통합 응답 체 솔 루 션

10602 단어 자바springboot
머리말
최근 자신 을 최적화 하기 전에Spring AOP의 통일 응답 체 를 바탕 으로 하 는 실현 방안.
통일 응답 체 는 무엇 입 니까?현재 의 전후 단 분리 구조 에서 백 엔 드 는 주로RESTful API의 데이터 인터페이스 이다.
그러나HTTP상태 코드 의 수량 이 제한 되 어 있 고 업무 가 증가 함 에 따라HTTP상태 코드 는 업무 중 에 발생 한 이상 상황 을 잘 나타 내지 못 한다.
그러면 응답 이 되 돌아 오 는JSON데 이 터 를 수정 하여 다음 과 같은 고유 한 필드 를 가 져 올 수 있 습 니 다.
{
    "code": 10000,
    "msg": "success",
    "data": {
        "id": 2,
        "name": "test"
    }
}

그 중에서 관건 적 인 속성의 용 도 는 다음 과 같다.
  • code결 과 를 되 돌려 주 는 상태 코드
  • msg결과 복귀 소식
  • data되 돌아 오 는 업무 데이터
  • 3개 속성 은 고유 속성 으로 매번 응답 결과 가 있 습 니 다.
    수요AOP을 바탕 으로 하 는 실현 방안 을 대체 할 수 있 기 를 바 라 며 다음 과 같은 몇 가 지 를 만족 시 켜 야 한다.
  • 기 존의AOP기반 실현 방안 에 필요 한Controller의 반환 유형 은Object이 고 새로운 방안 이 반환 유형
  • 을 제한 하지 않 아야 한다.
  • 기 존의AOP기반 실현 방안 은 절단면 표현 식+주해 제어 접점Controller(주해 의 가방 이름 수정 은 절단면 표현 식 의 수정 을 초래 할 수 있 습 니 다.즉,두 곳 을 수정 해 야 합 니 다)을 통 해 새로운 방안 이 필요 합 니 다.절단면 표현 식
  • 을 수정 하지 않 아 도 됩 니 다.
    아이디어
    상기 수 요 를 바탕 으로 사용SpringController강화 체 제 를 선택 하 는데 그 중에서 관건 적 인 유형 은 다음 과 같다3.
  • @ControllerAdvice:클래스 주석,지정Controller프로세서 클래스 를 강화 하 는 데 사 용 됩 니 다.
  • ResponseBodyAdvice:인터페이스,실현 후beforeBodyWrite()방법 후 응답 하 는body을 수정 할 수 있 으 며 결합@ControllerAdvice하여 사용 해 야 한다.
  • @ExceptionHandler:방법 주 해 는 이상 처리 방법 을 지정 하 는 데 사용 되 며@ControllerAdvice@ResponseBody을 결합 하여 사용 해 야 한다.

  • 예제 키 코드
    이 예제 에서 사용 하 는Spring Boot버 전 은2.1.6.RELEASE이 며,동시에 개발 도구 설치lombok플러그 인 이 필요 합 니 다.
    도입 의존
        
            
            
                org.springframework.boot
                spring-boot-starter-web
            
    
            
            
                org.projectlombok
                lombok
                true
            
    
            
            
                org.springframework.boot
                spring-boot-starter-test
                test
            
        

    통합 응답 체Controller증강 후 통일 응답 체 대응 대상
    import lombok.AllArgsConstructor;
    import lombok.Data;
    
    import java.io.Serializable;
    
    /**
     *         
     * @author NULL
     * @date 2019-07-16
     */
    @Data
    @AllArgsConstructor
    public class ResponseResult implements Serializable {
        /**
         *      
         */
        private Integer code;
        /**
         *     
         */
        private String msg;
        /**
         *   
         */
        private Object data;
    
    }

    통일 응답 주석
    통일 응답 주 해 는 통일 응답 강화 여 부 를 표시 하 는 주석 입 니 다.
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     *       
    * , * @author NULL * @date 2019-07-16 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) public @interface BaseResponse { }

    상태 코드 매 거
    통합 응답 체 에서 되 돌아 오 는 상태 코드code와 상태 정보msg에 대응 하 는 매 거 진 클래스
    /**
     *      
     *
     * @author NULL
     * @date 2019-07-16
     */
    public enum ResponseCode {
        /**
         *         
         */
        SUCCESS(10000, "success"),
        /**
         *          
         */
        RESOURCES_NOT_EXIST(10001, "     "),
        /**
         *                  
         */
        SERVICE_ERROR(50000, "     ");
        /**
         *    
         */
        private int code;
        /**
         *     
         */
        private String msg;
    
        ResponseCode(int code, String msg) {
            this.code = code;
            this.msg = msg;
        }
    
        public int getCode() {
            return code;
        }
    
        public String getMsg() {
            return msg;
        }
    }

    업무 이상 클래스
    업무 이상 류 는 업무 와 관련 된 이상 을 식별 하 는 데 사용 되 므 로 이 이상 류 는 강제 적 으로ResponseCode구조 방법 으로 참여 해 야 한다.그러면 이상 을 포착 하여 되 돌아 오 는 상태 코드 정 보 를 얻 을 수 있다.
    import com.rjh.web.response.ResponseCode;
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    
    /**
     *      ,       ,        
     *
     * @author NULL
     * @since  2019-07-16
     */
    @Data
    @EqualsAndHashCode(callSuper = false)
    public class BaseException extends RuntimeException{
    
        private ResponseCode code;
    
        public BaseException(ResponseCode code) {
            this.code = code;
        }
    
        public BaseException(Throwable cause, ResponseCode code) {
            super(cause);
            this.code = code;
        }
    }

    이상 처리 클래스
    실행 중 포획 되 지 않 은 이상 한 처리 클래스 를 처리 합 니 다.
    import com.rjh.web.exception.BaseException;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    /**
     *      
     *
     * @author NULL
     * @since  2019-07-16
     */
    @ControllerAdvice(annotations = BaseResponse.class)
    @ResponseBody
    @Slf4j
    public class ExceptionHandlerAdvice {
        /**
         *       Exception
         * @param e   
         * @return      
         */
        @ExceptionHandler(Exception.class)
        public ResponseResult handleException(Exception e){
            log.error(e.getMessage(),e);
            return new ResponseResult(ResponseCode.SERVICE_ERROR.getCode(),ResponseCode.SERVICE_ERROR.getMsg(),null);
        }
    
        /**
         *       RuntimeException
         * @param e      
         * @return      
         */
        @ExceptionHandler(RuntimeException.class)
        public ResponseResult handleRuntimeException(RuntimeException e){
            log.error(e.getMessage(),e);
            return new ResponseResult(ResponseCode.SERVICE_ERROR.getCode(),ResponseCode.SERVICE_ERROR.getMsg(),null);
        }
    
        /**
         *       BaseException
         * @param e     
         * @return      
         */
        @ExceptionHandler(BaseException.class)
        public ResponseResult handleBaseException(BaseException e){
            log.error(e.getMessage(),e);
            ResponseCode code=e.getCode();
            return new ResponseResult(code.getCode(),code.getMsg(),null);
        }
    }

    응답 강화 클래스Controller강 화 된 통일 응답 체 처리 류 는 이상 처리 류 가 이미 강화 되 었 으 므 로 돌아 오 는 대상 이 통일 응답 체 대상 인지 판단 해 야 한다.
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.core.MethodParameter;
    import org.springframework.http.MediaType;
    import org.springframework.http.server.ServerHttpRequest;
    import org.springframework.http.server.ServerHttpResponse;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
    
    /**
     *         
     * @author NULL
     * @date 2019-07-16
     */
    @ControllerAdvice(annotations = BaseResponse.class)
    @Slf4j
    public class ResponseResultHandlerAdvice implements ResponseBodyAdvice {
    
        @Override
        public boolean supports(MethodParameter returnType, Class converterType) {
            log.info("returnType:"+returnType);
            log.info("converterType:"+converterType);
            return true;
        }
    
        @Override
        public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
            if(MediaType.APPLICATION_JSON.equals(selectedContentType) || MediaType.APPLICATION_JSON_UTF8.equals(selectedContentType)){ //      Content-Type JSON   body
                if(body instanceof ResponseResult){ //                ,     body
                    return body;
                }else{
                    //                    ,            
                    ResponseResult responseResult =new ResponseResult(ResponseCode.SUCCESS.getCode(),ResponseCode.SUCCESS.getMsg(),body);
                    return responseResult;
                }
            }
            //  JSON  body      
            return body;
        }
    }

    사용 예시
    우선 대상 을 하나 준비 하 겠 습 니 다.
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    
    import java.io.Serializable;
    
    /**
     *    
     * @author NULL
     * @date 2019-07-16
     */
    @Data
    @EqualsAndHashCode
    public class User implements Serializable {
    
        private Integer id;
    
        private String name;
        
    }

    그리고 간단 한 거 하나 준비 하면 돼 요.
    import com.rjh.web.entity.User;
    import com.rjh.web.exception.BaseException;
    import com.rjh.web.response.BaseResponse;
    import com.rjh.web.response.ResponseCode;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     *     Controller
     *
     * @author NULL
     * @date 2019-07-16
     */
    @BaseResponse
    @RestController
    @RequestMapping("users")
    public class UserController {
    
        @GetMapping("/{userId}")
        public User getUserById(@PathVariable Integer userId){
            if(userId.equals(0)){
                throw new BaseException(ResponseCode.RESOURCES_NOT_EXIST);
            }
            if(userId.equals(1)){
                throw new RuntimeException();
            }
            User user=new User();
            user.setId(userId);
            user.setName("test");
            return user;
        }
        
    }

    실행 결과
  • 브 라 우 저 에서 직접 방문Conrtoller하면 결 과 를 다음 과 같이 되 돌려 줍 니 다(결 과 는 포맷 처리):
    {
        "code": 10001,
        "msg": "     ",
        "data": null
    }
  • 브 라 우 저 에서 직접 방문User하면 결 과 를 다음 과 같이 되 돌려 줍 니 다(결 과 는 포맷 처리):
    {
        "code": 50000,
        "msg": "     ",
        "data": null
    }
  • 브 라 우 저 에서 직접 방문UserController하면 결 과 를 다음 과 같이 되 돌려 줍 니 다(결 과 는 포맷 처리):
    {
        "code": 10000,
        "msg": "success",
        "data": {
            "id": 2,
            "name": "test"
        }
    }
  • 운행 결 과 를 통 해 알 수 있 듯 이 통일 적 인 응답 강화 가 이미 효력 이 발생 했 고 이상 을 잘 처리 할 수 있다.
    예제 코드 주소
    다음은 이 예제 의 코드 주소 입 니 다.괜 찮 거나 도움 이 된다 면http://127.0.0.1:8080/users/0을 주 십시오.https://github.com/spring-bas...
    참고 자료
  • https://docs.spring.io/spring...
  • https://docs.spring.io/spring...
  • 좋은 웹페이지 즐겨찾기