【问题标题】:Programmatically change http response status using spring 3 restful使用 spring 3 restful 以编程方式更改 http 响应状态
【发布时间】: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等。我该怎么做?

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案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。

      【讨论】:

      【解决方案3】:

      您可以为您的 API 使用一个方面。如果你为你的服务定义了一个@Around 拦截器,你可以改变响应内容。

      【讨论】:

        【解决方案4】:

        您需要更改输出值的类型ResponseEntity。在这里回答: How to respond with HTTP 400 error in a Spring MVC @ResponseBody method returning String?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-12-14
          • 1970-01-01
          • 2011-07-01
          • 2011-08-22
          • 2020-01-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多