java 返回 HttpStatus 代码 Spring REST 的更好方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27777518/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:22:17  来源:igfitidea点击:

Better approach to return HttpStatus code Spring REST

javaspringrestexceptionstatus

提问by azalut

I develope rest service using spring for a long time, and till now my approach to return http status code was like this:

我用spring开发了很长时间的rest服务,直到现在我返回http状态码的方法是这样的:

    @RequestMapping(value = "/sth")
    public void name(HttpServletResponse response){
        boolean lever = service.doSomethingAndReturnTrueIfSucceedOrFalseIfNot();
        if(lever){
            response.setStatus(HttpServletResponse.SC_OK);
        }else{
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST); //NOT_FOUND or whatever
        }
    }

But I am sure there is a better way to do this. I know that we have @ResponseStatusannotation, but it is.. static, I mean it returns always the same code- but what if something would have gone wrong? Then I dont want for example, to have 200 OK as response code.

但我相信有更好的方法来做到这一点。我知道我们有@ResponseStatus注释,但它是..静态的,我的意思是它总是返回相同的代码- 但是如果出现问题怎么办?然后我不想例如将 200 OK 作为响应代码。

I found the solution like this: add @ResponseStatusas static response code, but when something goes wrong in the controller, then throw some custom exceptionand catch it in new @ControllerAdvice class, and there also add @ResponseStatus annotation and return proper code.

我找到了这样的解决方案:添加@ResponseStatus作为静态响应代码,但是当控制器出现问题时,抛出一些自定义异常并在新的@ControllerAdvice 类中捕获它,并且还添加了 @ResponseStatus 注释并返回正确的代码。

    @RequestMapping(value = "/sth")
    @ResponseStatus(HttpStatus.OK)
    public void name(HttpServletResponse response) throws Exception{
        boolean lever = service.doSomethingAndReturnTrueIfSucceedOrFalseIfNot();
        if(!lever){
            throw new SomethingWentWrongCustomException("Not okay..");
        }
    }

And then catch it in the class like:

然后在类中捕获它,例如:

@ControllerAdvice
public class SomethingControllerAdvice{
    @ExceptionHandler(value = SomethingWentWrongCustomException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public void someName(){
    }
}

It seems to be quite elegant solution, but the code is quite.. wordy, isnt it? On the other hand, If I adopt this for whole application and create @ControllerAdvice classes, then It could have sense What do you think about it? Is there any other, maybe better approach?

这似乎是一个非常优雅的解决方案,但代码非常......罗嗦,不是吗?另一方面,如果我在整个应用程序中采用它并创建@ControllerAdvice 类,那么它可能有意义你怎么看?还有其他可能更好的方法吗?

I hope it is not opinion based question and I dont want it to be. I just dont want to use anti-patterns and have good practices from begginings :)

我希望这不是基于意见的问题,我不希望它是。我只是不想使用反模式并且从开始就有好的做法:)

回答by Maciej Walkowiak

Returning ResponseEntityas @M-deinum wrote is definitely way to go. Additionally, instead of defining behavior for each exception in @ControllerAdviceyou can just annotate your exceptions classes with appropriate @ResponseStatusannotations.

ResponseEntity像@M-deinum 所写的那样返回绝对是要走的路。此外,您无需为每个异常定义行为,@ControllerAdvice只需使用适当的@ResponseStatus注释来注释异常类即可。

@ResponseStatus(HttpStatus.BAD_REQUEST)
class SomeException extends RuntimeException {

}