1.技术架构:三层架构--mvc
M: model V:View C:Controller
2.建立项目所使用的包:
bean: JavaBean
dao :Dao接口
dao.impl: Dao接口的实现
service:业务接口(注册,登录)
service.impl: 业务接口的实现
web:Servlet控制器,处理页面的数据
工作流程:
User.java 定义了user的属性
package kangjie.bean; import java.io.Serializable; import java.util.Date; public class User implements Serializable{ private String username; private String password; private String email; private Date birthday; //date类型 public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } 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; } }
UserDao接口
package kangjie.dao; import kangjie.bean.User; public interface UserDao { /** * 根据用户名和密码查询用户 * @param username * @param password * @return 查询到,返回此用户,否则返回null */ public User findUserByUserNameAndPassword(String username, String password); /** * 注册用户 * @param user 要注册的用户 */ public void add(User user); /** * 更加用户名查找用户 * @param name * @return查询到了则返回此用户,否则返回null */ public User findUserByUserName(String username); }
UserDaoImpl dao接口的实现
package kangjie.dao.impl; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import kangjie.bean.User; import kangjie.dao.UserDao; import kangjie.utils.JaxpUtils; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; public class UserDaoImpl implements UserDao { /** * 需要从xml文件中读取数据,需要一个类JaxpUtils.java */ @Override public User findUserByUserNameAndPassword(String username, String password) { //加载dom树 Document document = JaxpUtils.getDocument(); //查询需要的node节点 Node node = document.selectSingleNode("//user[@username=‘" + username + "‘ and @password=‘" + password + "‘]"); if(node != null){ //find him 封装数据 User user = new User(); user.setUsername(username); user.setPassword(password); user.setEmail(node.valueOf("@email")); String birthday = node.valueOf("@birthday"); Date date; try { date = new SimpleDateFormat("yyyy-MM-dd").parse(birthday); //日期类型的转化 user.setBirthday(date); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } return user; } return null; } @Override public void add(User user) { //加载dom树 Document document = JaxpUtils.getDocument(); //拿到根节点 Element root = document.getRootElement(); //添加一个user节点 root.addElement("user").addAttribute("username", user.getUsername()) .addAttribute("password", user.getPassword()) .addAttribute("email", user.getEmail()) .addAttribute("birthday", new SimpleDateFormat("yyyy-MM-dd").format(user.getBirthday())) ; //将dom树报错到硬盘上 JaxpUtils.write2xml(document); } @Override public User findUserByUserName(String username) { //加载dom树 Document document = JaxpUtils.getDocument(); //查询需要的node节点 Node node = document.selectSingleNode("//user[@username=‘" + username + "‘]"); if(node != null){ //find him 封装数据 User user = new User(); user.setUsername(username); user.setPassword(node.valueOf("@password")); user.setEmail(node.valueOf("@email")); String birthday = node.valueOf("@birthday"); Date date; try { date = new SimpleDateFormat("yyyy-MM-dd").parse(birthday); user.setBirthday(date); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } return user; } return null; } }
UserService 业务逻辑接口
package kangjie.service; import kangjie.bean.User; import kangjie.exception.UserExistsException; public interface UserService { /** * 根据用户名和密码 * @param username * @param password * @return 登录成功返回次用户,否则返回null */ public User login(String username, String password); /** * 用户注册 * @param user * @return */ public void register(User user) throws UserExistsException; //注册失败时,抛出异常,由该类来处理 }
UserExistsException 接手异常
package kangjie.exception; public class UserExistsException extends Exception{ }
UserServiceImpl 业务逻辑接口的实现
package kangjie.service.imple; import kangjie.bean.User; import kangjie.dao.UserDao; import kangjie.dao.impl.UserDaoImpl; import kangjie.exception.UserExistsException; import kangjie.service.UserService; public class UserServiceImpl implements UserService { UserDao dao = new UserDaoImpl(); @Override public User login(String username, String password) { // TODO Auto-generated method stub return dao.findUserByUserNameAndPassword(username, password); } @Override public void register(User user) throws UserExistsException { // 注册成功与否,可以去servlet里去抓异常 User u = dao.findUserByUserName(user.getUsername()); if(u == null){ dao.add(user); }else{ throw new UserExistsException(); } } }
RegisterServlet 用户注册请求的处理
package kangjie.servlet; import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; 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 kangjie.bean.User; import kangjie.exception.UserExistsException; import kangjie.service.UserService; import kangjie.service.imple.UserServiceImpl; import kangjie.utils.WebUtils; import kangjie.web.formbean.UserFormBean; public class ResigterServlet extends HttpServlet { /** * 完成注册功能 * * This method is called when a form has its tag value method equals to get. */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //中文处理 request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); //先拿到数据,将数据封装到userformbean中,因为可能会有很多的bean,所以此处应该新创建一个类来处理这个问题 //WebUtils类,专门 封装数据 String username = request.getParameter("username"); System.out.println("---username---" + username); UserFormBean ufb = WebUtils.fillFormBean(UserFormBean.class, request); //第二步,验证数据 if(ufb.validate()){ //验证通过 //第三步,将formbean中的内容拷贝到user中 User user = new User(); //由于formbean中的生日是date类型,beanUtils类中不能自动转换,因此需要注册一个日期类型的转换器 //BeanUtils.copy将一个对象拷贝到另一个对象中去 try { ConvertUtils.register(new DateLocaleConverter(), Date.class); BeanUtils.copyProperties(user, ufb); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } //第四步,注册用户 //调用业务逻辑层,完成注册 UserService us = new UserServiceImpl(); try { us.register(user); System.out.println("注册成功"); //注册成功 //将用户存入session对象中 // request.getSession().setAttribute("loginuser", user); //返回登录页面 //最好采用请求重定向,(请求转发和请求重定向有什么区别) //重定向和转发有一个重要的不同:当使用转发时,JSP容器将使用一个内部的方法来调用目标页面,新的页面继续处理同一个请求, // 而浏览器将不会知道这个过程。 与之相反,重定向方式的含义是第一个页面通知浏览器发送一个新的页面请求。 // 因为,当你使用重定向时,浏览器中所显示的URL会变成新页面的URL, 而当使用转发时,该URL会保持不变。 // 重定向的速度比转发慢,因为浏览器还得发出一个新的请求。同时,由于重定向方式产生了一个新的请求, // 所以经过一次重 定向后,request内的对象将无法使用。 // response.sendRedirect(request.getContextPath() + "/login.jsp"); //注册成功,提示用户 response.getWriter().write("注册成功,2秒后转向登录页面"); response.setHeader("Refresh", "2;url=" + request.getContextPath() + "/login.jsp"); } catch (UserExistsException e) { // 说明用户已经注册过了 ufb.getErrors().put("username", "此用户已经被注册过了"); //将ufb存入request对象中 request.setAttribute("user", ufb); request.getRequestDispatcher("/register.jsp").forward(request, response); } }else{ //验证失败 //打回去,同事把他原来填写的数据回写过去 //把ufb对象存入request对象 request.setAttribute("user", ufb); //给页面传递的就是user对象,则在页面上显示的候,需要从user对象中拿取该数据 request.getRequestDispatcher("/register.jsp").forward(request, response); } } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
loginServlet 处理用户登录请求
package kangjie.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 kangjie.bean.User; import kangjie.service.UserService; import kangjie.service.imple.UserServiceImpl; public class loginServlet extends HttpServlet { /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); //获取页面数据 String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("---username---"+ username + "---password---" +password); //验证数据 UserService user = new UserServiceImpl(); User u = user.login(username, password); if(u != null){ //合法用户 request.getSession().setAttribute("loginuser", u); request.getRequestDispatcher("/main.jsp").forward(request, response); }else{ //非法用户 System.out.println("**用户名或密码错误**"); request.getSession().setAttribute("error", "用户名或密码错误"); response.sendRedirect(request.getContextPath() + "/servlet/login.jsp"); } } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
JaxpUtils 处理xml文件的类,使用xml文件来充当数据库
package kangjie.utils; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; //操作XML文件的方法 public class JaxpUtils { static String path; static { System.out.println("---getpath----"); path = JaxpUtils.class.getClassLoader().getResource("users.xml").getPath(); System.out.println("---path---" + path); } public static Document getDocument(){ //创建一个dom4j的解析器 try { SAXReader sx = new SAXReader(); Document doc = sx.read(path); return doc; } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public static void write2xml(Document document){ try { XMLWriter writer = new XMLWriter(new FileOutputStream(path), OutputFormat.createPrettyPrint()); writer.write(document); writer.close(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
WebUtils 封装页面的数据
package kangjie.utils; import java.lang.reflect.InvocationTargetException; import javax.servlet.http.HttpServletRequest; import org.apache.commons.beanutils.BeanUtils; //为页面服务,封装页面的数据 public class WebUtils { //写一个泛型 public static <T> T fillFormBean(Class<T> clazz,HttpServletRequest request){ T t = null; try { t = clazz.newInstance();//反射机制 BeanUtils.populate(t, request.getParameterMap()); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } return t; } }
UserFormBean 用来封装页面数据
package kangjie.web.formbean; import java.text.ParseException; import java.util.HashMap; import java.util.Map; import org.apache.commons.beanutils.locale.converters.DateLocaleConverter; /** * 为什么要UserFormBean * 是因为页面上的数据类型很多,与user不匹配,所以需要UserFormBean * @author kj * */ public class UserFormBean { private String username; private String password; private String repassword; private String email; private String birthday; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getRepassword() { return repassword; } public void setRepassword(String repassword) { this.repassword = repassword; } 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; } /** * 验证数据 * 服务端验证必须要有 * @return */ public boolean validate(){ //验证用户名 if(username == "" || username == null){ errors.put("username", "用户名或密码不能为空"); }else{ if(username.length() <3 || username.length() > 11){ errors.put("username", "用户名长度在3-8之间"); } } if(password == "" || password == null){ errors.put("password", "用户名或密码不能为空"); }else{ if(password.length() <3 || password.length() > 11){ errors.put("password", "密码长度在3-8之间"); } } //验证重复密码 if(!repassword.equals(password)){ errors.put("repassword", "两次密码输入不一致"); } //验证邮箱 if(email == "" || email == null){ errors.put("email", "邮箱不能为空"); }else{ if(!email.matches("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$")) { errors.put("email", "邮箱格式不正确"); } } //验证生日 if(birthday == "" || birthday == null){ errors.put("birthday", "生日不能为空"); }else{ //验证日期存在缺陷:2-30日不能验证,需要使用另外一个类: // -----DateLocalConverter---apache // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); DateLocaleConverter dlc = new DateLocaleConverter(); try { dlc.convert(birthday); } catch (Exception e) { // TODO Auto-generated catch block errors.put("birthday", "日期格式错误"); } } //如果errors为空,说明没有错误产生 return errors.isEmpty(); //userbean写好了,下边就开始写Servlet } //存放错误信息,使用Map,一对.然后只需要提供map的get方法即可 private Map<String,String> errors = new HashMap<String, String>(); public Map<String, String> getErrors() { return errors; } }
users.xml文件
<?xml version="1.0" encoding="UTF-8"?> <users> <user username="陈紫函" password="123" email="[email protected]" birthday="1980-10-10"/> </users>
register.jsp 注册页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>register.jsp</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="${pageContext.request.contextPath}/servlet/ResigterServlet" method="post"> <table border="8"> <tr> <td>姓名</td> <td><input type="text" name="username" value="${user.username }"></td> <!-- value 用来回显数据 --> <td>${user.errors.username }</td> </tr> <tr> <td>密码</td> <td><input type="password" name="password" value="${user.password }"></td> <td>${user.errors.password }</td> </tr> <tr> <td>确认密码</td> <td><input type="password" name="repassword" value="${user.repassword }"></td> <td>${user.errors.repassword }</td> </tr> <tr> <td>邮箱</td> <td><input type="text" name="email" value="${user.email }"></td> <td>${user.errors.email }</td> </tr> <tr> <td>生日</td> <td><input type="text" name="birthday" value="${user.birthday }"></td> <td>${user.errors.birthday }</td> </tr> <tr> <td colspan="3" align="center"><input type="submit" value="注册 "></td> </tr> </table> </form> </body> </html>
login.jsp 登录页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>登录</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="${pageContext.request.contextPath }/servlet/loginServlet"> 用户名:<input type="text" name="username"><br><br> 密 码: <input type="password" name="password"><br><br> <input type="submit" value="登录"><br> </form> </body> </html>
main.jsp 主页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>欢迎登录</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> 欢迎回来!${loginuser.username} </body> </html>
时间: 2024-11-10 10:48:07