通讯录改造——MVC设计模式
将之前用servlet写的程序转化为jsp+servlet的简单的MVC的三层结构。项目中程序的包如图
首先是实体对象:
package com.contactSystem.entiey; public class Contact { private String Id; private String name; private String sex; private String age; private String phone; private String qq; private String email; public String getId() { return Id; } public void setId(String id) { Id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getQq() { return qq; } public void setQq(String qq) { this.qq = qq; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "Contact [Id=" + Id + ", name=" + name + ", sex=" + sex + ", age=" + age + ", phone=" + phone + ", qq=" + qq + ", email=" + email + "]"; } }
然后就是对数据操作的抽象类
package com.contactSystem.dao; import java.io.FileNotFoundException; import java.io.UnsupportedEncodingException; import java.util.List; import org.dom4j.DocumentException; import com.contactSystem.entiey.Contact; public interface ContactOperate { public void addContact(Contact contact) throws Exception; public void updateContact(Contact contact) throws Exception; public void removeContact(String id) throws Exception; public Contact findContact(String id) throws Exception; public List<Contact> allContacts(); //根据名称姓名查询是否有存在重复。 public boolean checkIfContact(String name); }
具体实现类
package com.contactSystem.dao.daoImpl; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.persistence.Id; import javax.persistence.Tuple; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.SAXReader; import com.contactSystem.dao.ContactOperate; import com.contactSystem.entiey.Contact; import com.contactSystem.util.XMLUtil; public class Operater implements ContactOperate { @Override //添加联系人 public void addContact(Contact contact) throws Exception { // TODO Auto-generated method stub File file=new File("e:/contact.xml"); Document doc=null; Element rootElem=null; if (file.exists()) { doc=new SAXReader().read(file); rootElem=doc.getRootElement(); }else { doc=DocumentHelper.createDocument(); rootElem=doc.addElement("ContactList"); } //开始添加个体 Element element=rootElem.addElement("contact"); //有系统自动生成一随机且唯一的ID,赋给联系人Id,系统提供了一个包UUID包 String uuid=UUID.randomUUID().toString().replace("-", ""); element.addAttribute("Id", uuid); element.addElement("姓名").setText(contact.getName()); element.addElement("name").setText(contact.getName()); element.addElement("sex").setText(contact.getSex()); element.addElement("age").setText(contact.getAge()); element.addElement("phone").setText(contact.getPhone()); element.addElement("email").setText(contact.getEmail()); element.addElement("qq").setText(contact.getQq()); //写入到本地的xml文档中 XMLUtil.write2xml(doc); } @Override public void updateContact(Contact contact) throws Exception { // TODO Auto-generated method stub //通过xpath查找对应id的联系人 Document document=XMLUtil.getDocument(); Element element=(Element) document.selectSingleNode("//contact[@Id='"+contact.getId()+"']"); //根据标签改文本 System.out.println(element); element.element("name").setText(contact.getName()); element.element("age").setText(contact.getAge()); element.element("email").setText(contact.getEmail()); element.element("phone").setText(contact.getPhone()); element.element("sex").setText(contact.getSex()); element.element("qq").setText(contact.getQq()); XMLUtil.write2xml(document); } @Override public void removeContact(String id) throws Exception { // TODO Auto-generated method stub //通过xpath去查找对应的contact Document document=XMLUtil.getDocument(); Element element=(Element) document.selectSingleNode("//contact[@Id='"+id+"']"); /** * 如果是火狐浏览器,其本身有一个bug,对于一个get请求,它会重复做两次, * 第一次会把一个唯一的id给删除掉,但是在第二次的时候,它会继续去删,而这个时候查找不到,会报错,会发生错误, * 为了解决这个bug,我们在这里验证其是否为空 */ if (element!=null) { element.detach(); XMLUtil.write2xml(document); } } @Override public Contact findContact(String id) throws Exception { // TODO Auto-generated method stub Document document=XMLUtil.getDocument(); Element e=(Element) document.selectSingleNode("//contact[@Id='"+id+"']"); Contact contact=null; if (e!=null) { contact=new Contact(); contact.setAge(e.elementText("age")); contact.setEmail(e.elementText("email")); contact.setId(id); contact.setName(e.elementText("name")); contact.setPhone(e.elementText("phone")); contact.setSex(e.elementText("sex")); contact.setQq(e.elementText("qq")); } return contact; } @Override public List<Contact> allContacts() { // TODO Auto-generated method stub Document document=XMLUtil.getDocument(); List<Contact> list=new ArrayList<Contact>(); List<Element> conElements=(List<Element>)document.selectNodes("//contact"); for (Element element : conElements) { Contact contact=new Contact(); contact.setId(element.attributeValue("Id")); contact.setAge(element.elementText("age")); contact.setEmail(element.elementText("email")); contact.setName(element.elementText("name")); contact.setPhone(element.elementText("phone")); contact.setQq(element.elementText("qq")); contact.setSex(element.elementText("sex")); list.add(contact); } return list; } /** * true:说明重复 * false:说明没有重复 */ @Override public boolean checkIfContact(String name) { // TODO Auto-generated method stub //查询name标签是否一样 Document doc=XMLUtil.getDocument(); Element element=(Element) doc.selectSingleNode("//name[text()='"+name+"']"); if (element!=null) { return true; }else { return false; } } }
为了减轻Servlet的负担在增加一层(业务逻辑层)Service,这里举例,当联系人的名字存在时,提示出错,不在servlet中去判断,而在service中去处理,同样首先写出service抽象接口
package com.contactSystem.service; import java.util.List; import com.contactSystem.entiey.Contact; public interface ContactService { public void addContact(Contact contact) throws Exception; public void updateContact(Contact contact) throws Exception; public void removeContact(String id) throws Exception; public Contact findContact(String id) throws Exception; public List<Contact> allContacts(); }
这个时候有点相当于在Operate操作中添加了一层操作,在contactService的实现类中去有逻辑判断的去使用Operater的方法
package com.contactSystem.service.imple; import java.util.List; import com.contactSystem.dao.daoImpl.Operater; import com.contactSystem.entiey.Contact; import com.contactSystem.exception.NameRepeatException; import com.contactSystem.service.ContactService; /** * 处理项目中出现的业务逻辑 * @author Administrator * */ public class ContactServiceImpe implements ContactService { Operater operater =new Operater(); @Override public void addContact(Contact contact) throws Exception { // TODO Auto-generated method stub //执行业务逻辑判断 /** * 添加是否重复的业务逻辑 */ if (operater.checkIfContact(contact.getName())) { //重复 /** * 注意:如果业务层方法出现任何错误,则返回标记(自定义的异常)到servlet */ throw new NameRepeatException("姓名重复,不可使用"); } operater.addContact(contact); } @Override public void updateContact(Contact contact) throws Exception { // TODO Auto-generated method stub operater.updateContact(contact); } @Override public void removeContact(String id) throws Exception { // TODO Auto-generated method stub operater.removeContact(id); } @Override public Contact findContact(String id) throws Exception { // TODO Auto-generated method stub return operater.findContact(id); } @Override public List<Contact> allContacts() { // TODO Auto-generated method stub return operater.allContacts(); } }
这里通过抛出异常去将信息传递给Servlet,异常代码如下
package com.contactSystem.exception; /** * 姓名重复的自定义异常 * @author Administrator * */ public class NameRepeatException extends Exception{ public NameRepeatException(String msg) { super(msg); } }
现在来写Servlet,首先是首页的联系人列表Servlet
package com.contactSystem.servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.contactSystem.dao.daoImpl.Operater; import com.contactSystem.entiey.Contact; import com.contactSystem.service.ContactService; import com.contactSystem.service.imple.ContactServiceImpe; public class Index extends HttpServlet { /** * 显示所有联系人的逻辑方式 */ private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); ContactService service=new ContactServiceImpe(); List<Contact> contacts=service.allContacts(); /** * shift+alt+A ——>区域选择 * 正则表达式:“."表示任意字符,"*"表示多个字符 * “/1”表示一行代表匹配一行内容 */ request.setAttribute("contacts", contacts); request.getRequestDispatcher("/index.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
添加联系人
package com.contactSystem.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.contactSystem.dao.daoImpl.Operater; import com.contactSystem.entiey.Contact; import com.contactSystem.exception.NameRepeatException; import com.contactSystem.service.ContactService; import com.contactSystem.service.imple.ContactServiceImpe; public class addServlet extends HttpServlet { /** * 处理添加联系人的逻辑 */ private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String userName=request.getParameter("userName"); String age=request.getParameter("age"); String sex=request.getParameter("sex"); String phone=request.getParameter("phone"); String qq=request.getParameter("qq"); String email=request.getParameter("email"); ContactService service=new ContactServiceImpe(); Contact contact=new Contact(); contact.setName(userName); contact.setAge(age); contact.setSex(sex); contact.setPhone(phone); contact.setQq(qq); contact.setEmail(email); try { service.addContact(contact); } catch (NameRepeatException e) { // TODO Auto-generated catch block //处理名字重复的异常 request.setAttribute("message", e.getMessage()); request.getRequestDispatcher("/add.jsp").forward(request, response); return; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } response.sendRedirect(request.getContextPath()+"/Index"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
查找联系人
package com.contactSystem.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.contactSystem.dao.daoImpl.Operater; import com.contactSystem.entiey.Contact; import com.contactSystem.service.ContactService; import com.contactSystem.service.imple.ContactServiceImpe; public class FindIdServlet extends HttpServlet { /** * 修改联系人逻辑 */ private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); ContactService service=new ContactServiceImpe(); String id=request.getParameter("id"); Contact contact=null; try { contact=service.findContact(id); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } request.setAttribute("contact", contact); request.getRequestDispatcher("/update.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
修改联系人
package com.contactSystem.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.contactSystem.dao.daoImpl.Operater; import com.contactSystem.entiey.Contact; import com.contactSystem.service.ContactService; import com.contactSystem.service.imple.ContactServiceImpe; public class UpdateServlet extends HttpServlet { /** * 将修改后的数据提交 */ private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); request.setCharacterEncoding("utf-8"); String userName=request.getParameter("userName"); String age=request.getParameter("age"); String sex=request.getParameter("sex"); String phone=request.getParameter("phone"); String qq=request.getParameter("qq"); String email=request.getParameter("email"); String id=request.getParameter("id"); ContactService service=new ContactServiceImpe(); Contact contact=new Contact(); contact.setId(id); contact.setName(userName); contact.setAge(age); contact.setSex(sex); contact.setPhone(phone); contact.setQq(qq); contact.setEmail(email); try { service.updateContact(contact); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } response.sendRedirect(request.getContextPath()+"/Index"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
删除联系人
package com.contactSystem.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.contactSystem.dao.daoImpl.Operater; import com.contactSystem.service.ContactService; import com.contactSystem.service.imple.ContactServiceImpe; public class DeleteServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); String id=request.getParameter("id"); ContactService service=new ContactServiceImpe(); try { service.removeContact(id); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } response.sendRedirect(request.getContextPath()+"/Index"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
以上完成了MVC的M和C,还差View,现在来具体显示jsp页面
首页所有联系人的显示
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html> <html> <head> <meta charset='utf-8'> <title>查询所有联系人</title> <style media='screen'> table td { text-align: center; } table { border-collapse: collapse; } </style> </head> <body> <center> <h2>查询所有联系人</h2> </center> <table border='1' align='center'> <tbody> <thead> <th>编号</th> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>电话</th> <th>QQ</th> <th>邮箱</th> <th>操作</th> </thead> <c:forEach items="${contacts}" var="con" varStatus="varSta"> <tr> <td>${varSta.count }</td> <td>${con.name }</td> <td>${con.sex }</td> <td>${con.age }</td> <td>${con.phone }</td> <td>${con.qq }</td> <td>${con.email }</td> <td><a href='${pageContext.request.contextPath }/FindIdServlet?id=${con.id}'>修改</a> <a href='${pageContext.request.contextPath }/DeleteServlet?id=${con.id}'>删除</a></td> </tr> </c:forEach> <tr> <td colspan='8'> <a href='${pageContext.request.contextPath}/add.jsp'>添加联系人</a> </td> </tr> </tbody> </table> </body> </html>
修改联系人,首先要把要修改联系人的信息都显示在信息栏中,然后用户去修改相关信息
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>修改联系人</title> <style media="screen"> #btn{ width:40px; width: 50px; background: green; color: white; font-size:14px; } </style> </head> <body> <center> <h2>修改联系人</h2> </center> <form action="${pageContext.request.contextPath }/UpdateServlet" method="post"> <table border="1" align="center"> <tbody> <tr> <th>姓名</th> <td><input type="text" name="userName" value="${contact.name}"/></td> <input type="hidden" name="id" value="${contact.id }"/> </tr> <tr> <th>年龄</th> <td><input type="text" name="age" value="${contact.age }" /></td> </tr> <tr> <th>性别</th> <td> <input type="radio" name="sex" value="男" <c:if test="${contact.sex=='男' }"> checked="true"</c:if>/>男 <input type="radio" name="sex" value="女" <c:if test="${contact.sex=='女' }"> checked="true"</c:if> />女 </td> </tr> <tr> <th>电话</th> <td><input type="text" name="phone" value="${contact.phone }" /></td> </tr> <tr> <th>QQ</th> <td><input type="text" name="qq" value="${contact.qq }" /></td> </tr> <tr> <th>邮箱</th> <td><input type="text" name="email" value="${contact.email }" /></td> </tr> <tr> <td colspan="3" align="center"> <input type="submit" value="提交" id="btn"/> </td> </tr> </tbody> </table> </form> </body> </html>
最后就是添加联系人了
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>添加联系人</title> <style media="screen"> #btn{ width:40px; width: 50px; background: green; color: white; font-size:14px; } </style> </head> <body> <center> <h2>添加联系人</h2> </center> <form action="${pageContext.request.contextPath}/addServlet" method="post"> <table border="1" align="center"> <tbody> <tr> <th>姓名</th> <td><input type="text" name="userName" value="${message }" /></td> </tr> <tr> <th>年龄</th> <td><input type="text" name="age" /></td> </tr> <tr> <th>性别</th> <td> <input type="radio" name="sex" value="男"/>男 <input type="radio" name="sex" value="女" />女 </td> </tr> <tr> <th>电话</th> <td><input type="text" name="phone" /></td> </tr> <tr> <th>QQ</th> <td><input type="text" name="qq" /></td> </tr> <tr> <th>邮箱</th> <td><input type="text" name="email" /></td> </tr> <tr> <td colspan="3" align="center"> <input type="submit" value="提交" id="btn"/> </td> </tr> </tbody> </table> </form> </body> </html>
最后可以加上一个测试类,方便自己调试
package com.contactSystem.Junit; import static org.junit.Assert.*; import java.util.List; import org.junit.Before; import com.contactSystem.dao.daoImpl.Operater; import com.contactSystem.entiey.Contact; public class Test { Operater operator=null; //初始化这个对象的实例 @Before public void init(){ operator=new Operater(); } @org.junit.Test public void Add() throws Exception{ Contact contact=new Contact(); contact.setAge("21"); contact.setEmail("454444@qq.com"); contact.setName("gqxing"); contact.setPhone("13455555"); contact.setQq("235346662"); contact.setSex("男"); operator.addContact(contact); } @org.junit.Test public void update() throws Exception{ Contact contact=new Contact(); contact.setId("002"); contact.setAge("0"); contact.setEmail("0000000@qq.com"); contact.setName("test"); contact.setPhone("0-00000000000"); contact.setQq("000000000000"); contact.setSex("男"); operator.updateContact(contact); } @org.junit.Test public void removeContact() throws Exception{ operator.removeContact("002"); } @org.junit.Test public void findContact() throws Exception{ Contact contact=operator.findContact("002"); System.out.println(contact); } @org.junit.Test public void allContact() throws Exception{ List<Contact> contacts= operator.allContacts(); for (Contact contact : contacts) { System.out.println(contact); } } @org.junit.Test public void TetsCheckBoolean() throws Exception{ Boolean flag=operator.checkIfContact("郭庆兴"); System.out.println(flag); } }
最后运行的结构示意图:
当名字重复的时候:提交就会显示
很希望自己是一棵树,守静、向光、安然,敏感的神经末梢,触着流云和微风,窃窃的欢喜。脚下踩着最卑贱的泥,很踏实。还有,每一天都在隐秘成长。