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

naz*_*art 29 java spring http-status-code-404 retrofit

我正在使用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());
}
Run Code Online (Sandbox Code Playgroud)

}

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

res.setStatus(HttpStatus.NOT_FOUND.value());
新的ResponseEntity(HttpStatus.BAD_REQUEST);

但我需要返回Response.

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

chr*_*ke- 60

创建一个NotFoundException@ResponseStatus(HttpStatus.NOT_FOUND)注释的类,并从控制器中抛出它.

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

  • 需要标准导入意味着:import org.springframework.http.HttpStatus; (5认同)
  • 只需抛出ResponseStatusException(在此处详细说明另一个答案),无需为每个唯一的HTTP状态和原因文本创建新类。 (3认同)
  • @andrej 有时这是一个很好的解决方案,但是 (1) `ResponseStatusException` 直到 Spring 5 才添加;(2) “NotFoundException”对于被捕获或对于带有“@ExceptionHandler”的双栈 HTML UI 非常有用。 (2认同)
  • 此解决方案将 Exception 与您的 REST-Controller 层紧密耦合。我想避免的东西。我会在 `@AroundAdvice` 组件中使用 `@ExceptionHandler` 代替 (2认同)

and*_*rej 32

这很简单,只需抛出org.springframework.web.server.ResponseStatusException即可

throw new ResponseStatusException(
  HttpStatus.NOT_FOUND, "entity not found"
);
Run Code Online (Sandbox Code Playgroud)

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

  • 在许多情况下,这是一个好方法。请注意,该类直到Spring 5才可用。 (3认同)
  • 这不是最好的,您的访问者将看到错误堆栈信息。 (2认同)

ama*_*zia 25

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

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

并返回以下内容:

return new ResponseEntity(HttpStatus.NOT_FOUND);
Run Code Online (Sandbox Code Playgroud)

  • 确切地说,您应该返回ResponseEntity <T>,其中T是例如Response(第一个案例).当它是一个正确的响应时,你将返回新的ResponseEntity(myResponse,HttpStatus.OK). (5认同)

小智 10

您可以像这样在 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
 ...
}
Run Code Online (Sandbox Code Playgroud)