1

I am working on a project made with Spring Framework. I have not touched Java in years, and this is all very new to me. The project has the below UI controller displaying product information:

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.List;
import java.util.ArrayList;

@Controller
public class UiController {

    private ProductService productService;
    private LocationService locationService;
    private InventoryService inventoryService;
    private CartService cartService;


    public UiController(
            ProductService productService,
            LocationService locationService,
            InventoryService inventoryService,
            CartService cartService) {
        this.productService = productService;
        this.locationService = locationService;
        this.inventoryService = inventoryService;
        this.cartService = cartService;

    }

    @GetMapping("/")
    public String home(Model model) {
        model.addAttribute("products", productService.getAllProducts());
        return "index";
    }
    @GetMapping("/brand/{brand}")
    public String brand(Model model, @PathVariable String brand) {
        model.addAttribute("products", productService.getProductByBrand(brand));
        return "index";
    }

    @GetMapping("/product/{productId}")
    public String product(Model model, @PathVariable String productId) {
        Product prod = productService.getProduct(productId);
        ArrayList<Product> ps = new ArrayList<Product>();
        ps.add(prod);
        model.addAttribute("products", ps);
        return "index";
    }
}

To go with this controller, I have an html template:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Product Listing</h1>
<table>
    <tr>
        <th>PRODUCT ID</th>
        <th>PRICE</th>
        <th>DESCRIPTION</th>
        <th>BRAND</th>
    </tr>
    <tr th:each="product : ${products}">
        <td th:text="${product.getProductId()}"/>
        <td th:text="${product.getPrice()}"/>
        <td th:text="${product.getDescription()}"/>
        <td th:text="${product.getBrand()}"/>
    </tr>
</table>

</body>
</html>

When there are no products - meaning that if the size() of my ArrayList products is 0, I want to display 404.

How could I do this?

Igor Shmukler
  • 1,742
  • 3
  • 15
  • 48
  • Does this answer your question? [How to check if list is empty using thymeleaf?](https://stackoverflow.com/questions/33106391/how-to-check-if-list-is-empty-using-thymeleaf) – aksappy Aug 10 '21 at 22:41
  • Your app is Spring MVC based. Not a rest api. By `I want to display 404` i assume you want to display a 404 html page? – gtiwari333 Aug 10 '21 at 22:42
  • 1
    Refer to Exception handling in Spring Web https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc for more details – gtiwari333 Aug 10 '21 at 22:42
  • https://stackoverflow.com/questions/21061638/spring-mvc-how-to-return-custom-404-errorpages this should answer your question – gtiwari333 Aug 10 '21 at 22:47
  • Note that 404 is not the customary response for an empty collection resource; it's simply a 200 with no entries. In this case, you could wrap the `table` if a `th:if="${products.empty}"`. – chrylis -cautiouslyoptimistic- Aug 10 '21 at 22:51

1 Answers1

2

From your url, it seems you are looking for a specific product with given id. It doesn't make much sense to return a template from this request or even putting it into a list (that will always have one value). For asynchronous you can write:

@GetMapping("/product/{productId}")
public ResponseEntity<Product> product(Model model, @PathVariable String productId) {
    Product prod = productService.getProduct(productId);
    if(prod == null) {
        return new ResponseEntity<Product>(null, HttpStatus.NOT_FOUND);
    } else {
        return new ResponseEntity<Product>(prod, HttpStatus.OK);
    }
}

If you really need to return a template you could put a status variable in your model and check it's status on the client side.

Or if you want to redirect, only do the check and build return string accordinly.

@GetMapping("/product/{productId}")
public String product(Model model, @PathVariable String productId) {
    Product prod = productService.getProduct(productId);
    if(prod == null) {
        return "errors/404";
    } else {
        return "index";
    }
}
fdev
  • 87
  • 1
  • 7