Skip to content

Lab 7 - 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.

  1. 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 {
    }
    
  2. Open up the CoffeeOrderWebController class and inside the coffeeOrderView 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()

  3. Try it out by running the CoffeeVendingMachineApplication and browsing to localhost: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.

  1. Open CoffeeOrderRestTest and add the following test method:
    @Test
    public void getWithNonExistentIdReturnsNotFound() throws Exception {
      mockMvc.perform(get("/api/coffeeorders/9999"))
             .andExpect(status().isNotFound());
    }
    
  2. 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.

  1. Open the CoffeeOrderApiController and change the method signature for coffeeOrderInfo to return ResponseEntity<CoffeeOrderResponse> instead of CoffeeOrderResponse.

  2. 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!

  3. Change the return for the "happy" case (where the order was found) to be:

    return ResponseEntity.ok(coffeeOrderResponse); 
    
  4. 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.

  5. Run the tests, they should all pass.

  6. 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.