Java 使用 spring 3 restful 以编程方式更改 http 响应状态
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20067057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Programmatically change http response status using spring 3 restful
提问by 1Sundorbon_bangla
I have a controller like below
我有一个像下面这样的控制器
@Controller("myController")
@RequestMapping("api")
public class MyController {
@RequestMapping(method = RequestMethod.GET, value = "/get/info/{id}", headers = "Accept=application/json")
public @ResponseBody
Student getInfo(@PathVariable String info) {
.................
}
@ExceptionHandler(Throwable.class)
@ResponseStatus( HttpStatus.EXPECTATION_FAILED)
@ResponseBody
public String handleIOException(Throwable ex) {
ErrorResponse errorResponse = errorHandler.handelErrorResponse(ex);
return errorResponse.toString();
}
}
The controller has an error handling mechanism, in the error handling option it always return expectation fail status code 417. But I need to set a dynamic error Http status code like 500, 403 etc depending on type of error. How do I do this?
控制器具有错误处理机制,在错误处理选项中,它总是返回预期失败状态代码 417。但我需要根据错误类型设置动态错误 Http 状态代码,如 500、403 等。我该怎么做呢?
回答by MartenCatcher
You need to change the type of the output value ResponseEntity. Answer here: How to respond with HTTP 400 error in a Spring MVC @ResponseBody method returning String?
您需要更改输出值ResponseEntity的类型。在这里回答: 如何在返回字符串的 Spring MVC @ResponseBody 方法中响应 HTTP 400 错误?
回答by Amir Kost
You can use an Aspect for your API. If you define an @Around interceptor for your service, you can change the response content.
您可以为您的 API 使用一个方面。如果为服务定义了@Around 拦截器,则可以更改响应内容。
回答by Steve
Going by the code above, you need to be more careful about which exceptions you are throwing and handling. Setting up an exception handler for Throwable seems overly broad.
按照上面的代码,您需要更加小心地抛出和处理哪些异常。为 Throwable 设置异常处理程序似乎过于宽泛。
The way I do this is to create an ErrorMessage class with my XML/JSON marshalling annotations.
我这样做的方法是使用我的 XML/JSON 编组注释创建一个 ErrorMessage 类。
@XmlRootElement(name = "error")
public class ErrorMessage {
private Throwable exception;
private String message;
public ErrorMessage() {
this.message = "";
}
public ErrorMessage(String message) {
this.message = message;
}
public ErrorMessage(Throwable exception) {
this.exception = exception;
this.message = exception.getLocalizedMessage();
}
@XmlTransient
@JsonIgnore
public Throwable getException() {
return exception;
}
public void setException(Throwable exception) {
this.exception = exception;
}
@XmlElement(name = "message")
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
With that in place, I tend to create my own application exceptions and then create my exception handler methods such as:
有了这个,我倾向于创建自己的应用程序异常,然后创建我的异常处理程序方法,例如:
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseBody
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorMessage handleResourceNotFoundException(ResourceNotFoundException e, HttpServletRequest req) {
return new ErrorMessage(e);
}
@ExceptionHandler(InternalServerErrorException.class)
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorMessage handleInternalServerErrorException(InternalServerErrorException e, HttpServletRequest req) {
return new ErrorMessage(e);
}
With those in place, I just need to throw appropriate exceptions from my controller methods. For instance, if I throw a ResourceNotFoundException, then Spring will redirect that to my handleResourceNotFoundException method, which returns a 404, and that will also return JSON or XML representing the error.
有了这些,我只需要从我的控制器方法中抛出适当的异常。例如,如果我抛出 ResourceNotFoundException,那么 Spring 会将其重定向到我的 handleResourceNotFoundException 方法,该方法返回 404,并且还将返回表示错误的 JSON 或 XML。
回答by 1Sundorbon_bangla
I get a solution and going to share this and also like to know any good suggestions.
我得到了一个解决方案并打算分享这个,也想知道任何好的建议。
@Controller("myController")
@RequestMapping("api")
public class MyController {
@RequestMapping(method = RequestMethod.GET, value = "/get/info/{id}", headers = "Accept=application/json")
public @ResponseBody
Student getInfo(@PathVariable String info) {
// ...
}
}
// ...
@ExceptionHandler(Throwable.class)
//@ResponseStatus( HttpStatus.EXPECTATION_FAILED)<<remove this line
@ResponseBody
public String handleIOException(HttpServletResponse httpRes,Throwable ex){ // <<Change this
if (some condition) {
httpRes.setStatus(HttpStatus.BAD_GATEWAY.value());
} else {
httpRes.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
}
ErrorResponse errorResponse = errorHandler.handleErrorResponse(ex);
return errorResponse.toString();
}
Expected out in rest client :
预计在休息客户端:
502 Bad Gateway
{
"status":"BAD_GATEWAY",
"error":"java.lang.UnsupportedOperationException",
"message":"Some error message"
}
Thanks for your replies. I still need pointers for good practices.
感谢您的回复。我仍然需要良好实践的指针。