Lab07 mvc not found
Goal¶
Handle the case where the requested ID is not in the Repository, and return a 404 status code (Not Found).
Don't forget to run *all* tests to make sure everything is still working before continuing.
A. Web: Throw Exception¶
For web-based controllers, in order to return a Not Found (404) status code, you need to throw a special exception.
-
Create a new exception class called
CoffeeOrderNotFoundHttpException:import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "No account with that ID was found.") public class CoffeeOrderNotFoundHttpException extends RuntimeException { } -
Open up the
CoffeeOrderWebControllerclass and inside thecoffeeOrderViewmethod, throw the above exception if the order wasn't found when you look for it in the Repository.Throwing Exception
To throw the exception, you would do:
throw new CoffeeOrderNotFoundHttpException() -
Try it out by running the
CoffeeVendingMachineApplicationand browsing tolocalhost:8080/coffee-order/999
B. API: Return ResponseEntity¶
For HTTP APIs, we can return a 404 (Not Found) status code in a different way, using the ResponseEntity class.
First, let's add an Integration Test that checks for a 404 status code being returned.
- Open
CoffeeOrderRestTestand add the following test method:@Test public void getWithNonExistentIdReturnsNotFound() throws Exception { mockMvc.perform(get("/api/coffeeorders/9999")) .andExpect(status().isNotFound()); } -
Run it and it should fail.
How Did It Fail?
What was the root cause of the failure, i.e., which Exception? It's a good idea to get used to looking at the stack trace for the root failure reason.
Now modify the controller to return a response entity.
-
Open the
CoffeeOrderApiControllerand change the method signature forcoffeeOrderInfoto returnResponseEntity<CoffeeOrderResponse>instead ofCoffeeOrderResponse. -
If you try and run the tests at this point, you may get a compile error in one of the tests. Why, and how would you fix it?
Ask for Help
Remember, if you can't figure it out after a few minutes, ask for help!
-
Change the
returnfor the "happy" case (where the order was found) to be:return ResponseEntity.ok(coffeeOrderResponse); -
For the not found case, you would do the following:
return ResponseEntity.notFound().build();Builder Pattern
Note that the
ResponseEntity.notFound()follows the Builder pattern. -
Run the tests, they should all pass.
-
Try out the API using Postman or curl.
ResponseEntity Reference
You can look at this reference for more details: https://www.baeldung.com/spring-response-entity
Once you've completed the above steps,
check in with the instructor to review your code.