使用 spring 3 restful 以编程方式更改 http 响应状态
Posted
技术标签:
【中文标题】使用 spring 3 restful 以编程方式更改 http 响应状态【英文标题】:Programmatically change http response status using spring 3 restful 【发布时间】:2013-12-02 17:46:39 【问题描述】:我有一个像下面这样的控制器
@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();
控制器有一个错误处理机制,在错误处理选项中它总是返回期望失败状态码417。但我需要根据错误类型设置一个动态错误Http状态码,如500、403等。我该怎么做?
【问题讨论】:
【参考方案1】:我得到了一个解决方案并打算分享这个,也想知道任何好的建议。
@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();
预计在休息客户端:
502 Bad Gateway
"status":"BAD_GATEWAY",
"error":"java.lang.UnsupportedOperationException",
"message":"Some error message"
感谢您的回复。我仍然需要一些好的做法。
【讨论】:
【参考方案2】:按照上面的代码,您需要更加小心您正在抛出和处理哪些异常。为 Throwable 设置异常处理程序似乎过于宽泛。
我这样做的方法是使用我的 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;
有了这些,我倾向于创建自己的应用程序异常,然后创建我的异常处理程序方法,例如:
@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);
有了这些,我只需要从我的控制器方法中抛出适当的异常。例如,如果我抛出 ResourceNotFoundException,那么 Spring 会将其重定向到我的 handleResourceNotFoundException 方法,该方法返回 404,并且还会返回表示错误的 JSON 或 XML。
【讨论】:
我在让它与自定义异常一起工作时遇到了一些问题,所以我很高兴找到这个table about exception types that Spring maps to different status codes by default。 (与我的自定义(Spring Boot)ErrorController 配合得很好。)【参考方案3】:您可以为您的 API 使用一个方面。如果你为你的服务定义了一个@Around 拦截器,你可以改变响应内容。
【讨论】:
【参考方案4】:您需要更改输出值的类型ResponseEntity。在这里回答: How to respond with HTTP 400 error in a Spring MVC @ResponseBody method returning String?
【讨论】:
以上是关于使用 spring 3 restful 以编程方式更改 http 响应状态的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Spring Security 3.1 以编程方式登录用户
Spring REST security - 以不同的方式保护不同的 URL
如何以编程方式为 Tyrus WebSocket @ServerEndpoint 启用 WSS