我刚刚在我的Spring Boot应用程序中创建了一个controlleradvice,并试图在该建议中获取返回值对象:
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
response.setStatusCode(HttpStatus.OK);
int status = <from returnValue>;
return ResponseEntity.status(HttpStatus.valueOf(status)).body(body);
}
}
以及在我的控制器中:
return new ResponseEntity(HttpStatus.NO_CONTENT);
这里的逻辑总是发送200个状态代码,但是在响应中我们有实际的状态代码:
{
"headers": {},
"body": {},
"statusCode": "NO_CONTENT",
"statusCodeValue": 201
}
所以我的问题是我不知道如何使用returnType访问beforeBodyWrite方法中的returnValue。 在IDE中调试时,可以看到returnValue已添加到returnType。
答案 0 :(得分:1)
根据您的问题,我假设您需要控制器始终发送200,并将实际的主体,标头,状态代码包装在一个对象中并作为响应发送。
这是解决问题的方法
有一个自定义对象来包装您的回复
public class MyResponse {
Map<String, String> headers;
Object body;
String statusCode;
int statusCodeValue;
public MyResponse(Map<String, String> headers, Object body, String statusCode, int statusCodeValue) {
this.headers = headers;
this.body = body;
this.statusCode = statusCode;
this.statusCodeValue = statusCodeValue;
}
}
只需从您的控制器创建并返回包装器对象
@GetMapping("/user")
public MyResponse getUsers() {
int statusValue = 200;
List<User> users;
try {
users = service.getUser();
}
catch (UserNotFoundException ex) { statusValue = 404; }
catch (ActionNotAllowedException ex) { statusValue = 401; }
catch (Exception ex) { statusValue = 500;}
return new MyResponse(getHeaders(), users, statusValue, HttpStatus.valueOf(statusValue))
}
答案 1 :(得分:0)
编辑:刚刚测试过。效果很好!
不是使用returnType,而是使用响应来获取状态,该状态由调用建议的控制器方法传播。我将您的beforeBodyWrite重写为仅用于获取和设置状态的部分。这次我还没有测试过,但是请记住在另一个实例上进行测试。
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
java.lang.Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
ServerHttpResponse response) {
int status = HttpStatus.OK.value();
if (response instanceof ServletServerHttpResponse) {
status = ((ServletServerHttpResponse) response).getServletResponse().getStatus();
}
response.setStatusCode(HttpStatus.OK);
return ResponseEntity.status(HttpStatus.valueOf(status)).body(body);
}