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
CoffeeOrderWebController
class and inside thecoffeeOrderView
method, 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
CoffeeVendingMachineApplication
and 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
CoffeeOrderRestTest
and 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
CoffeeOrderApiController
and change the method signature forcoffeeOrderInfo
to 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
return
for 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.