用MVC模式来改写用户登录验证程序【JavaWeb】【附完整代码】【数据库应用开发】连接数据库登录注册功能实现

实验八 MVC模式

一、实验要求

用MVC模式来改写用户登录验证程序

二、实验步骤/代码

2.1项目结构

如果需要功能更完善、代码更简洁以及bug更少的代码,可以到我的小程序 航筱北同学上搜索查看。里面还有很多实战项目和面试话术。

2.2实现代码

实现了model模型层、view视图层、controller控制层的分离。

具体代码见文档尾,可点击链接跳转查看

User.java

UserDao.java

JdbcUtils.java

JdbcUserDaoImpl.java

DaoFactory.java

UserException.java

UserService.java

CommonUtils.java

LoginServlet.java

RegistServlet.java

VerifyCode.java

VerifyCodeServlet.java

welcome.jsp

regist.jsp

index.jsp

三、实验结果

运行截图:

  • 启动server,进入localhost:8080

  • 根据提示,点击跳转到登录页面进行登录

  • 输入信息登录,发现用户名不存在,原因是数据库没有这个用户名。再点击去注册,跳转至注册页面。

  • 首先,密码长度有限制,登录名也有限制,如果存在用户名,会提示用户名已存在。

  • 满足要求填写注册表单后,提示注册成功,而且此时,刷新数据库,会看到刚刚注册的信息。

 

  • 根据提示我们来到登录页登录,并试着故意输错密码,显示密码错误。

  • 输入正确密码后,成功进入。获取数据库信息并显示到页面。

附:

实现代码:

User.java

package domain;

  

  

public class User {

    private String username;

    private String password;

    private String verifyCode;

    private int age;

    private String gender;

  

    public int getAge() {

        return age;

    }

  

    public void setAge(int age) {

        this.age = age;

    }

  

    public String getGender() {

        return gender;

    }

  

    public void setGender(String gender) {

        this.gender = gender;

    }

  

    public String getVerifyCode() {

        return verifyCode;

    }

  

    public void setVerifyCode(String verifyCode) {

        this.verifyCode = verifyCode;

    }

  

    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;

    }

  

    @Override

    public String toString() {

        return super.toString();

    }

}

UserDao.java

package dao;

  

import domain.User;

  

public interface UserDao {

    public User findByUsername(String username);

  

    public void add(User user);

  }

JdbcUtils.java

package util;

  

import java.io.InputStream;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.util.Properties;

  

  

public class JdbcUtils {

    private static Properties properties = null;

  

    static {

        //家在配置文件到properties文件中

        try {

            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbconfig.properties");

            properties = new Properties();

            properties.load(in);

        } catch (Exception e) {

            throw new RuntimeException(e);

        }

  

        try {

            Class.forName(properties.getProperty("driverClassName"));

        } catch (Exception e) {

            throw new RuntimeException(e);

        }

    }

  

    public static Connection getConnection() throws SQLException {

  

  

        return DriverManager.getConnection(properties.getProperty("url"),

                properties.getProperty("username"),

                properties.getProperty("password"));

  

  

    }

}

JdbcUserDaoImpl.java

package dao;

  

import domain.User;

import util.JdbcUtils;

  

import java.sql.*;

  

public class JdbcUserDaoImpl implements UserDao {

  

    @Override

    public User findByUsername(String username) {

        Connection connection = null;

        PreparedStatement ps = null;

        ResultSet rs = null;

        User user = new User();

        try {

            connection = JdbcUtils.getConnection();

            String sql = "SELECT * FROM t_user WHERE username=?";

            ps = connection.prepareStatement(sql);

            ps.setString(1, username);

            rs = ps.executeQuery();

            if (rs == null) return null;

            if (rs.next()) {

                user.setUsername(rs.getString("username"));

                user.setPassword(rs.getString("password"));

                user.setAge(rs.getInt("age"));

                user.setGender(rs.getString("gender"));

                return user;

            } else {

                return null;

            }

  

        } catch (Exception e) {

            throw new RuntimeException(e);

        } finally {

            try {

                if (rs != null) rs.close();

                if (ps != null) ps.close();

                if (connection != null) connection.close();

            } catch (Exception e) {

                throw new RuntimeException(e);

            }

        }

  

    }

  

    @Override

    public void add(User user) {

        Connection connection = null;

        PreparedStatement ps = null;

        try {

            connection = JdbcUtils.getConnection();

            String sql = "insert into t_user values(?,?,?,?)";

            ps = connection.prepareStatement(sql);

            ps.setString(1, user.getUsername());

            ps.setString(2, user.getPassword());

            ps.setInt(3, user.getAge());

            ps.setString(4, user.getGender());

            ps.executeUpdate();

        } catch (Exception e) {

            throw new RuntimeException(e);

        } finally {

            try {

                if (ps != null) ps.close();

                if (connection != null) connection.close();

            } catch (Exception e) {

                throw new RuntimeException(e);

            }

        }

  

    }

}

DaoFactory.java

package dao;

  

import java.io.InputStream;

import java.util.Properties;

  

public class DaoFactory {

    private static Properties properties = null;

  

    static {

        //加在配置文件到properties文件中

        try {

            InputStream in = DaoFactory.class.getClassLoader().getResourceAsStream("dao.properties");

            properties = new Properties();

            properties.load(in);

        } catch (Exception e) {

            throw new RuntimeException(e);

        }

    }

  

    //返回一个具体实现UserDao的实现类

    public static UserDao getUserDao() {

        /*

         *给出一个配置文件,文件中给出UserDao接口的实现类名称

         * 我们这个方法,获取实现类的类名,通过反射创建对象

         */

  

        try {

            Class clazz = Class.forName(properties.getProperty("dao.UserDao"));

            return (UserDao) clazz.newInstance();

        } catch (Exception e) {

            throw new RuntimeException(e);

        }

  

    }

}

UserException.java

package service;


public class UserException extends Exception {

    public UserException(String message) {

        super(message);

    }

}

UserService.java

package service;

  

import dao.DaoFactory;

import dao.UserDao;

  

import domain.User;

  

  

public class UserService {

    UserDao userDao = DaoFactory.getUserDao();

  

    public void regist(User user) throws UserException {

        User _user = userDao.findByUsername(user.getUsername());

        if (_user != null) {

            throw new UserException("用户名" + user.getUsername() + "已被注册");

        }

        userDao.add(user);

    }

  

    public User login(User user) throws UserException {

        User _user = userDao.findByUsername(user.getUsername());

        if (_user == null) {

            throw new UserException("用户名不存在");

        }

        if (!user.getPassword().equals(_user.getPassword())) {

            throw new UserException("密码错误");

        }

        return _user;

    }

}

CommonUtils.java

package util;

  

import org.apache.commons.beanutils.BeanUtils;

  

import java.util.Map;

import java.util.UUID;

  

public class CommonUtils {

    public static <T> T toBean(Map map, Class<T> clazz) {

        try {

            T bean = clazz.newInstance();

            BeanUtils.populate(bean, map);

            return bean;

        } catch (Exception e) {

            throw new RuntimeException(e);

        }

    }

}

LoginServlet.java

package servlet;

  

import domain.User;

import service.UserException;

import service.UserService;

import util.CommonUtils;

  

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

  

public class LoginServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

  

        request.setCharacterEncoding("utf-8");

        response.setContentType("text/html;charset=utf-8");

  

        /*

         * 获取表单数据,将用户名在数据库中查找

         * 1.成功,比较得到的密码和表单中的密码是否一样,一样则成功,不一样则返回密码错误信息

         * 2.失败,返回用户名错误的信息

         */

        User form=CommonUtils.toBean(request.getParameterMap(),User.class);

        UserService userService=new UserService();

        try {

            User user= userService.login(form);

            request.getSession().setAttribute("sessionUser",user);

            response.sendRedirect(request.getContextPath()+"/user/welcome.jsp");

        } catch (UserException e) {

            request.setAttribute("user",form);

            request.setAttribute("msg",e.getMessage());

            request.getRequestDispatcher("/user/login.jsp").forward(request,response);

  

        }

    }

}

RegistServlet.java

package servlet;

  

import domain.User;

import service.UserException;

import service.UserService;

import util.CommonUtils;

  

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.util.HashMap;

import java.util.Map;

  

  

public class RegistServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

  

        request.setCharacterEncoding("utf-8");

        response.setContentType("text/html;charset=utf-8");

  

        UserService userService=new UserService();

        User form=CommonUtils.toBean(request.getParameterMap(),User.class);

  

        //校验用户名、密码是否为空,长度要在3-15之间,验证码要正确

        Map<String,String> errors=new HashMap<>();

        String username=form.getUsername();

        if (username==null||username.trim().isEmpty())

        {

            errors.put("username","用户名不能为空");

        }else if (username.length()<2||username.length()>15)

        {

            errors.put("username","用户名长度应该在215之间");

        }

  

        String password=form.getPassword();

        if (password==null||password.trim().isEmpty())

        {

            errors.put("verifyCode","密码不能为空");

        }else if (password.length()<3||password.length()>15)

        {

            errors.put("password","密码长度应该在315之间");

        }

  

        String verifyCode=form.getVerifyCode();

        String sessionVerifyCode=(String) request.getSession().getAttribute("session_vcode");

        if (verifyCode==null||verifyCode.trim().isEmpty())

        {

            errors.put("verifyCode","验证码不能为空");

        }else if (verifyCode.length()!=4)

        {

            errors.put("verifyCode","验证码长度应该在为4");

        }else if (!sessionVerifyCode.equalsIgnoreCase(verifyCode))

        {

            errors.put("verifyCode","验证码错误");

        }

  

        if (errors!=null&&errors.size()>0)

        {

            request.setAttribute("errors",errors);

            request.setAttribute("user",form);

            request.getRequestDispatcher("/user/regist.jsp").forward(request,response);

            return;

        }

  

  

        try {

            userService.regist(form);

            response.getWriter().println("<h1>注册成功</h1><a href='"+request.getContextPath()+"/user/login.jsp"+"'>点击这里去登录</a>");

        } catch (UserException e) {

            request.setAttribute("user",form);

            request.setAttribute("msg",e.getMessage());

            request.getRequestDispatcher("/user/regist.jsp").forward(request,response);

        }

    }

}

VerifyCode.java

package util;

  

  

import javax.imageio.ImageIO;

import java.awt.*;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Random;

  

  

public class VerifyCode {

    private int width = 70;//设置图片缓冲区的宽

    private int height = 35;//设置图片缓冲区的高

    private Random r = new Random();//生成随机数字

    private String[] fontNames = {"宋体", "华文楷体", "黑体", "微软雅黑"};//创建一个字体数组

    private Color bgColor = new Color(255, 255, 255);//创建图片的白色背景

    private String codes = "23456789zxcvbnmasdfgjkqwertyui";//可供选择的随机文字

    private String text;//在图片上生成的文本

  

    /*

     * 创建图片缓冲区

     */

    public BufferedImage getImage() {

        BufferedImage image = createImage();//1.调用创建图片缓冲区方法

        Graphics g = image.getGraphics();//3.得到绘制环境

        StringBuilder sb = new StringBuilder();//用来装载生成的验证码文本

        /*

        循环四次

        每次生成一个字符

         */

        for (int i = 0; i < 4; i++) {

            String str = randomChar() + "";//调用产生随机字符方法,随机生成一个字符

            sb.append(str);//将生成的随机字符加到sb后面

            g.setFont(randomFont());//调用产生随机字体方法

            g.setColor(randomColor());//调用产生随机颜色方法

            g.drawString(str, i * width / 5, height - 5);//在图片中绘制文本

        }

        this.text = sb.toString();//把生成字符串赋给文本

        drawLine(image);//调用添加干扰线方法对图片中的文本进行干扰

        return image;

    }

  

    /*

     * 返回验证码图片上的文本,

     * 此方法必须在getImage()方法调用之后

     *

     */

    public String getText() {

        return this.text;

    }

  

    /*

     *保存图片到指定的输出流

     */

    public static void output(BufferedImage image, OutputStream out) throws IOException {

        ImageIO.write(image, "JPEG", out);

    }

  

    /*

     *创建图片缓冲区方法

     */

    private BufferedImage createImage() {

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        Graphics g = image.getGraphics();

        g.setColor(bgColor);

        g.fillRect(0, 0, width, height);

        return image;

    }

  

    /*

     * 生成随机字符方法

     */

    public char randomChar() {

        int index = r.nextInt(codes.length());

        char y = codes.charAt(index);

        return y;

    }

  

    /*

     *生成随机字体

     */

    public Font randomFont() {

        int index = r.nextInt(fontNames.length);

        int style = r.nextInt(4);//设置字体样式,0表示无样式,1表示粗体,2表示斜体,3表示粗体加斜体

        int size = r.nextInt(4) + 19;//设置字体大小,范围在24-27之间

        return new Font(fontNames[index], style, size);

    }

  

    /*

     *生成随机颜色方法

     */

    public Color randomColor() {

        int red = r.nextInt(150);

        int green = r.nextInt(150);

        int blue = r.nextInt(150);

        return new Color(red, green, blue);

    }

  

    /*

     *生成干扰线方法

     */

    public void drawLine(BufferedImage image) {

        //循环三次,画三条干扰线

        //先取到画笔,然后才能画线嘛!

        Graphics graphics = image.getGraphics();

        for (int i = 0; i < 3; i++) {

            int x1 = r.nextInt(width);

            int y1 = r.nextInt(height);

            int x2 = r.nextInt(width);

            int y2 = r.nextInt(height);//得到所要划线的起点和终点坐标

            graphics.setColor(Color.BLUE);//设置干扰线颜色

            graphics.drawLine(x1, y1, x2, y2);

        }

    }

}

VerifyCodeServlet.java

package servlet;

  

import util.VerifyCode;

  

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.awt.image.BufferedImage;

import java.io.IOException;

  

  

public class VerifyCodeServlet extends HttpServlet {

  

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

        VerifyCode vc = new VerifyCode();

        BufferedImage image = vc.getImage();

        request.getSession().setAttribute("session_vcode", vc.getText());

        VerifyCode.output(image, response.getOutputStream());

    }

}

dao.properties

dao.UserDao=dao.JdbcUserDaoImpl

dbconfig.properties

driverClassName=com.mysql.cj.jdbc.Driver

  url=jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8

  username=root

  password=liulei2021

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"

         version="4.0">

    <servlet>

        <servlet-name>RegistServlet</servlet-name>

        <servlet-class>servlet.RegistServlet</servlet-class>

    </servlet>

    <servlet>

        <servlet-name>VerifyCodeServlet</servlet-name>

        <servlet-class>servlet.VerifyCodeServlet</servlet-class>

    </servlet>

    <servlet>

        <servlet-name>LoginServlet</servlet-name>

        <servlet-class>servlet.LoginServlet</servlet-class>

    </servlet>

  

  

    <servlet-mapping>

        <servlet-name>RegistServlet</servlet-name>

        <url-pattern>/RegistServlet</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

        <servlet-name>VerifyCodeServlet</servlet-name>

        <url-pattern>/VerifyCedeServlet</url-pattern>

    </servlet-mapping>

    <servlet-mapping>

        <servlet-name>LoginServlet</servlet-name>

        <url-pattern>/LoginServlet</url-pattern>

    </servlet-mapping>

</web-app>

welcome.jsp

<%--
  Created by IntelliJ IDEA.
  User: Liu'lei
  Date: 2021/11/5
  Time: 17:23
  To change this template use File | Settings | File Templates.
--%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>
欢迎页</title>
</head>
<body>
<h1>
欢迎页</h1>
<c:choose>
    <c:when test="${ empty sessionScope.sessionUser}">您还没有登录,<a href="<c:url value='/user/login.jsp'/> ">点击这里跳转到登录页面.</a> </c:when>
    <c:otherwise>您好啊,${sessionScope.sessionUser.username}<br/>
       
你的个人信息如下:<br/>
       
用户名:${sessionScope.sessionUser.username}<br/>
       
性 别:${sessionScope.sessionUser.gender}<br/>
       
年 龄:${sessionScope.sessionUser.age}<br/>
   
</c:otherwise>
</c:choose>
</body>
</html>

login.jsp

<%--

  Created by IntelliJ IDEA.

  User: Liu'lei

  Date: 2021/11/5

  Time: 17:22

  To change this template use File | Settings | File Templates.

--%>

  <%@ page contentType="text/html;charset=UTF-8" language="java" %>

  <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

  <html>

<head>

    <title>登录页</title>

</head>

<body>

<h1>登录</h1>

<p style="color:red;font-weight: 900">${msg}</p>

<form action="<c:url value='/LoginServlet'/> " method="post">

    用户名:<input type="text" name="username" value="${user.username}"/>${errors.username}<br/>

    密  码:<input type="password" name="password" value="${user.password}"/>${errors.password}<br/>

    <input type="submit" value="登录"><br/><br/>

    <a href="/user/regist.jsp">没有账号?点击去注册!</a>

</form>

</body>

</html>

regist.jsp

<%--

  Created by IntelliJ IDEA.

  User: Liu'lei

  Date: 2021/11/5

  Time: 17:22

  To change this template use File | Settings | File Templates.

--%>

  <%@ page contentType="text/html;charset=UTF-8" language="java" %>

  <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

  <html>

<head>

    <title>注册页</title>

  

    <script type="text/javascript">

        function _change() {

            var ele=document.getElementById("vCode");

            ele.src="<c:url value='/VerifyCedeServlet'/>?xxx="+new Date().getTime();

        }

    </script>

</head>

<body>

<h1>注册</h1>

<p style="color:red;font-weight: 900">${msg}</p>

<form action="<c:url value='/RegistServlet'/> " method="post">

    用户名:<input type="text" name="username" value="${user.username}"/>${errors.username}<br/>

    密  码:<input type="password" name="password" value="${user.password}"/>${errors.password}<br/>

    性 别:<input type="radio" name="gender" value="" checked="checked"/>${errors.gender}&nbsp;<input type="radio" name="gender" value="" />${errors.gender}<br/>

    年 龄:<input type="number" name="age" value="${user.age}"/>${errors.age}<br/>

    验证码:<input type="text" name="verifyCode" value="${user.verifyCode}" size="10"/>${errors.verifyCode}

    <img id="vCode" src="<c:url value='/VerifyCedeServlet'/> ">

    <a href="javascript:_change()"> 点击更换 </a><br/>

    <input type="submit" value="提交"><br/>

</form>

</body>

</html>

index.jsp

<%--

  Created by IntelliJ IDEA.

  User: Liu'lei

  Date: 2021/11/5

  Time: 17:19

  To change this template use File | Settings | File Templates.

--%>

  <%@ page contentType="text/html;charset=UTF-8" language="java" %>

  <html>

<head>

    <title>首页跳转</title>

</head>

<body>

  <jsp:forward page="./user/welcome.jsp"></jsp:forward>

  </body>

</html>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值