Java 如何在 Spring Boot @ResponseBody 中返回 404 响应状态 - 方法返回类型是 Response?

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

How to return 404 response status in Spring Boot @ResponseBody - method return type is Response?

javaspringhttp-status-code-404retrofit

提问by nazar_art

I'm using Spring Boot with @ResponseBody based approach like the following:

我将 Spring Boot 与基于 @ResponseBody 的方法一起使用,如下所示:

@RequestMapping(value = VIDEO_DATA_PATH, method = RequestMethod.GET)
public @ResponseBody Response getData(@PathVariable(ID_PARAMETER) long id, HttpServletResponse res) {
    Video video = null;
    Response response = null;
    video = videos.get(id - 1);
    if (video == null) {
      // TODO how to return 404 status
    }
    serveSomeVideo(video, res);
    VideoSvcApi client =  new RestAdapter.Builder()
            .setEndpoint("http://localhost:8080").build().create(VideoSvcApi.class);
    response = client.getData(video.getId());
    return response;
}

public void serveSomeVideo(Video v, HttpServletResponse response) throws IOException  {
    if (videoDataMgr == null) {
        videoDataMgr = VideoFileManager.get();
    }
    response.addHeader("Content-Type", v.getContentType());
    videoDataMgr.copyVideoData(v, response.getOutputStream());
    response.setStatus(200);
    response.addHeader("Content-Type", v.getContentType());
}

I tried some typical approaches as:

我尝试了一些典型的方法:

res.setStatus(HttpStatus.NOT_FOUND.value());
new ResponseEntity(HttpStatus.BAD_REQUEST);

res.setStatus(HttpStatus.NOT_FOUND.value());
新的响应实体(HttpStatus.BAD_REQUEST);

but I need to return Response.

但我需要返回Response

How to return here 404 status code if video is null?

如果视频为空,如何在此处返回 404 状态代码?

采纳答案by chrylis -cautiouslyoptimistic-

Create a NotFoundExceptionclass with an @ResponseStatus(HttpStatus.NOT_FOUND)annotation and throw it from your controller.

创建一个NotFoundException带有@ResponseStatus(HttpStatus.NOT_FOUND)注释的类并将其从控制器中抛出。

@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "video not found")
public class VideoNotFoundException extends RuntimeException {
}

回答by amazia

Your original method can return ResponseEntity(doesn't change your method behavior):

您的原始方法可以返回ResponseEntity(不会改变您的方法行为):

@RequestMapping(value = VIDEO_DATA_PATH, method = RequestMethod.GET)
public ResponseEntity getData(@PathVariable(ID_PARAMETER) long id, HttpServletResponse res{
... 
}

and return the following:

并返回以下内容:

return new ResponseEntity(HttpStatus.NOT_FOUND);

回答by Micha?

You can just set responseStatus on res like this:

您可以像这样在 res 上设置 responseStatus :

@RequestMapping(value = VIDEO_DATA_PATH, method = RequestMethod.GET)
public ResponseEntity getData(@PathVariable(ID_PARAMETER) long id,
                                            HttpServletResponse res) {
...
    res.setStatus(HttpServletResponse.SC_NOT_FOUND); 
    // or res.setStatus(404)
    return null; // or build some response entity
 ...
}

回答by andrej

This is very simply done by throwing org.springframework.web.server.ResponseStatusException:

这是通过抛出org.springframework.web.server.ResponseStatusException非常简单地完成的:

throw new ResponseStatusException(
  HttpStatus.NOT_FOUND, "entity not found"
);

It's compatible with @ResponseBody and with any return value. Requires Spring 5+

它与@ResponseBody 和任何返回值兼容。需要春天 5+