宿舍管理系统代码详解(登录界面)

        之前已经对这个管理系统进行了大体上的结构的展现,后面的篇章将对其中的前端代码进行详细的介绍与展示。

目录

一、数据库建表

二、登录界面前端代码

        1.样式展示

        2.代码详解        

(1)template部分

(2)script部分

(3)安全问题

        添加cookie:

        web会话跟踪:

三、后端代码 

1.admin

2.LoginServelet

3.LoginDao

四、过滤器


一、数据库建表

-- 管理员表
CREATE TABLE admin(
id INT PRIMARY KEY AUTO_INCREMENT,
account VARCHAR(20),
PASSWORD VARCHAR(50),
gender CHAR(1),
phone VARCHAR(11),
oper_time DATETIME
)

        管理员是不可能从前端的操作页面上添加信息的,所以一般都是在数据库中添加好管理员的信息。

二、登录界面前端代码

        1.样式展示

        2.代码详解        

        前端是以vue框架为基础搭建的,所以代码会有三部分(<template>,<script>,<style>)

(1)template部分

<template>
	<el-form ref="form" :model="form" label-width="80px">
		<el-form-item label="账号" style="width: 300px;">
			<el-input v-model="form.account"></el-input>
		</el-form-item>
		<el-form-item label="密码" style="width: 300px;">
			<el-input type="password" v-model="form.password"></el-input>
		</el-form-item>
		<el-form-item>
			<el-button type="primary" @click="onSubmit">登录</el-button>
			<el-button>取消</el-button>
		</el-form-item>
	</el-form>
</template>

        这部分是引用element-UI组件的代码,然后对代码进行修改,已达到自己想要的样式(Element - 网站快速成型工具

<el-input></el-input>简单的文本框输入,type中可添加“password”使输入的内容隐藏

<el-button></el-button>按钮组件

(2)script部分

<script>
	export default {
		data() {
			return {
				form: {
					account: "admin",
					password: "4321"
				}
			}
		},
		methods: {
			onSubmit() {
				if (this.form.account.length == 0) {
					this.$message({
						message: '账号不能为空!',
						type: 'warning'
					});
					return;
				}
				if (this.form.password.length == 0) {
					this.$message({
						message: '密码不能为空!',
						type: 'warning'
					});
					return;
				}
				//与后端交互
				this.$http.post("login", "account=" + this.form.account + "&password=" + this.form.password).then((
				resp) => {
					if (resp.data.code == 200) {
						sessionStorage.setItem("account", resp.data.result.account);
						sessionStorage.setItem("gender", resp.data.result.gender);
						sessionStorage.setItem("phone", resp.data.result.phone);
						sessionStorage.setItem("token", resp.data.result.token);
						this.$router.push("/Main");
					}
					if (resp.data.code == 201) {
						this.$message({
							message: resp.data.desc,
							type: 'warning'
						});
						return;
					} else {
						this.$message({
							message: resp.data.desc,
							type: 'warning'
						});
						return;
					}
				});


			}
		}
	}
</script>

1.data中是前端中的数据,登录需要9账号(account)和密码(password)两个数据,可以将这两个数据放在form中,方便调用

        为了测试方便,就直接在前端给账号密码赋值了,后续测试中就不用来回输入数据了,在整体的项目结束后,不要忘了在前端赋值的数据删除

2.methods——方法,用来写js中的函数,方法包含一系列语句和算法,用于执行特定的任务。通过调用方法,可以对对象进行操作、访问字段或返回特定的结果。方法是类中的核心组成部分,用于封装可重用的代码块。

3.onSubmit()函数:用来判断账号密码是否为空,不为空时才能进入到操作页面。

this.$http.post("login", "account=" + this.form.account + "&password=" + this.form.password).then((
				resp)

在js中的数据是json类型的,要传到前端需要进行序列化(即将json对象序列化为 键=值&键=值)所以需要这么一段话进行拼接,但是这只适合少量的数据,如果数据量大的话,就会十分麻烦,所以就可以写一个函数专门用来对象序列化:

function jsonToString(form) {
		var str = "";
		for (var s in form) {
			str += s + "=" + form[s] + "&";
		}
		return str.substring(0, str.length - 1);
	}

后面就可以直接调用这个函数即可。

4.从网页接受data.code值,然后进行判断。如果为200,就将管理员的数据一并由路由导航跳转到后面的操作页面,否则就进行报错。

(3)安全问题

        1.登陆成功后,在前端获取到后端响应的信息

        前端存储用户信息

        2.在前端判断用户是否登录

        目前除了访问login.vue是不需要登录,除此之外的组件,都必须是登录后才能访问

        使用vue-router中的路由导航守卫,在前端每次发生路由跳转时会触发拦截

        判断访问哪些组件,哪些组件需要登录,那些组件不需要登录

        3.路由嵌套

        在main路由下,嵌套其他的子路由

        4.后端判断用户身份

        添加cookie:
package com.ffyc.dormserver.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
后端向前端响应时,告诉前端,本次响应是安全的
 */
@WebFilter(urlPatterns = "/*")
public class CorsFilter implements Filter {
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
        HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
        //允许携带Cookie时不能设置为* 否则前端报错
        httpResponse.setHeader("Access-Control-Allow-Origin", httpRequest.getHeader("origin"));//允许所有请求跨域
        httpResponse.setHeader("Access-Control-Allow-Methods", "*");//允许跨域的请求方法GET, POST, HEAD 等
        httpResponse.setHeader("Access-Control-Allow-Headers", "*");//允许跨域的请求头
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");//是否携带cookie

        filterChain.doFilter(servletRequest, servletResponse);
    }
}
        web会话跟踪:

        因为http请求是无状态,一次请求响应结束后,就结束了,下一次再向服务器发送请求,服务器并不知道是谁向他发送的

        我们需要对整个会话过程进行跟踪:

        1.当登录时,后端验证账号密码是否正确,如果账号正确,就需要在后端为当前登录的用户生成一个令牌(token),将令牌信息响应给前端

        2.前端存储token

        3.后面每次从前端向后端发送请求,都要携带token

        4.后端验证令牌,如果令牌有效,继续向后执行,如果令牌无效,向前端返回

package com.ffyc.dormserver.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ffyc.dormserver.model.Result;
import com.ffyc.dormserver.util.JWTUtil;

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

@WebFilter(urlPatterns = "/api/*")
public class TokenFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest)servletRequest;//向下转型
        String token=request.getHeader("token");//请求头中的token
        System.out.println("token验证过滤器");
        //验证token
        boolean res= JWTUtil.verify(token);
        if(res){//token验证成功,继续向后执行,到达目标servlet程序
            filterChain.doFilter(servletRequest,servletResponse);
        }else{//token验证失败,向前端响应401
            Result result=new Result(401,"token认证失败",null);
            servletResponse.getWriter().print(new ObjectMapper().writeValueAsString(result));
        }
    }
}

三、后端代码 

1.admin

package com.ffyc.dormserver.model;

public class Admin {
    private int id;
    private String account;
    private String password;
    private String gender;
    private String phone;
    private String token;

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public int getId() {
        return id;
    }

    public String getAccount() {
        return account;
    }

    public String getPassword() {
        return password;
    }

    public String getGender() {
        return gender;
    }

    public String getPhone() {
        return phone;
    }

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

    public void setAccount(String account) {
        this.account = account;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}

在后端获取管理员的信息

2.LoginServelet

package com.ffyc.dormserver.web;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ffyc.dormserver.dao.LoginDao;
import com.ffyc.dormserver.model.Admin;
import com.ffyc.dormserver.model.Result;
import com.ffyc.dormserver.util.JWTUtil;

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.sql.SQLException;

/*
登录处理的servlet程序--web层(与前端交互的一层)
 */
@WebServlet(urlPatterns = "/login",name="login",loadOnStartup = 1)
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接收前端提交的数据
        String account=req.getParameter("account");
        String password=req.getParameter("password");
        //调用其他的程序处理
        LoginDao loginDao=new LoginDao();
        Result<Admin>result=null;//标准的数据结果
        try {
            Admin admin=loginDao.login(account,password);
            //向后端做出响应
            if(admin!=null){
                //登陆成功后为当前登录的用户生成token
                String token= JWTUtil.getToken(admin);
                admin.setToken(token);
                result=new Result<>(200,"登陆成功",admin);
                //resp.getWriter().print(new ObjectMapper().writeValueAsString(admin));
            }else{
                result=new Result<>(201,"账号或密码错误",null);
                //resp.getWriter().print("账号或密码错误!");
            }
        } catch (Exception throwables) {
            throwables.printStackTrace();
            result=new Result<>(500,"系统忙!",null);
            //resp.getWriter().print("系统忙!");
        }
        resp.getWriter().print(new ObjectMapper().writeValueAsString(result));
        //向前端做出响应
    }
}

登录界面只需要将数据返回到后端,所以只有dopost方法,没有doget方法

在dopost方法中,需要接受传到后端的账号和密码两个数据,然后调用dao类判断数据库中是否有对应的值,然后返回对应的admin值

3.LoginDao

package com.ffyc.dormserver.dao;

import com.ffyc.dormserver.model.Admin;
import com.mysql.jdbc.Driver;

import java.sql.*;

public class LoginDao {
    public Admin login(String account, String passwords) throws SQLException {
        DriverManager.registerDriver(new Driver());
        String url = "jdbc:mysql://127.0.0.1:3306/dormdb?serverTimezone=Asia/Shanghai";
        String user = "root";
        String password = "root";
        Connection connection = null;
        PreparedStatement ps = null;
        Admin admin = null;
        try {
            //建立与数据库的连接
            connection = DriverManager.getConnection(url, user, password);
            ps = connection.prepareStatement("select id,account,gender,phone from admin where account=? and password=?");
            ps.setString(1, account);
            ps.setString(2, passwords);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                admin = new Admin();
                admin.setId(rs.getInt("id"));
                admin.setAccount(rs.getString("account"));
                admin.setGender(rs.getString("gender"));
                admin.setPhone(rs.getString("phone"));
            }
            return admin;
        } finally {
            if (ps != null) {
                ps.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }
}


与后端交互的代码,只用查找前端传过来的数据在数据库中是否存在即可

连接好数据库后,进行查找,将查找出来的值传给damin

四、过滤器

package com.ffyc.dormserver.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
/*
设置请求和响应编码集
 */
@WebFilter(urlPatterns = "/*")
public class EncodingFilter implements Filter {
    /*
    执行过滤操作的方法
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("编码过滤器");
        //设置请求编码集
        servletRequest.setCharacterEncoding("utf-8");
        //设置响应编码集
        servletResponse.setContentType("text/html;charset=utf-8");
        //让请求离开过滤器,继续向下执行,下一个可能是过滤器,也可能是目标访问的servlet
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

  • 17
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘伊珂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值