用户注册登录项目

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>
原文地址:https://www.cnblogs.com/taiguyiba/p/6159994.html