Spring MVC development technology ~ ~ application of Servlet controller decoupling and verifier in MVC mode

1 function introduction

The function of this application is to fill in and submit the product form for the user. If the price information is entered incorrectly, an error prompt will appear. If there is no error, the product will be saved and a completion page will be displayed to display the saved product information.

2 new technology

2.1 decoupling controller

The previous business logic code is written in the Servlet controller, and the Servlet class will expand with the increase of application complexity.
To avoid this problem, we will improve the Servlet and extract the business logic code into a separate class called controller.

2.2 verifier technology of Web

When a Web application executes an action, an important step is to verify the input. The content of verification can be simple, such as checking whether an input is empty or complex, such as verifying credit card number.
Modern MVC framework usually supports both programmatic and declarative verification methods. In programming mode, user input verification needs to be performed by encoding, while in declarative mode, XML documents or attribute files containing verification rules need to be provided. There is an additional ProductValidator class and two JSTL jar packages

Decoupling controller and case with calibrator

3.1 procedure composition of the case

3.2 JavaBean s and forms

3.2.1 Product

package com.springmvc.domain;
import java.io.Serializable;
public class Product implements Serializable {	
	private static final long serialVersionUID = -4535580184779437563L;
	private String name;
    private String description;
    private float price;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
}

3.2.2 ProductForm

package com.springmvc.form;
public class ProductForm {
	    private String name;
	    private String description;
	    private String price;
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String getDescription() {
			return description;
		}
		public void setDescription(String description) {
			this.description = description;
		}
		public String getPrice() {
			return price;
		}
		public void setPrice(String price) {
			this.price = price;
		}
}

3.2 Validator

package com.springmvc.validator;
import java.util.ArrayList;
import java.util.List;
import com.springmvc.form.ProductForm;
public class ProductValidator {
	public List<String> validate(ProductForm productForm) {
		List<String> errors = new ArrayList<String>();
		String name = productForm.getName();
		if (name == null || name.trim().isEmpty()) {
			errors.add("Product must have a name");
		}
		String price = productForm.getPrice();
		if (price == null || price.trim().isEmpty()) {
			errors.add("Product must have a price");
		} else {
			try {
				Float.parseFloat(price);
			} catch (NumberFormatException e) {
				errors.add("Invalid price value");
			}
		}
		return errors;
  }
}

There is a validate method in the ProductValidator class that operates on the ProductForm object to ensure that the product name is not empty and that its price is a reasonable number. The validate method returns a list of strings containing error information. If an empty list is returned, the input is valid.
The only place in the application where product verification is needed is to save the product. The SaveProductController class. We introduce the ProductValidator class for the SaveProductController class

3.3 Controller control class

There are two controller classes in the controller directory, InputProductController and SaveProductController.
Both controllers implement the controller interface.

3.3.1 Controller interface

package com.springmvc.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Controller {
	String handleRequest(HttpServletRequest request, 
			HttpServletResponse response);
}

The Controller interface has only one method, handleRequest. The implementation class of the Controller interface accesses the HttpServletRequest and HttpServletResponse objects of the current request through this method.

3.3.2 InputProductController

package com.springmvc.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class InputProductController implements Controller {
	@Override
	public String handleRequest(HttpServletRequest request, HttpServletResponse response) {
		return "/WEB-INF/jsp/ProductForm.jsp";
	}
}

Directly return the path of ProductForm.jsp

3.3.3 SaveProductController

The only place in the application where product verification is needed is to save the product. The SaveProductController class. We introduce the ProductValidator class for the SaveProductController class

package com.springmvc.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.springmvc.domain.Product;
import com.springmvc.form.ProductForm;
import com.springmvc.validator.ProductValidator;
public class SaveProductController implements Controller {
	@Override
	public String handleRequest(HttpServletRequest request, HttpServletResponse response) {
		ProductForm productForm = new ProductForm();
        // populate form properties
        productForm.setName(request.getParameter("name"));
        productForm.setDescription(request.getParameter("description"));
        productForm.setPrice(request.getParameter("price"));        
        // validate ProductForm
        ProductValidator productValidator = new ProductValidator();
        List<String> errors = productValidator.validate(productForm);
        if (errors.isEmpty()) {
            // create Product from ProductForm
            Product product = new Product();
            product.setName(productForm.getName());
            product.setDescription(productForm.getDescription());
            product.setPrice(Float.parseFloat(productForm.getPrice()));
            // no validation error, execute action method
            // insert code to save product to the database
            // store product in a scope variable for the view
            request.setAttribute("product", product);
            return "/WEB-INF/jsp/ProductDetails.jsp";
        } else {
            // store errors and form in a scope variable for the view
            request.setAttribute("errors", errors);
            request.setAttribute("form", productForm);
            return "/WEB-INF/jsp/ProductForm.jsp";
        }    
	}
}

Read the request to construct a ProductForm object, use the ProductForm object to construct a Product object, and return the path of ProductDetail.jsp.
Class and call the validate method.
If an error is found, the handlerRequest method is forwarded to the ProductForm.jsp page.
If there are no errors, create a Product object, set properties, and forward to the / WEB-INF/jsp/ProductDetails.jsp page

3.4 dispatcher servlet class

package com.springmvc.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.springmvc.controller.InputProductController;
import com.springmvc.controller.SaveProductController;
public class DispatcherServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;    
    public DispatcherServlet() {
        super();       
    }	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		process(request, response);
	}	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		process(request, response);
	}	
	private void process(HttpServletRequest request,
            HttpServletResponse response) 
            throws IOException, ServletException {
        String uri = request.getRequestURI();       
        int lastIndex = uri.lastIndexOf("/");
        String action = uri.substring(lastIndex + 1);         
        String dispatchUrl = null;
        if (action.equals("product_input.action")) {
        	InputProductController controller = new InputProductController();
        	dispatchUrl = controller.handleRequest(request, response);
        } else if (action.equals("product_save.action")) {
        	SaveProductController controller = new SaveProductController();
        	dispatchUrl = controller.handleRequest(request, response);
        }
        if (dispatchUrl != null) {
            RequestDispatcher rd = request.getRequestDispatcher(dispatchUrl);
            rd.forward(request, response);
        }
    }
}

The role of the dispatcher servlet is to check each URI, create the corresponding controller, and call its HanderRequest method.

3.5 view view layer

3.5.1 ProductForm.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML>
<html>
<head>
<title>Add Product Form</title>
<style type="text/css">@import url(css/main.css);</style>
</head>
<body>
<div id="global">
<c:if test="${requestScope.errors != null }">
	<p id="errors">
		Error(s)!
		<ul>
			<c:forEach var="error" items="${requestScope.errors}">
				<li>${error}</li>
			</c:forEach>
		</ul>
	</p>	
</c:if>
<form action="product_save.action" method="post">
    <fieldset>
        <legend>Add a product</legend>
            <p>
                <label for="name">Product Name: </label>
                <input type="text" id="name" name="name" 
                    tabindex="1">
            </p>
            <p>
                <label for="description">Description: </label>
                <input type="text" id="description" 
                    name="description" tabindex="2">
            </p>
            <p>
                <label for="price">Price: </label>
                <input type="text" id="price" name="price" 
                    tabindex="3">
            </p>
            <p id="buttons">
                <input id="reset" type="reset" tabindex="4">
                <input id="submit" type="submit" tabindex="5" 
                    value="Add Product">
            </p>
    </fieldset>
</form>
</div>
</body>
</html>

3.5.2 ProductDetails.jsp

<!DOCTYPE HTML>
<html>
<head>
<title>productDetail</title>
<style type="text/css">@import url(css/main.css);</style>
</head>
<body>
<div id="global">
    <h4>The product has been saved.</h4>
    <p>
        <h5>Details:</h5>
        Product Name: ${product.name}<br/>
        Description: ${product.description}<br/>
        Price: $${product.price}
    </p>
</div>
</body>
</html>

3.5.3 CSS

#global {
    text-align: left;border: 1px solid #dedede;background: #efefef;
	width: 560px;padding: 20px;margin: 100px auto;
}
form {
  font:100% verdana; min-width: 500px; max-width: 600px;width: 560px;
}
form fieldset {
  border-color: #bdbebf;border-width: 3px;margin: 0;
}

legend {
	font-size: 1.3em;
}

form label { 
	width: 250px;display: block;float: left;text-align: right;padding: 2px;
}

#buttons {
	text-align: right;
}

3.5.4 Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>YJYSpring_MVC_Servlet_Validator_PaulDeckCH02</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>com.springmvc.servlet.DispatcherServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>*.action</url-pattern>
  </servlet-mapping>
</web-app>

4 running tests

Input address

http://localhost:8080/YJYSpring_MVC_Servlet_Validator_PaulDeckCH02/product_input.action

Page display, blank in ProductName, enter non value in Price

Click Add Product to display the error prompt

Enter the correct information and display the Product information

Test finished

42 original articles published, praised 27 and visited 1510
Private letter follow

Tags: JSP xml Java JavaEE

Posted on Tue, 14 Jan 2020 22:51:58 -0800 by cricher