还再在Controller接口写统一返回的JSON结构?快来试试@ControllerAdvice注解

众所周知目前前后端交互基本都采用标准的JSON结构{"code": 200, "message": "成功", "data": null}
不认识@ControllerAdvice注解之前接口是这样返回的

    @GetMapping("/")
    public BaseResponse test() {
        String testMsg = testService.getTestMsg();
        return BaseResponse.ok(testMsg);
    }
    
    @GetMapping("/findUser/{id}")
    public BaseResponse findUserById(@PathVariable("id") Long userId) {
        User user = testService.findUserById(userId);
        return BaseResponse.ok(user);
    }

BaseResponse为统一返回的对象

@Data
@EqualsAndHashCode
@NoArgsConstructor
public class BaseResponse {

    /**
     * 响应码
     */
    private Integer code;

    /**
     * 响应消息
     */
    private String msg;

    /**
     * 响应数据
     */
    private T data;

    public BaseResponse(Integer status, String msg, T data) {
        this.code = status;
        this.msg = msg;
        this.data = data;
    }


    @NonNull
    public static  BaseResponse ok(@Nullable String msg, @Nullable T data) {
        return new BaseResponse<>(HttpStatus.OK.value(), msg, data);
    }

    @NonNull
    public static  BaseResponse ok(@Nullable String msg) {
        return ok(msg, null);
    }


    public static  BaseResponse ok(@Nullable T data) {
        return new BaseResponse<>(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), data);
    }
}

认识@ControllerAdvice注解之后接口是这样返回的

    @GetMapping("/")
    public String test() {
        String testMsg = testService.getTestMsg();
        return testMsg;
    }

    @GetMapping("/findUser/{id}")
    public User findUserById(@PathVariable("id") Long userId) {
        User user = testService.findUserById(userId);
        return user;
    }

使用了@ControllerAdvice 注解对Controller层的所有接口做拦截,然后使用BaseResponse进行统一的封装,这样就不必再在每个Controller接口里都去使用BaseResponse进行封装了

@ControllerAdvice("com.test.controller")
public class CommonResultControllerAdvice implements ResponseBodyAdvice {

    @Override
    public boolean supports(MethodParameter returnType,
                            @NonNull Class> converterType) {
        return AbstractJackson2HttpMessageConverter.class.isAssignableFrom(converterType);
    }

    @Override
    @NonNull
    public final Object beforeBodyWrite(@Nullable Object body,
                                        @NonNull MethodParameter returnType,
                                        @NonNull MediaType contentType,
                                        @NonNull Class> converterType,
                                        @NonNull ServerHttpRequest request,
                                        @NonNull ServerHttpResponse response) {
        MappingJacksonValue container = getOrCreateContainer(body);
        // The contain body will never be null
        beforeBodyWriteInternal(container);
        return container;
    }

    /**
     * Wrap the body in a {@link MappingJacksonValue} value container (for providing
     * additional serialization instructions) or simply cast it if already wrapped.
     */
    private MappingJacksonValue getOrCreateContainer(Object body) {
        return body instanceof MappingJacksonValue ? (MappingJacksonValue) body :
                new MappingJacksonValue(body);
    }

    private void beforeBodyWriteInternal(MappingJacksonValue bodyContainer) {
        // Get return body
        Object returnBody = bodyContainer.getValue();

        if (returnBody instanceof BaseResponse) {
            return;
        }

        BaseResponse baseResponse = BaseResponse.ok(returnBody);
        bodyContainer.setValue(baseResponse);
    }
}





你可能感兴趣的:(还再在Controller接口写统一返回的JSON结构?快来试试@ControllerAdvice注解)