在 ControllerAdvice 中获取返回值
Get returnValue in ControllerAdvice
我刚刚在我的 spring 引导应用程序中创建了一个 controlleradvice,并试图在建议中获取 return 值对象:
@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.
根据您的问题,我假设您需要控制器始终发送 200 并将实际的 body、header、状态代码包装在 object 中并作为响应发送。
这里有一个解决方法
自定义 object 来包装您的回复
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;
}
}
只需从您的控制器return创建包装器object
@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))
}
编辑:刚刚对此进行了测试。这很好用!
不使用 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);
}
我刚刚在我的 spring 引导应用程序中创建了一个 controlleradvice,并试图在建议中获取 return 值对象:
@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.
根据您的问题,我假设您需要控制器始终发送 200 并将实际的 body、header、状态代码包装在 object 中并作为响应发送。
这里有一个解决方法
自定义 object 来包装您的回复
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;
}
}
只需从您的控制器return创建包装器object
@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))
}
编辑:刚刚对此进行了测试。这很好用!
不使用 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);
}