简体   繁体   English

使用spring 3 restful以编程方式更改http响应状态

[英]Programmatically change http response status using spring 3 restful

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. 控制器有一个错误处理机制,在错误处理选项中它总是返回期望失败状态代码417.但我需要根据错误类型设置动态错误Http状态代码,如500,403等。 How do I do this? 我该怎么做呢?

You need to change the type of the output value ResponseEntity . 您需要更改输出值ResponseEntity的类型。 Answer here: How to respond with HTTP 400 error in a Spring MVC @ResponseBody method returning String? 在这里回答: 如何在返回String的Spring MVC @ResponseBody方法中响应HTTP 400错误?

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. 我仍然需要指导好的做法。

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。

You can use an Aspect for your API. 您可以为API使用Aspect。 If you define an @Around interceptor for your service, you can change the response content. 如果为服务定义@Around拦截器,则可以更改响应内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM