标签:
参考资料:http://www.cnblogs.com/xdp-gacl/p/3902537.html
<?xml version="1.0" encoding="UTF-8"?> <users> </users>
package lyyp.util; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.URL; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; /** * XML解析?读取?写入? * @author Buddha * */ public class XmlUtils { private static String filename="DB.xml"; public static Document getDocument()throws DocumentException{ URL url =XmlUtils.class.getClassLoader().getResource(filename); String realpath =url.getPath(); SAXReader reader =new SAXReader(); return reader.read(new File(realpath)); } public static void write2Xml(Document document) throws IOException{ URL url =XmlUtils.class.getClassLoader().getResource(filename); String realpath=url.getPath(); OutputFormat format=OutputFormat.createPrettyPrint(); XMLWriter writer =new XMLWriter(new FileOutputStream(realpath),format); writer.write(document); writer.close(); } }
分层架构的代码也是按照【域模型层(domain)】→【数据访问层(dao、dao.impl)】→【业务处理层(service、service.impl)】→【表现层(web.controller、web.UI、web.filter、web.listener)】→【工具类(util)】→【测试类(junit.test)】的顺序进行编写的。
在lyyp.domain包下创建一个User类
User类具体代码如下:
package lyyp.domain; import java.io.Serializable; import java.util.Date; /** * @author Buddha 用户实体类 */ public class User implements Serializable { /** * 鼠标放置在类名处,显示选择Add generated serial version ID【添加生成的序列版本ID】 */ private static final long serialVersionUID = -5856247296702032275L; // 用户名 private String id; // 用户名 private String userName; // 用户密码 private String userPwd; // 用户邮箱 private String email; // 用户生日 private Date birthday; //声明字段之后,Source - Generate Getters Setters...【创建get,set方法】全选,OK public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPwd() { return userPwd; } public void setUserPwd(String userPwd) { this.userPwd = userPwd; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public static long getSerialversionuid() { return serialVersionUID; } }
在lyyp.dao包下创建一个IUserDao接口类,对于开发接口类,我习惯以字母I作类的前缀,这样一眼就看出当前这个类是一个接口,这也算是一种良好的开发习惯吧,通过看类名就可以方便区分出是接口还是具体的实现类。
IUserDao接口的具体代码如下:
package lyyp.dao; import lyyp.domain.User; /** * @author Buddha *用户接口类 */ public interface IUserDao { /** 按【/**加回车,为带参数注释段】 * 根据用户名和密码来查找用户 * @param userName * @param userPwd * @return 查找到的用户 */ User find(String userName,String userPwd); /** * 添加用户 * @param user */ void add(User user); /** * 根据用户名来查找用户 * @param userName * @return 查找到的用户 */ User find(String userName); }
对于接口中的方法定义,这个只能是根据具体的业务来分析需要定义哪些方法了,但是无论是多么复杂的业务,都离不开基本的CRUD(增删改查)操作,Dao层是直接和数据库交互的,所以Dao层的接口一般都会有增删改查这四种操作的相关方法。
在lyyp.dao.impl包下创建一个UserDaoImpl类
UserDaoImpl类是IUserDao接口的具体实现类,对于接口的实现类命名方式,我习惯以"接口名(去除前缀I)+impl"形式或者"接口名+impl"形式来命名:IUserDao(接口)→UserDaoImpl(实现类)或者IUserDao(接口)→IUserDaoImpl(实现类),这也算是一些个人的编程习惯吧,平时看到的代码大多数都是以这两种形式中的一种来来命名接口的具体实现类的,反正就是要能够一眼看出接口对应的实现类是哪一个就可以了。
UserDaoImpl类的具体代码如下:
暂时不贴
package lyyp.exception; /** * 自定义异常 * * @author Buddha * */ @SuppressWarnings("serial")//加上此代码,不出警告,否则需要UID=………………L public class UserExistException extends Exception { public UserExistException() { super(); } public UserExistException(String message, Throwable cause) { super(message, cause); } public UserExistException(String message){ super(message); } public UserExistException(Throwable cause) { super(cause); } }
在lyyp.service包中创建IUserService接口类
IUserService接口的具体代码如下:
package lyyp.service; import lyyp.domain.User; import lyyp.exception.UserExistException; /** * service层对web层提供所有的业务服务 IUserService接口类 * * @author Buddha * */ public interface IUserService { /** * 提供注册服务 * * @param user * @throws UserExistException */ void registerUser(User user) throws UserExistException; /** * 提供登录服务 * * @param userName * @param userPwd * @return */ User loginUser(String userName, String userPwd); }
在lyyp.service.impl包中创建UserServiceImpl类
UserServiceImpl类为IUserService接口的具体实现类,具体代码如下:
package lyyp.service.impl; import lyyp.dao.IUserDao; import lyyp.dao.impl.UserDaoImpl; import lyyp.domain.User; import lyyp.exception.UserExistException; import lyyp.service.IUserService; /** * IUserService接口的具体实现类 * * @author Buddha * */ public class UserServiceImpl implements IUserService { private IUserDao userDao = new UserDaoImpl(); @Override public void registerUser(User user) throws UserExistException { if (userDao.find(user.getUserName()) != null) { // checked exception // unchecked exception // 这里抛编译时异常的原因:让上一层处理这个异常,已给用户一个友好提示 throw new UserExistException("注册的用户名已存在"); } userDao.add(user); } @Override public User loginUser(String userName, String userPwd) { return userDao.find(userName,userPwd); } }
1、在lyyp.web.UI包下写一个RegisterUIServlet为用户提供注册界面
RegisterUIServlet收到用户请求后,就跳到register.jsp
RegisterUIServlet的代码如下:
package lyyp.web.UI; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author Buddha * 为用户提供注册的用户界面的Servlet * RegisterUIServlet负责为用户输出注册界面 * 当用户访问RegisterUIServlet时,就跳转到WEB-INF/pages目录下的register.jsp页面 */ @SuppressWarnings("serial") public class RegisterUIServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/WEB-INF/pages/register.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
register.jsp页面的代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>用户注册</title> </head> <body style="text-align: center;"> <!-- <form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post">指明表单提交后,交给RegisterServlet进行处理 --> <form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post"> <table> <tr> <td>用户名</td> <td><input type="text" name="userName"/></td> </tr> <tr> <td>密码</td> <td><input type="password" name="userPwd"/></td> </tr> <tr> <td>确认密码</td> <td><input type="password" name="confirmPwd"/></td> </tr> <tr> <td>邮箱</td> <td><input type="text" name="email"></td> </tr> <tr> <td>生日</td> <td><input type="text" name="birthday"></td> </tr> <tr> <td><input type="reset" value="清空"></td> <td><input type="submit" value="注册"></td> </tr> </table> </form> </body> </html>
3、在lyyp.web.controller包下编写用于处理用户注册的RegisterServlet
RegisterServlet担任着以下几个职责:
1、接收客户端提交到服务端的表单数据。
2、校验表单数据的合法性,如果校验失败跳回到register.jsp,并回显错误信息。
3、如果校验通过,调用service层向数据库中注册用户。
为了方便RegisterServlet接收表单数据和校验表单数据,在此我设计一个用于校验注册表单数据RegisterFormbean,再写WebUtils工具类,封装客户端提交的表单数据到formbean中。
在lyyp.web.formbean包下创建一个用于校验注册表单数据RegisterFormbean
RegisterFormbean代码如下:
package lyyp.web.formbean; import java.util.HashMap; import java.util.Map; import org.apache.commons.beanutils.locale.converters.DateLocaleConverter; /** * 封装的用户注册表单bean,用来接受register.jsp中表单输入项的值 * RegisterFormBean中的属性与register.jsp中的表单输入项的name一一对应 * RegisterFormBean的职责除了负责接受register.jsp中的表单输入项的值之外,还担任着校验表单输入项的值的合法性 * * @author Buddha * */ public class RegisterFormBean { // RegisterFormBean中的属性值与register.jsp中的表单输入项的name一一对应 // <input type="text" name="userName"/> private String userName; // <input type="password" name="userPwd"/> private String userPwd; // <input type="password" name="confirmPwd"/> private String confirmPwd; // <input type="text" name="email"> private String email; // <input type="text" name="birthday"> private String birthday; private Map<String, String> errors = new HashMap<String, String>(); public Map<String, String> getErrors() { return errors; } public void setErrors(Map<String, String> errors) { this.errors = errors; } /* * validate方法负责校验表单输入项 表单输入项校验规则: private String userName;用户名不能为空,并且要是3-8的字母 * abcdABcd private String userPwd;密码不能为空,并且要是3-8的数字 private String * confirmPwd;两次密码要一致 private String email;可以为空,不为空要是一个合法的邮箱 private String * birthday;可以为空,不为空时,要是一个合法的日期 */ public boolean validate() { boolean isOk = true; if (this.userName == null || this.userName.trim().equals("")) { isOk = false; errors.put("userName", "用户名不能为空"); } else { if (!this.userName.matches("[a-zA-z]{3,8}")) { isOk = false; errors.put("userName", "用户名必须是3-8位的字母"); } } if (this.userPwd == null || this.userPwd.trim().equals("")) { isOk = false; errors.put("userPwd", "密码不能为空"); } else { if (!this.userPwd.matches("\\d{3,8}")) { isOk = false; errors.put("userPwd", "密码必须是3-8位的数字"); } } // private String password2; 两次密码要一致 if (this.confirmPwd != null) { if (!this.confirmPwd.equals(this.userPwd)) { isOk = false; errors.put("confirmPwd", "两次密码不一致"); } } // private String email; 可以为空,不为空要是一个合法的邮箱 if (this.email != null && !this.email.trim().equals("")) { if (!this.email.matches("\\w+@\\w+(\\.\\w+)+")) { isOk = false; errors.put("email", "邮箱不合法"); } } // private String birthday; 可以为空,不为空时,要是一个合法的日期 if (this.birthday != null && !this.birthday.trim().equals("")) { try { DateLocaleConverter conver = new DateLocaleConverter(); conver.convert(this.birthday); } catch (Exception e) { isOk = false; errors.put("birthday", "日期不合法"); } } return isOk; } // 字段的get,set方法 public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPwd() { return userPwd; } public void setUserPwd(String userPwd) { this.userPwd = userPwd; } public String getConfirmPwd() { return confirmPwd; } public void setConfirmPwd(String confirmPwd) { this.confirmPwd = confirmPwd; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } }
在lyyp.util包下创建一个WebUtils工具类,该工具类的功能就是封装客户端提交的表单数据到formbean中
package lyyp.util; import java.util.Enumeration; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import org.apache.commons.beanutils.BeanUtils; /** * 工具类,封装客户端提交的表单数据到formbean中 * @author Buddha * */ public class WebUtils { /** * 将request对象装换成T对象 * @param request * @param clazz * @return */ public static <T> T request2Bean(HttpServletRequest request,Class<T> clazz){ try { T bean =clazz.newInstance(); Enumeration<String> e = request.getParameterNames(); while(e.hasMoreElements()){ String name=(String)e.nextElement(); String value = request.getParameter(name); BeanUtils.setProperty(bean, name, value); } return bean; } catch (Exception e) { throw new RuntimeException(); } } /** * 生成 * @return */ public static String makeId(){ return UUID.randomUUID().toString(); } }
最后看一下负责处理用户注册的RegisterServlet完整代码:
package lyyp.web.controller; import java.io.IOException; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.beanutils.locale.converters.DateLocaleConverter; import lyyp.domain.User; import lyyp.exception.UserExistException; import lyyp.service.IUserService; import lyyp.service.impl.UserServiceImpl; import lyyp.util.WebUtils; import lyyp.web.formbean.RegisterFormBean; /** * 处理用户注册的Servlet * * @author Buddha * */ public class RegisterServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 将客户端提交的表单数据封装到RegisterFormBean对象中 RegisterFormBean formbean = WebUtils.request2Bean(request, RegisterFormBean.class); // 校验用户注册填写的表单 if (formbean.validate() == false) {// 如果校验失败 // 将封装了用户填写表单数据的formbean对象发送回register.jsp页面的form表单中进行显示 request.setAttribute("formbean", formbean); // 校验石板就说明是用户填写的表单数据有问题,那么就跳转回register.jsp request.getRequestDispatcher("/WEB-INF/pages/register.jsp").forward(request, response); return; } User user = new User(); try { // 注册字符串到日期的转换器 ConvertUtils.register(new DateLocaleConverter(), Date.class); BeanUtils.copyProperties(user, formbean);// 把表单的数据填充到javabean中 user.setId(WebUtils.makeId());// 设置用户的Id属性 IUserService service = new UserServiceImpl(); // 调用service层提供的注册用户服务实现用户注册 service.registerUser(user); String messgae = String.format("注册成功!!3秒后为您自动跳转到登录页面<meta http-equiv=‘refresh‘content=‘3;url=%s‘/>", request.getContextPath() + "/servlet/LoginUIServlet"); request.setAttribute("message", messgae); request.getRequestDispatcher("/message.jsp").forward(request, response); } catch (UserExistException e) { formbean.getErrors().put("userName", "注册用户已存在"); request.setAttribute("formbean", formbean); request.getRequestDispatcher("/WEB-INF/pages/register.jsp").forward(request, response); } catch (Exception e) { e.printStackTrace();// 在后台记录异常 request.setAttribute("messgae", "对不起,注册失败"); request.getRequestDispatcher("/messags.jsp").forward(request, response); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
用户注册时如果填写的表单数据校验不通过,那么服务器端就将一个存储了错误提示消息和表单数据的formbean对象存储到request对象中,然后发送回register.jsp页面,因此我们需要在register.jsp页面中取出request对象中formbean对象,然后将用户填写的表单数据重新回显到对应的表单项上面,将出错时的提示消息也显示到form表单上面,让用户知道是哪些数据填写不合法!
修改register.jsp页面,代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>用户注册</title> </head> <body style="text-align: center;"> <!-- <form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post">指明表单提交后,交给RegisterServlet进行处理 --> <form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post"> <table> <tr> <td>用户名</td> <td> <%--使用EL表达式${}提取存储在request对象中的formbean对象中封装的表单数据(formbean.userName)以及错误提示消息(formbean.errors.userName)--%> <input type="text" name="userName" value="${formbean.userName}">${formbean.errors.userName} </td> </tr> <tr> <td>密码</td> <td><input type="password" name="userPwd" value="${formbean.userPwd }">${forambean.errors.userPwd }</td> </tr> <tr> <td>确认密码</td> <td><input type="password" name="confirmPwd" value="${formbean.confirmPwd}">${formbean.errors.confirmPwd}</td> </tr> <tr> <td>邮箱</td> <td><input type="text" name="email" value="${formbean.email}">${formbean.errors.email}</td> </tr> <tr> <td>生日</td> <td><input type="text" name="birthday" value="${formbean.birthday}">${formbean.errors.birthday}</td> </tr> <tr> <td><input type="reset" value="清空"></td> <td><input type="submit" value="注册"></td> </tr> </table> </form> </body> </html>
在WebConten-WEB-INF中的web.xml文件中加入以下代码:
<!-- 注册的servlet --> <servlet> <servlet-name>RegisterUIServlet</servlet-name> <servlet-class>lyyp.web.UI.RegisterUIServlet</servlet-class> </servlet> <servlet> <servlet-name>RegisterServlet</servlet-name> <servlet-class>lyyp.web.controller.RegisterServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>RegisterUIServlet</servlet-name> <url-pattern>/servlet/RegisterUIServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>RegisterServlet</servlet-name> <url-pattern>/servlet/RegisterServelt</url-pattern> </servlet-mapping>
到此,用户注册功能就算是开发完成了!
下面测试一下开发好的用户注册功能:
输入URL地址:http://localhost:8080/lyyp/servlet/RegisterUIServlet
1、在lyyp.web.UI包下写一个LoginUIServlet为用户提供登录界面
LoginUIServlet收到用户请求后,就跳到login.jsp
LoginUIServlet的代码如下:
package lyyp.web.UI; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * * @author Buddha *LoginUIServlet负责为用户输出登陆界面 *当用户访问LoginUIServlet时,就跳转到WEB-INF/pages目录下的login.jsp页面 */ public class LoginUIServlet extends HttpServlet{ public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{ request.getRequestDispatcher("/WEB-INF/pages/login.jsp").forward(request, response); } public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ doGet(request, response); } }
2、在/WEB-INF/pages/目录下编写用户登录的jsp页面login.jsp
login.jsp页面的代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>用户登录</title> </head> <body> <form action="${pageCpntext.request.contextPath }/servlet/LoginServlet" method="post"> 用户名:<input type="text" name="username"><br/> 密码:<input type="password" name="password"><br/> <input type="submit" value="登录"><br/> </form> </body> </html>
login.jsp中的<form action="${pageContext.request.contextPath}/servlet/LoginServlet"method="post">指明表单提交后,交给LoginServlet进行处理。
3、在lyyp.web.controller包下编写用于处理用户登录的LoginServlet
LoginServlet的代码如下:
package lyyp.web.controller; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import lyyp.domain.User; import lyyp.service.IUserService; import lyyp.service.impl.UserServiceImpl; /** * 处理用户登录的servlet * * @author Buddha * */ public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取用户填写的登录用户名 String username = request.getParameter("username"); // 获取用户填写的登录密码 String password = request.getParameter("password"); IUserService service = new UserServiceImpl(); // 用户登录 User user = service.loginUser(username, password); if (user == null) { String message = String.format("用户名或密码有误,请重新登录!2秒后为您自动跳转到登录页面<meta http-equiv=‘refresh‘ content=‘2;url=%s‘", request.getContextPath() + "/servlet/LoginUIServlet"); request.setAttribute("message", message); request.getRequestDispatcher("message.jsp").forward(request, response); return; } // 登录成功后,就将用户存储到session中 request.getSession().setAttribute("user", user); String message = String.format("恭喜:%s,登陆成功!本页将在3秒后跳到首页!!<meta http-equiv=‘refresh‘ content=‘3;url=%s‘", user.getUserName(), request.getContextPath() + "/index.jsp"); request.setAttribute("message", message); request.getRequestDispatcher("/message.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
在WebConten-WEB-INF中的web.xml文件中加入以下代码:
<!-- 登录的servlet --> <servlet> <servlet-name>LoginUIServlet</servlet-name> <servlet-class>lyyp.web.UI.LoginUIServlet</servlet-class> </servlet> <servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>lyyp.web.controller.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LoginUIServlet</servlet-name> <url-pattern>/servlet/LoginUIServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/servlet/LoginServlet</url-pattern> </servlet-mapping>
到此,用户登录的功能就算是开发完成了。
下面测试一下开发好的用户登录功能,输入URL地址:http://localhost:8080/lyyp/servlet/LoginUIServlet访问login.jsp页面,输入正确的用户名和密码进行登录,
在lyyp.web.controller包下编写用于处理用户注销的LogoutServlet
LogoutServlet的代码如下:
在lyyp.web.filter包下编写过滤器CharacterEncodingFilter
CharacterEncodingFilter的代码如下:
package lyyp.web.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; /** * 过滤器处理表单传到servlet的乱码问题 * @author Buddha * */ public class CharacterEncodingFilter implements Filter{ private String encoding =null; @Override public void init(FilterConfig filterConfig)throws ServletException{ //encoding 在web.xml中指定 this.encoding =filterConfig.getInitParameter("encoding"); } @Override public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException{ //解决表单提交时的中文乱码问题 request.setCharacterEncoding(encoding); chain.doFilter(request, response); } @Override public void destroy(){ } }
在WebConten-WEB-INF中的web.xml文件中加入以下代码:
<!-- filter过滤器 --> <filter> <filter-name>EncodingFilter</filter-name> <filter-class>lyyp.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
标签:
原文地址:http://www.cnblogs.com/shakyamuni/p/5117073.html