Spring MVC模式示例(采用解耦控制器+校验器)
Product
package com.mstf.bean; import java.io.Serializable; /** * Product类,封装了一些信息,包含三个属性 * @author wangzheng * */ public class Product implements Serializable { private static final long serialVersionUID = 1L; 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; } }
ProductForm
package com.mstf.bean.form; /** * ProductForm是表单类 * 作用:当数据校验失败时,用于保存和展示用户在原始表单的输入 * @author wangzheng * */ 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; } }
Controller
package com.mstf.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public interface Controller { String handleRequest(HttpServletRequest req,HttpServletResponse resp); }
InputProductController
package com.mstf.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class InputProductController implements Controller { @Override public String handleRequest(HttpServletRequest req,HttpServletResponse resp) { return "/WEB-INF/jsp/ProductForm.jsp"; } }
SaveProductController
package com.mstf.controller; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.mstf.bean.Product; import com.mstf.bean.form.ProductForm; import com.mstf.validator.ProductValidator; public class SaveProductController implements Controller { @Override public String handleRequest(HttpServletRequest req,HttpServletResponse resp) { // 构建一个ProductForm表单对象 ProductForm productForm = new ProductForm(); // 写入表单对象 productForm.setName(req.getParameter("name")); productForm.setDescription(req.getParameter("description")); productForm.setPrice(req.getParameter("price")); //引入校验器 ProductValidator productValidator=new ProductValidator(); List<String> errors=productValidator.validate(productForm); if(errors.isEmpty()) { // 创建模型 Product product = new Product(); product.setName(productForm.getName()); product.setDescription(productForm.getDescription()); product.setPrice(Float.parseFloat(productForm.getPrice())); req.setAttribute("product", product); return "/WEB-INF/jsp/ProductDetails.jsp"; } else { req.setAttribute("errors", errors); req.setAttribute("form", productForm); return "/WEB-INF/jsp/ProductForm.jsp"; } } }
DispatcherServlet
package com.mstf.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.mstf.controller.InputProductController; import com.mstf.controller.SaveProductController; public class DispatcherServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { process(req, resp); } @Override public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { process(req, resp); } /** * 这个方法用来处理所有输入请求 * @param req * @param resp * @throws IOException * @throws ServletException */ private void process(HttpServletRequest req,HttpServletResponse resp) throws IOException,ServletException { req.setCharacterEncoding("UTF-8"); //转码 resp.setCharacterEncoding("UTF-8"); String uri=req.getRequestURI(); // 获取请求URI int lastIndex=uri.lastIndexOf("/"); String action=uri.substring(lastIndex+1); // 获取action名称 String dispatchUrl=null; // 执行方法 if(action.equals("product_input.action")) { InputProductController controller=new InputProductController(); dispatchUrl=controller.handleRequest(req, resp); } else if (action.equals("product_save.action")) { SaveProductController controller=new SaveProductController(); dispatchUrl=controller.handleRequest(req, resp); } if(dispatchUrl!=null) { RequestDispatcher rd=req.getRequestDispatcher(dispatchUrl); rd.forward(req, resp); } } }
ProductValidator
package com.mstf.validator; import java.util.ArrayList; import java.util.List; import com.mstf.bean.form.ProductForm; /** * 校验器 * @author wangzheng * */ 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("必须输入名称!"); } String price = productForm.getPrice(); if (price == null || price.trim().isEmpty()) { errors.add("必须输入价格!"); } else { try { Float.parseFloat(price); } catch (NumberFormatException e) { errors.add("输入的价格无效!"); } } return errors; } }
ProductDetails.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>详情</title> <style type="text/css">@IMPORT url("css/main.css");</style> </head> <body> <div id="global"> <h4>产品已保存</h4> <p> <h5>详细列表:</h5> 名称: ${product.name}<br> 简介: ${product.description}<br> 价格: ¥${product.price} </p> </div> </body> </html>
ProductForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>添加</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"> 操作出错! <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>添加:</legend> <p> <label for="name">名称: </label> <input type="text" id="name" name="name" tabindex="1"> </p> <p> <label for="description">简介: </label> <input type="text" id="description" name="description" tabindex="2"> </p> <p> <label for="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="添加"> </p> </fieldset> </form> </div> </body> </html>
我们有两个方法来进行软件设计:一个是让其足够的简单以至于让BUG无法藏身;另一个就是让其足够的复杂,让人找不到BUG。前者更难一些。