网站注册登录模块

需求: 利用MVC模式实现网站注册登录模块
- (1)实现一个注册页面,可以将用户使用表单提交的注册信息保存到MySql数据库中,用户可以上传头像
- (2)实现一个登陆页面,当用户输入用户名和密码之后.去之前保存数据库里看看是否有该用户信息,如果有,就提示登陆成功,显示用户头像和用户名.没有的话,提示用户名密码错误,重新登陆
- (3)登录成功的用户可以通过注销退出登录

(一)注册界面前后端

1.注册界面JSP
  • 需要实现前端对注册信息的验证,需要实现上传头像的功能
register.jsp
<form enctype="multipart/form-data" method="post" action="${pageContext.request.contextPath}/servlet/RegisterServlet" onsubmit="return validate()">
   <table border="1" width="600">
        <tr>
            <td>*用户名:</td>
            <td><input type="text" name="username" /> </td>
        </tr>
        <tr>
            <td>*密码:</td>
            <td><input type="password" name="password"  /> </td>
        </tr>
        <tr>
            <td>*确认密码:</td>
            <td><input type="password" name="repass"  /> </td>
        </tr>
        <tr>
            <td>*Email:</td>
            <td><input type="text" name="email"  /> </td>
        </tr>
         <tr>
            <td>*头像:</td>
            <td><input type="file" name="headimg"  /> </td>
        </tr>
        <tr>
            <td><input type="submit"  value="提交注册信息" /></td>
            <td></td>
        </tr>
    </table>
  </form>
前端Js验证:
function validate()
{
    var name = document.getElementById("name");
    var email = document.getElementById("email");
    var password = document.getElementById("password");
    var repass = document.getElementById("repass");

    //判断姓名格式
   var regName = /^([\u4e00-\u9fa5]+|([a-z]+\s?)+)$/;
   if(name.value.match(regName) == null){
       alert("姓名格式有误,请输入中文名或英文名!");
       return false;
   }

   //判断电子邮箱格式
   var regEmail=/^\w+@\w+\.(com|edu|org|gov|cn)$/g ;
   if(email.value.match(regEmail)==null){
       alert("电子邮箱格式错误!");
       return false;
   }

   //判断密码
    var regPassword =/(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{3,8}/
   if(password.value.length<3||password.value.length>8)
   {
       alert("请设置长度位3~8的密码!");
       return false;
   }
   else if(password.value.match(regPassword)==null)
   {
       alert("密码必须包含字符、数字和特殊字符!");
       return false;
   }

   //验证确认密码
   if(repss.value != password.value)
   {
       alert("确认密码不一致!");
       return false;
   }
    return true;
}

2.注册控制器RegisterServlet

业务逻辑:
(1)对拿到的客户端请求数据进行验证和保存,切割表单数据和文件数据(函数一)
(2)验证通过,显示注册成功,跳到登陆界面,服务器端验证不通过,则回到注册界面,比如用户名已注册(函数二)
(3)把实现功能的函数封装进service中,把获取到的表单用户数据保存到数据库中

RegisterServlet.java
    UserService service = new UserService();
    private String uploadImgDirString;

  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException
  {
      System.out.println("开始验证");

      request.setCharacterEncoding("utf-8");//请求编码
      response.setContentType("text/html;charset=utf-8");//告诉浏览器编码格式
      response.setCharacterEncoding("utf-8");//正文编码

      //common切割表单数据和文件
      User user = parseUser(request);

      //判断用户名是否已经注册过
      boolean isUserNameExists = service.isUserNameExists(user.getUsername());

      if (!isUserNameExists)
      {
          //没有重名,先保存用户数据到数据库中,然后跳转到登陆界面
          int result = service.registerUser(user);
          System.out.println("result="+result);

          if (result==1)
          {
               response.getWriter().println("注册成功,1s后跳转到登陆界面");
               response.setHeader("refresh","1;url='"+request.getContextPath()+"/login.jsp'");
          }

      }
      else
      {
          response.getWriter().println("此用户名已被注册,请重新注册");
          response.setHeader("refresh","1;url='"+request.getContextPath()+"/register.jsp'");
      }

  }

  //解析数据包方法不可分离出去
  private User parseUser(HttpServletRequest request)
  {
      //利用common-bin组件来解析数据包,拿到表单数据和图片地址
      User user = new User();

      String username = null;
      String password = null;
      String email = null;
      String heading_path = null;

      //拿到存放上传图像的路径
      uploadImgDirString = request.getRealPath("/img");
      //System.out.println("uploadImgDirString=" + uploadImgDirString);

      //开始解析数据包
      DiskFileItemFactory factory = new DiskFileItemFactory();
      ServletContext servletContext=this.getServletConfig().getServletContext();
      File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
      factory.setRepository(repository);
      // 拿到上传组件
      ServletFileUpload upload = new ServletFileUpload(factory);

      // 开始解析请求的数据包
      try
      {
          List<FileItem> filelist = upload.parseRequest(request);

          // 处理apache已经分割好的数据集合
          Iterator<FileItem> iter = filelist.iterator();

          while (iter.hasNext())
          {
              FileItem item = iter.next();

              if (item.isFormField())
              {
                // 如果是表表单数据
                  if (item.getFieldName().equals("username"))
                  {
                    username = item.getString();
                  }
                  else if (item.getFieldName().equals("password"))
                  {
                    password = item.getString();
                  }
                  else if (item.getFieldName().equals("email"))
                  {
                      email = item.getString();
                  }
              }
              else
              {
                    // 如果是文件数据,交给service处理,接收返回的图片路径
                  heading_path=service.getFilePath(item, uploadImgDirString);
              }
        }

      }
      catch (FileUploadException e)
      {
          e.printStackTrace();
      }
    //封装一条记录到JavaBean
      user.setUsername(username);
      user.setPassword(password);
      user.setEmail(email);
      user.setHeading_path(heading_path);

    return user;
  }


  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException
  {
        doGet(request, response);
  }
3.JavaBean和Mysql数据库
  • 包含username,password,email和图片路径heading_path
  • 数据库需要新建并加载配置数据
User.java
public class User
{
    private String username;
    private String email;
    private String password;
    private String heading_path;

    @Override
    public String toString()
    {
        return "User [username=" + username + ", email=" + email
            + ", password=" + password + ", heading_path=" + heading_path
            + "]";
    }

    public User(String username, String email, String password,
        String heading_path)
    {
        super();
        this.username = username;
        this.email = email;
        this.password = password;
        this.heading_path = heading_path;
    }
    public String getUsername()
    {
        return username;
    }
    public void setUsername(String username)
    {
        this.username = username;
    }
    public String getEmail()
    {
        return email;
    }
    public void setEmail(String email)
    {
        this.email = email;
    }
    public String getPassword()
    {
        return password;
    }
    public void setPassword(String password)
    {
        this.password = password;
    }
    public String getHeading_path()
    {
        return heading_path;
    }

    public void setHeading_path(String heading_path)
    {
        this.heading_path = heading_path;
    }
}
DBUtils.java
package com.cskaoyan.db.utils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

//数据仓库
public class DBUtils
{
    static Properties properties;
    static Connection con;
    static String host;
    static String port;
    static String db;

    static
    {
    try
    {
    //加载配置文件
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        String path = DBUtils.class.getClassLoader().getResource("conn.prop").getPath();

        properties = new Properties();
        properties.load(new FileInputStream(path));

        host = properties.getProperty("host");
        port = properties.getProperty("port");
        db = properties.getProperty("db");

    }
    catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    catch (InstantiationException e)
    {
        e.printStackTrace();
    }
    catch (IllegalAccessException e)
    {
        e.printStackTrace();
    }
    catch (ClassNotFoundException e)
    {
        e.printStackTrace();
    }
    }

    //连接数据库
    public static Connection getConnection() throws SQLException
    {
        String url = "jdbc:mysql://" + host + ":" + port + "/" + db;
        return DriverManager.getConnection(url, properties);

    }

    //关闭连接,释放资源
    public static void realeseResourse(Connection con, Statement st,
        ResultSet rs)
    {
        if (con != null)
        {
            try
            {
            con.close();
            }
            catch (SQLException e)
            {
            e.printStackTrace();
            }
        }
        if (st != null)
        {
            try
            {
            con.close();
            }
            catch (SQLException e)
            {
            e.printStackTrace();
            }
        }

        if (rs != null)
        {
            try
            {
            con.close();
            }
            catch (SQLException e)
            {
            e.printStackTrace();
            }
        }

    }

}
数据库配置conn.prop放在src目录下
host=localhost
port=3306
db=mysj
user=root
password=123456

4.数据接口访问层

  • 封装不同类型的数据库存取方法,比如将数据存入mysql数据库中,或者将数据存入xml文件中打印输出
    需要不同的方法来实现
package com.cskaoyan.dataInterface;
import com.cskaoyan.model.User;

public interface UserData
{
    //用戶数据访问接口,由具体的数据存储仓库去实现
    public boolean findUserNameInXml(String username);
    public int saveUserToXml(User user);
    public boolean findUserNameInXml(String username, String password);
    public String findHeadingPathInXml(String username);
}
5.写model实现对数据库的增删改查来保存user信息
  • 需要实现数据接口层的具体方法
MySql.java
package com.cskaoyan.model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.cskaoyan.dataInterface.UserData;
import com.cskaoyan.db.utils.DBUtils;

//实现对具体类型的数据仓库的操作
public class MySql implements UserData
{
//判断注册用户名是否已经存在
    public boolean findUserNameInXml(String username)
    {
        boolean ret = false;

        Connection conn = null;
        ResultSet rs = null;
        PreparedStatement st = null;

        try
        {
            conn = DBUtils.getConnection();

            st = conn.prepareStatement("select * from user where username = ?;");
            st.setString(1, username);
            rs = st.executeQuery();

            if (rs.next())
            {// 结果集不为空,说明对应用户名和密码有
                ret = true;
            }

        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }

        return ret;
    }

//把用户信息记录插入到数据库中
    public int saveUserToXml(User user)
    {
        int ret = -1;

        Connection conn = null;
        ResultSet rs = null;
        PreparedStatement st = null;

        try
        {
            conn = DBUtils.getConnection();
            st = conn.prepareStatement("insert into user values(?,?,?,?); ");

            st.setString(1, user.getUsername());
            st.setString(2, user.getPassword());
            st.setString(3, user.getEmail());
            st.setString(4, user.getHeading_path());

            ret = st.executeUpdate();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }

        return ret;
    }
}
6.写service封装对数据库的具体操作(多态)
UserService.java
package com.cskaoyan.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

import org.apache.commons.fileupload.FileItem;
import com.cskaoyan.dataInterface.UserData;
import com.cskaoyan.model.MySql;
import com.cskaoyan.model.User;

//service层,实现业务逻辑,分派业务给具体的数据仓库去实现
public class UserService
{
//判读注册用户名是否存在
    public boolean isUserNameExists(String username)
    {
        UserData userData = new MySql();
        boolean isExists = userData.findUserNameInXml(username);

        return isExists;
    }

//保存用户信息到数据库中
    public int registerUser(User user)
    {
        UserData userData = new MySql();
        userData.saveUserToXml(user);

        return 1;
    }

    public String getPicturePath(String username)
    {
        UserData userData = new MySql();
        String picturePath = userData.findHeadingPathInXml(username);
        return picturePath;
    }


    //处理文件数据,得到图片路径
    public String getFilePath(FileItem item, String uploadImgDirString)
    {
        //拼接获取图片的绝对路径
        String ret = null;
        String fileName = item.getName(); // 文件名
        try
        {
            InputStream inputStream = item.getInputStream();

            // UUID文件重名的问题
            UUID randomUUID = UUID.randomUUID();
            String finalImageFilename = randomUUID.toString() + fileName;

            // 文件目录规划的问题
            // 在指定文件夹下创建一个新的文件
            File file = new File(uploadImgDirString, finalImageFilename);
            FileOutputStream fos = new FileOutputStream(file);

            //输出流保存图片到服务器硬盘的指定位置
            byte[] b = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(b)) != -1)
            {
              fos.write(b, 0, len);
            }
            fos.close();

            ret = file.getAbsolutePath();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

           return ret;
        }

}

(二)登陆界面前后端

1.写注册成功后跳转到的登陆界面JSP
login.jsp
<form action="${pageContext.request.contextPath}/servlet/LoginServlet" method="get">
    用户名 <input type="text" name="username" /><br>
    密 &nbsp;码 <input type="password" name="password" /><br>
    <input type="submit" value="登录" />
</form>
2.写处理登录成功的servlet控制器
  • 需要把用户登陆的用户名,密码保存到session中,通服务器后台数据库中的数据进行验证
  • 需要利用得到的用户名去数据库中查找保存的图片路径,取出来保存到session中
  • 以上两个方法的实现需要到service中写
LoginServlet.java
package com.cskaoyan.servlet;

public class LoginServlet extends HttpServlet
{

    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {

        //验证用户名密码是否与服务器上一致
        response.setContentType("text/html;charset=utf-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        UserService service = new UserService();
            //找到图片路径
        String path = service.getPicturePath(username);
            //验证用户名和密码与数据库已保存的注册信息是否一致
        boolean flag  = service.checkUserInfo(username, password);

        if (flag)
        {
            // 把用户信息和图片路径放到Session里
            HttpSession session = request.getSession(true);
            session.setAttribute("username", username);
            session.setAttribute("password", password);
            session.setAttribute("heading_path", path);

            response.getWriter().println("登陆成功,即将跳转到主页");
            response.setHeader("refresh", "1;url='" + request.getContextPath() + "/index.jsp'");
        }
        else
        {
            response.getWriter().println("用户名密码输入错误,请重新登陆");
            response.setHeader("refresh", "1;url='"+request.getContextPath()+"/login.jsp'");
        }

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
       doGet(request, response);
    }

}
3.写登陆界面的service和数据访问接口
  • //验证用户名密码是否与服务器上一致
  • //找到图片路径
UserService.java
public String getPicturePath(String username)
   {
       UserData userData = new MySql();
       String picturePath = userData.findHeadingPathInXml(username);
       return picturePath;
   }

   public boolean checkUserInfo(String username, String password)
   {
       UserData userData = new MySql();
       boolean isUserInfOk = userData.findUserNameInXml(username, password);

       return isUserInfOk;
   }
MySql.java
public boolean findUserNameInXml(String username, String password)
{
    boolean ret = false;

    Connection conn = null;
    ResultSet rs = null;
    PreparedStatement st = null;

    try
    {
        conn = DBUtils.getConnection();

        st = conn.prepareStatement("select * from user where username = ? and password =? ; ");

        st.setString(1, username);
        st.setString(2, password);

        rs = st.executeQuery();

        if (rs.next())
        {
            ret = true; // 结果集不为空,说明存在对应用户名
        }

    }
    catch (SQLException e)
    {
        e.printStackTrace();
    }

    return ret;
}


public String findHeadingPathInXml(String username)
{
    String headimg_path = null;
    Connection conn = null;
    ResultSet rs = null;
    PreparedStatement ps;

     try
    {
        conn = DBUtils.getConnection();

        ps = conn.prepareStatement("select * from user where username = ?;");
        System.out.println(username);
        ps.setString(1, username);
        rs = ps.executeQuery();

          //查
        while (rs.next())
        {
             headimg_path = rs.getString("headimg_path");
         }
    }

    catch (SQLException e)
    {
        e.printStackTrace();
    }
        return headimg_path;
    }

(三)写登陆成功的主页

1.登陆成功的界面JSP
  • 需要显示用户图像和用户名
  • 需要有注销按钮
<body>
   <h1>个人主页</h1> <br>
   <hr>
   <%
       response.setContentType("text/html;charset=utf-8");
       String username = (String)  pageContext.getAttribute("username", PageContext.SESSION_SCOPE);
       String headPath = (String) pageContext.getAttribute("heading_path", PageContext.SESSION_SCOPE);

       if (username ==null)
       {
   %>
       <a href = "${pageContext.request.contextPath}/login.jsp">登录&nbsp;&nbsp;</a>
       <a href = "${pageContext.request.contextPath }/register.jsp">注册</a>
   <%
       }
       else
       {
   %>

    <img src='<%=headPath%>'/>
   ${username},&nbsp;欢迎您!<br>
   <a href = '${pageContext.request.contextPath}/servlet/LogoutServlet'>注销</a>

   <%
        }
   %>

  </body>
2.注销Servlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException
   {
       response.setContentType("text/html;charset=utf-8");
       HttpSession session = request.getSession(false);

       if (session != null)
       {
           session.invalidate();
           response.getWriter().println("正在注销,1秒后跳转到主页");
           response.setHeader("refresh", "1;url='"+request.getContextPath()+"/index.jsp'");
       }
   }

   public void doPost(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException
   {
       doGet(request, response);
   }

(四)利用Junit测试各函数是否正常运行

package com.cskaoyan.test;
import junit.framework.Assert;
import org.junit.Test;
import com.cskaoyan.model.MySql;
import com.cskaoyan.model.User;

@SuppressWarnings("deprecation")
public class FunctionTest
{
    @Test
    public void testMySaveUser()
    {
        MySql model = new MySql();

        User user = new User("aa", "aa", "aa", "bb");

        int saveUserToXml = model.saveUserToXml(user);

        System.out.println(saveUserToXml);
    }

    @Test
    public void testMyFindUser()
    {
        MySql model = new MySql();

        boolean ret = model.findUserNameInXml("aa", "bb");

        // 断言
        Assert.assertEquals(false, ret);
    }

    @Test
    public void testMyFindUsername()
    {
        MySql model = new MySql();
        boolean ret = model.findUserNameInXml("cc");

        Assert.assertEquals(true, ret);
    }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值