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

JavaSpringHttp Status-Code-404Retrofit

Java Problem Overview


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

@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);

but I need to return Response.

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

Java Solutions


Solution 1 - Java

This is very simply done by throwing 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+

Solution 2 - Java

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

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

Solution 3 - Java

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

@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);

Solution 4 - Java

You can just set responseStatus on res like this:

@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
 ...
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questioncatch23View Question on Stackoverflow
Solution 1 - JavaandrejView Answer on Stackoverflow
Solution 2 - Javachrylis -cautiouslyoptimistic-View Answer on Stackoverflow
Solution 3 - JavaamaziaView Answer on Stackoverflow
Solution 4 - JavaMichałView Answer on Stackoverflow