如何告诉视图控制器发生错误? (Spring MVC)

时间:2016-10-26 06:31:50

标签: spring jsp spring-mvc jstl

如何以更好的方式在控制器的视图中说出触发错误/验证消息?目前,我通过发送布尔属性来做到这一点。例如,在创建产品时,我有两个可能的错误。产品的UPC格式无效,或者复制upc。我也有一个有效的

@RequestMapping("/createProduct")
public String createProduct(Model model, @RequestParam(value = "name") String name,
        @RequestParam(value = "upc") String upc, @RequestParam(value = "category") String categoryName,
        @RequestParam(value = "description") String description, @RequestParam(value = "price") BigDecimal price,
        @RequestParam(value = "stock") int stock){

    model.addAttribute("activeTab", 3);

    if(Validator.invalidUpcFormat(upc)){

        model.addAttribute("invalidFormat", true); //trigger for invalid format
        return "management";
    }

    Category category = productService.getCategory(categoryName);

    Product product = new Product(upc, category, name, description, price);
    InventoryProduct inventoryProduct = new InventoryProduct(product, stock);

    try {

        managerService.add(inventoryProduct);
        model.addAttribute("productCreated", true);
    } catch (DuplicateProductException e) {

        model.addAttribute("upc", upc);
        model.addAttribute("duplicateProduct", true); // trigger for duplicate product
    }



    return "management";
}

以下是我的观点:

    <div id="menu3"
            class="tab-pane fade <c:if test="${activeTab == 3}">in active</c:if>">
            <div class="container-fluid" style="padding: 2%;">
                <div class="row">
                    <div class="col-md-12"
                        style="padding-left: 15%; padding-right: 15%;">
                        <c:if test="${productCreated}">
                            <div class="alert alert-success fade in">
                                <a href="#" class="close" data-dismiss="alert"
                                    aria-label="close">&times;</a> <strong>Success!</strong>
                                Product has been created!
                            </div>
                        </c:if>
                        <c:if test="${duplicateProduct}">
                            <div class="alert alert-warning fade in">
                                <a href="#" class="close" data-dismiss="alert"
                                    aria-label="close">&times;</a> <strong>Oh no!</strong>
                                Product with the UPC ${upc} already exists!
                            </div>
                        </c:if>
                        <c:if test="${invalidFormat}">
                            <div class="alert alert-warning fade in">
                                <a href="#" class="close" data-dismiss="alert"
                                    aria-label="close">&times;</a> <strong>Oops!</strong>
                                Invalid UPC format!
                            </div>
                        </c:if>
                        <form
                            action="${pageContext.request.contextPath}/manager/createProduct"
                            method="post">
                            <div class="form-group">
                                <label for="Name">Name </label> <input type="text" name="name"
                                    class="form-control" required />
                            </div>
                            <div class="form-group">
                                <label for="UPC">UPC </label> <input type="number" name="upc"
                                    class="form-control" required />
                            </div>
                            <div class="form-group">
                                <div class="form-group">
                                    <label for="category">Category</label> <select
                                        class="form-control" name="category" required>
                                        <option selected disabled value="">SELECT CATEGORY</option>
                                        <c:forEach items="${categories}" var="item">
                                            <option>${item.getName()}</option>
                                        </c:forEach>
                                    </select>
                                </div>
                            </div>
                            <div class="form-group">
                                <label for="description">Description</label>
                                <textarea class="form-control" rows="5" name="description"></textarea>
                            </div>
                            <div class="form-group">
                                <label for="price">Price </label> <input type="number"
                                    name="price" class="form-control" required />
                            </div>
                            <div class="form-group">
                                <label for="stock">Stock </label> <input type="number"
                                    name="stock" class="form-control" required />
                            </div>
                            <button type="submit" class="btn btn-primary">Add
                                product</button>
                        </form>
                    </div>
                </div>
            </div>
        </div>

除了发送布尔触发器之外,还有更好的做法吗?

1 个答案:

答案 0 :(得分:2)

你可以使用Spring BindingResult。这通常填充了绑定和验证结果。但您也可以手动添加错误。

但首先您需要重构代码,以便使用单个命令/表单支持对象而不是所有@Param

public class CreateProductCommand {
    private String name;
    private String upc;
    private String categoryName;
    .... //other fields
    public CreateProductCommand (){} //parameter less conturctor

    Getter+Setter
}

控制器

@RequestMapping("/createProduct")
public ModelAndView createProduct(CreateProductCommand createProductCommand, BindingResult bindingResult)  //Binding result must be the parameter direct next to the object that should been validated!!!
{


    if (someustomValidationForUcpFail()) {
           bindingResult.rejectValue("upc", //the field name of the invalid field
                    "error.Message.Key",
                    "Default Error Message");
    }

    if (bindingResult.hasErrors()) {
        ModelMap model = new ModelMap();
        model.add("createProductCommand", createProductCommand); 
        return new ModelAndView("createForm", model)
    } else {
        Product product = ...
        return new ModelAndView("showProduct", "product", product)
    }
}

JSP:

您需要使用弹簧形式和输入标签:

<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
          xmlns:c="http://java.sun.com/jsp/jstl/core"
          xmlns:springForm="http://www.springframework.org/tags/form"
          version="2.0">
    ....
    <springForm:form action="<c:url value="/manager/createProduct">" method="POST" modelAttribute="createProductCommand">
        <springForm:input path="name"/> <form:errors path="name" />
        <springForm:input path="ucp"/> <form:errors path="ucp" />
        ....
    </springForm:form>
    ....