Java WEB管理系统

Java WEB管理系统


java web 第二次作业讲解

需求分析

要求完成注册登录以及表单验证

完成登录之后跳转至首页

概要设计

技术选型

依赖管理:maven

异步交互:AJAX

数据库:MySQL5.6

交互数据格式:JSON

测试:Junit

采用姓名和学号登录(坑)。

文件目录以及梳理:


│  pom.xml       # maven配置文件
├─src 			# 源代码路径
│  ├─main
│  │  ├─java
│  │  │  ├─dao	# 访问数据库
│  │  │  │  │  LiangZaiDao.java		# 访问靓仔数据库的接口
│  │  │  │  │  
│  │  │  │  └─imlp
│  │  │  │          LiangZaiDaoImpl.java 	# 靓仔dao的实现类
│  │  │  │          
│  │  │  ├─filter
│  │  │  │      CharacterFilter.java	# 字符过滤器
│  │  │  │      LoginFilter.java	# 首页过滤器
│  │  │  │      
│  │  │  ├─pojo		# 实体
│  │  │  │      LiangZai.java		# 靓仔实体类
│  │  │  │      ResultInfo.java		# 响应数据类
│  │  │  │      
│  │  │  ├─service		# 业务
│  │  │  │  │  LiangZaiService.java		# 靓仔业务逻辑接口
│  │  │  │  │  
│  │  │  │  └─impl
│  │  │  │          LiangZaiServiceImpl.java	# 靓仔业务逻辑实现类
│  │  │  │          
│  │  │  ├─servlet		# 处理前后端交互
│  │  │  │      LoginServlet.java		# 处理登录交互
│  │  │  │      RegisterServlet.java	# 处理注册交互
│  │  │  │      
│  │  │  └─utils
│  │  │          DbUtil.java	# JDBC工具类
│  │  │          
│  │  ├─resources
│  │  │      db.propertice		# JDBC配置
│  │  │      
│  │  └─webapp		# 前端代码
│  │      │  index.html		# 首页
│  │      │  login.html		# 登录页面
│  │      │  register.html	# 注册页面
│  │      ├─css
│  │      │      layui.css
│  │      │      style.css
│  │      ├─img    
│  │      └─js
│  │              
│  └─test		# 测试类
│      └─java
│              LiangDaoTest.java		# Dao测试类

总体设计

第一步:数据库搭建

此处仅提供数据库结构,因为本次作业不是我主要负责,所以我取名比较随意(靓仔),实际开发请勿模仿。

自行根据自己的想法修改数据库并添加数据。

DROP TABLE IF EXISTS `liangzai`;
CREATE TABLE `liangzai`  (
  `id` int(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  `sex` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  `class` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  `stu_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  `password` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;

第二步:IDEA创建项目

建议创建maven项目或java ee项目(spring 项目也行),此处采用java ee项目(tomcat8.0以上支持cookie写入中文,servlet3.0以上支持注解配置)

在这里插入图片描述

在这里插入图片描述

项目目录如下:

在这里插入图片描述

因为采用异步交互,所以删去index.jsp文件。

第三步:导入依赖

在pom.xml文件中粘贴以下代码

<dependencies>
	<!--项目创建好自带的servlet-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
    <!--MySQL数据库连接依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.37</version>
        </dependency>
	<!--junit测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>RELEASE</version>
            <scope>test</scope>
        </dependency>
        <!--beanUtils-->
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.2</version>
            <scope>compile</scope>
        </dependency>
        <!--jackson-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.3.3</version>
        </dependency>
    </dependencies>

第四步:创建实体类

需要在java文件夹下创建一个pojo文件夹并在其中新建两个类一个为:LiangZai,一个为ResultInfo。LiangZai用于映射数据库,ResultInfo用于与前端的交互

具体代码如下:

package pojo;

/**
 * @author 北落燕门
 */
public class LiangZai {
    private int id;
    private String name;
    private String sex;
    private String banJi;
    private String stuId;

    @Override
    public String toString() {
        return "Liang{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", banJi='" + banJi + '\'' +
                ", stuId='" + stuId + '\'' +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getBanJi() {
        return banJi;
    }

    public void setBanJi(String banJi) {
        this.banJi = banJi;
    }

    public String getStuId() {
        return stuId;
    }

    public void setStuId(String stuId) {
        this.stuId = stuId;
    }

    public LiangZai(int id, String name, String sex, String banJi, String stuId) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.banJi = banJi;
        this.stuId = stuId;
    }

    public LiangZai() {
    }
}

package pojo;


/**
 * @author 北落燕门
 */
public class ResultInfo {
    private boolean flag;
    private Object data;
    private String msg;

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String errorMsg) {
        this.msg = errorMsg;
    }

    public ResultInfo(boolean flag, Object data, String errorMsg) {
        this.flag = flag;
        this.data = data;
        this.msg = errorMsg;
    }

    public ResultInfo() {
    }
}

第五步:连接数据库

编写配置文件

在resources文件夹下创建db.propertice文件然后输入以下内容

driver = com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/[数据库名称]?UseUnicode=true&characterEncoding=UTF-8
username = [数据库用户名]
password = [数据库密码]
实现JDBC建立连接

在java文件夹下新建utils文件夹并创建DbUtil类,内容如下:

package utils;


import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Driver;

import java.io.FileReader;
import java.net.URL;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

/**
 * @author 北落燕门
 */
public class DbUtil {
    private static String url;
    private static String username;
    private static String password;
    //使用静态方法自动执行
    static {
        try {
            //实用反射将db.propertice文件加载进内存
            Properties pro = new Properties();
            ClassLoader classLoader = Driver.class.getClassLoader();
            URL resource = classLoader.getResource("db.propertice");
            assert resource != null;
            String path = resource.getPath();
            FileReader fileReader = new FileReader(path);
            pro.load(fileReader);
            //获取db.propertice文件的内容
            String driver = pro.getProperty("driver");
            url = pro.getProperty("url");
            username = pro.getProperty("username");
            password = pro.getProperty("password");
            //加载驱动
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 建立连接
     * @return 返回Connecting连接对象
     * @throws Exception 抛出异常
     */
    public  static Connection getConnection()throws Exception{
       return (Connection) DriverManager.getConnection(url, username, password);
    }

    /**
     * 关闭连接
     * @param ps
     * @param conn
     */
    public static void close(PreparedStatement ps, Connection conn){
        if (ps!=null){
            try {
                ps.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }else if (conn!=null){
            try {
                conn.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 方法重载 关闭连接
     * @param rs
     * @param ps
     * @param conn
     */
    public static void close(ResultSet rs, PreparedStatement ps, Connection conn){
        if (rs!=null){
            try {
                rs.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }else if (ps!=null){
            try {
                ps.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }else if (conn!=null){
            try {
                conn.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

第六步:实现Dao层

之后在java文件夹下创建dao文件夹,并创建LiangZaiDao接口

根据任务需求我们需要实现添加实体、查询实体的功能,因此创建以下三个抽象方法

    /**
     * 通过id和password查找
     * @param name 姓名
     * @param stuId 班级
     * @return flag
     */
    boolean findByNameAndStuId(String name, String stuId);

    /**
     * 通过用户名和密码查找
     * @param id id
     * @return flag
     */
    boolean findById(int id);

    /**
     * 添加
     * @param lz 传入靓仔对象
     * @return flag
     */
    boolean add(LiangZai lz);

之后在dao文件夹下新建impl文件夹并创建LiangZaiDaoImpl类继承LiangZaiDao接口并复写其中所有方法。返回值boolean类型用于判断是否执行成功。代码如下:

public class LiangZaiDaoImpl implements LiangZaiDao {
    Connection conn = null;
    PreparedStatement pstm = null ;
    ResultSet rs = null;
    /**
     * 用于登录界面在数据库中查询姓名与学号
     * @param name 姓名
     * @param stuId 学号
     * @return flag
     */
    @Override
    public boolean findByNameAndStuId(String name, String stuId) {
        //编写sql
        String sql = "SELECT * FROM liangzai WHERE name = ? AND stu_id = ?";
        try {
            //调用DbUtil建立连接
            conn = DbUtil.getConnection();
            //开启事务
            conn.setAutoCommit(false);
            //绑定sql
            pstm = conn.prepareStatement(sql);
            //补全sql语句
            pstm.setString(1,name);
            pstm.setString(2,stuId);
            //执行sql
            rs = pstm.executeQuery();
            if (rs.next()){
                //提交
                conn.commit();
                return true;
            }

        } catch (Exception e) {
            try {
                //回滚
                if (conn!=null){
                    conn.rollback();
                }
            }catch (Exception e1){
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            //关闭数据库连接
            DbUtil.close(rs,pstm,conn);
        }
        return false;
    }

    /**
     * 用于查询用户是否存在(不用于登录)
     * @param id id
     * @return flag
     */
    @Override
    public boolean findById(int id) {
        //编写sql
        String sql = "SELECT * FROM liangzai WHERE id = ?";
        try {
            //建立连接
            conn = DbUtil.getConnection();
            //开启事务
            conn.setAutoCommit(false);
            //绑定sql语句
            pstm = conn.prepareStatement(sql);
            pstm.setInt(1,id);
            //执行sql
            rs = pstm.executeQuery();
            if (rs.next()){
                conn.commit();
                return true;
            }
        } catch (Exception e) {
            try{
                if (conn!=null){
                    //回滚
                    conn.rollback();
                }
            }catch (Exception e1){
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            //关闭数据库连接
            DbUtil.close(rs,pstm,conn);
        }
        return false;
    }

    /**
     * 用于注册等对数据库进行添加的操作
     * @param lz 传入靓仔对象
     * @return flag
     */
    @Override
    public boolean add(LiangZai lz) {
        //编写sql
        String sql = "INSERT INTO liangzai(name,sex,class,stu_id) VALUES(?,?,?,?)";
        try {
            //建立连接
            conn = DbUtil.getConnection();
            //开启事务
            conn.setAutoCommit(false);
            pstm = conn.prepareStatement(sql);
            pstm.setString(1,lz.getName());
            pstm.setString(2,lz.getSex());
            pstm.setString(3,lz.getBanJi());
            pstm.setString(4,lz.getStuId());
            int i = pstm.executeUpdate();
            if (i!=0){
                //提交事务
                conn.commit();
                return true;
            }
        } catch (Exception e) {
            try{
                if (conn!=null){
                    //回滚
                    conn.rollback();
                }
            }catch (Exception e1){
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            //关闭连接
            DbUtil.close(pstm,conn);
        }
        return false;
    }
}

第七步:实现service层

在java文件夹下新建一个包命名为service其中新建一个接口命名为LiangZaiService。

package service;

import pojo.LiangZai;

/**
 * @author 北落燕门
 */
public interface LiangZaiService {
    /**
     * 登录服务
     * @param lz 靓仔实体
     * @return 返回实体对象
     */
    boolean liangZaiLogin(LiangZai lz);

    /**
     * 注册服务
     * @param lz 靓仔实体
     * @return 返回flag
     */
    boolean liangZaiRegister(LiangZai lz);
}

之后在service文件夹中新建文件夹并创建类LiangZaiServiceImpl实现LiangZaiService接口

package service.impl;

import dao.LiangZaiDao;
import dao.imlp.LiangZaiDaoImpl;
import pojo.LiangZai;
import service.LiangZaiService;

/**
 * @author 北落燕门
 */
public class LiangZaiServiceImpl implements LiangZaiService {
    LiangZaiDao lzDao = new  LiangZaiDaoImpl();

    @Override
    public boolean liangZaiLogin(LiangZai lz) {
        return lzDao.findByNameAndStuId(lz.getName(), lz.getStuId());
    }

    @Override
    public boolean liangZaiRegister(LiangZai lz) {
        boolean byNameAndStuId = lzDao.findByNameAndStuId(lz.getName(), lz.getStuId());
        if (byNameAndStuId){
            return false;
        }
        return lzDao.add(lz);
    }
}

第八步:实现servlet

注册servlet
package servlet;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.beanutils.BeanUtils;
import pojo.LiangZai;
import pojo.ResultInfo;
import service.impl.LiangZaiServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

/**
 * @author 北落燕门
 */
@WebServlet("/register")
public class RegisterServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //封装获取到的数据为map
        Map<String, String[]> map = req.getParameterMap();
        LiangZai lz = new LiangZai();
        try {
            //使用工具类将map元素封装为对象
            BeanUtils.populate(lz,map);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        System.out.println(lz);
        LiangZaiServiceImpl liangZaiService = new LiangZaiServiceImpl();
        boolean flag = liangZaiService.liangZaiRegister(lz);
        ResultInfo resultInfo = new ResultInfo();
        if (flag){
            resultInfo.setFlag(true);
            resultInfo.setMsg("注册成功");
        }else {
            resultInfo.setFlag(false);
            resultInfo.setMsg("注册失败");
        }
        //响应数据
        ObjectMapper mapper = new ObjectMapper();
        resp.setContentType("application/json;charset=UTF-8");
        mapper.writeValue(resp.getOutputStream(),resultInfo);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }
}
登录servlet
package servlet;

import com.fasterxml.jackson.databind.ObjectMapper;
import pojo.LiangZai;
import pojo.ResultInfo;
import service.LiangZaiService;
import service.impl.LiangZaiServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 北落燕门
 */
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        LiangZai lz = new LiangZai();
        ResultInfo resultInfo = new ResultInfo();
        lz.setName(req.getParameter("name"));
        lz.setStuId(req.getParameter("stuId"));
        LiangZaiService liangZaiService = new LiangZaiServiceImpl();
        boolean flag = liangZaiService.liangZaiLogin(lz);
        if (!flag){
            resultInfo.setMsg("用户名或密码错误");
            resultInfo.setFlag(false);
        }else{
            resultInfo.setMsg("登录成功");
            resultInfo.setFlag(true);
            req.getSession().setAttribute("liangzai",lz);
            //跳转首页
            //req.getRequestDispatcher("index.html").forward(req,resp);
        }
        //响应数据
        ObjectMapper mapper = new ObjectMapper();
        resp.setContentType("application/json;charset=UTF-8");
        mapper.writeValue(resp.getOutputStream(),resultInfo);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }
}

第九步:实现前台

我们需要三个页面:index.html,login.html,register.html

通过login.html的登录之后才能转跳到index.html

在webapp文件夹下新建这三个文件夹

login.html(此处只给出核心代码)

 <script>
      $(function () {
        //给登录按钮绑定单击事件
        $('#btn').click(function () {
          var serializeUrl = $('#login').serialize();
          //console.log(serializeUrl)
          $.post('/login', serializeUrl, function (data) {
            if (data.flag) {
              var serializeUrl = $('#login').serialize();
              location.href = 'index.html';
            } else {
              // var serializeUrl = $("#login").serialize();
              console.log(data);
              alert('用户名或密码错误,登录失败...');
            }
          });
        });
      });
    </script>
    <div class="switch">
      <h2>没有账号?</h2>
      <a href="register.html">注册账号</a>
    </div>
    <div class="main">
      <form action="" id="login" method="post" accept-charset="utf-8">
        <h1>欢迎访问</h1>
        <input name="name" type="text" placeholder="姓名" required />
        <input name="stuId" type="password" placeholder="学号" required />
        <button type="button" id="btn" class="btn">登录</button>
      </form>
    </div>
   </body>

register.html

 <script>
 	      $(function () {
        //表单提交时进行校验
        $('#btn').click(function () {
          // return false;
          //发送数据到服务器
          //校验通过发送ajax请求,提交表单数据
          $.post('/register', $('#registerForm').serialize(), function (data) {
            console.log($('#registerForm').serialize());
            if (data.flag) {
              alert('注册成功');
            } else {
              alert('注册失败');
            }
          });
          return false;
        });
 </script>
 
 <div class="switch">
      <h2>已有账号?</h2>
      <a href="./login.html">点击登录</a>
    </div>
    <div class="main">
      <form
        action=""
        id="registerForm"
        method="post"
        accept-charset="UTF-8"
        class="sign"
      >
        <h1>注册账号</h1>
        <input name="name" type="text" placeholder="姓名" required />
        <input name="stuId" type="text" placeholder="学号" required />
        <input name="sex" type="text" placeholder="性别" required />
        <input name="banJi" type="text" placeholder="班级" required />
        <button class="btn" id="btn" type="button">注册</button>
      </form>
    </div>
   </body>

index.html

自行补充

第十步:过滤器

这里我们需要实现两个过滤器,一个是CharacterFilter,一个是LoginFilter。CharacterFilter用于统一请求与响应的汉字编码格式为UTF-8,LoginFilter用于解决在uri直接输入/index.html便可绕过登录访问主页的问题。

CharacterFilter

package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 北落燕门
 */
@WebFilter("/*")
public class CharacterFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        //获取请求方式
        String method = req.getMethod();
        String post = "post";
        if (post.equals(method)){
            req.setCharacterEncoding("UTF-8");
        }
        //处理响应乱码
        resp.setContentType("text/html;charset=UTF-8");
        chain.doFilter(req,resp);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

LoginFilter

package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 北落燕门
 */
@WebFilter("/index.html")
public class LoginFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        Object lz = req.getSession().getAttribute("liangzai");
        if (lz!=null){
            chain.doFilter(req,resp);
        }else {
            req.setAttribute("login_msg","您尚未登录,请登录");
            req.getRequestDispatcher("login.html").forward(req,resp);
        }
    }
    @Override
    public void destroy() {
    }
}
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值