zoukankan      html  css  js  c++  java
  • 用户注册登录项目

    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="chengzihan@163.com" 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>
          <font color =red>${error }</font> <form action="${pageContext.request.contextPath }/servlet/loginServlet"> 用户名:<input type="text" name="username"><br><br>&nbsp;码: <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>
  • 相关阅读:
    创建异步Web服务
    MCAD考试计划
    微软面试题
    Reborn
    Qt项目注意事项
    在ASP.Net中两种利用CSS实现多界面
    为ASP.NET控件添加常用的JavaScript操作
    用Split函数分隔字符串
    Microsoft .NET Pet Shop 4.0
    搞定QString,string,char*,CString的互转
  • 原文地址:https://www.cnblogs.com/taiguyiba/p/6159994.html
Copyright © 2011-2022 走看看