众所周知目前前后端交互基本都采用标准的JSON结构{"code": 200, "message": "成功", "data": null}
不认识@ControllerAdvice注解之前接口是这样返回的
@GetMapping("/")
public BaseResponse<String> test() {
String testMsg = testService.getTestMsg();
return BaseResponse.ok(testMsg);
}
@GetMapping("/findUser/{id}")
public BaseResponse<User> findUserById(@PathVariable("id") Long userId) {
User user = testService.findUserById(userId);
return BaseResponse.ok(user);
}
BaseResponse为统一返回的对象
@Data
@EqualsAndHashCode
@NoArgsConstructor
public class BaseResponse<T> {
/**
* 响应码
*/
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 <T> BaseResponse<T> ok(@Nullable String msg, @Nullable T data) {
return new BaseResponse<>(HttpStatus.OK.value(), msg, data);
}
@NonNull
public static <T> BaseResponse<T> ok(@Nullable String msg) {
return ok(msg, null);
}
public static <T> BaseResponse<T> 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<Object> {
@Override
public boolean supports(MethodParameter returnType,
@NonNull Class<? extends HttpMessageConverter<?>> converterType) {
return AbstractJackson2HttpMessageConverter.class.isAssignableFrom(converterType);
}
@Override
@NonNull
public final Object beforeBodyWrite(@Nullable Object body,
@NonNull MethodParameter returnType,
@NonNull MediaType contentType,
@NonNull Class<? extends HttpMessageConverter<?>> 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<Object> baseResponse = BaseResponse.ok(returnBody);
bodyContainer.setValue(baseResponse);
}
}
去掉StringHttpMessageConvert消息转换器,否则Controller层接口返回String时不会转为统一的返回对象BaseResponse
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.removeIf(c -> c instanceof StringHttpMessageConverter);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。