小项目(servelt+jsp+mysql+EL+JSTL)完成一个登录功能的Servlet,具有增删改查的操作。实现登录身份验证,防止非法登录,防止多点登录,记住用户名密码功能。

小项目(servelt+jsp+mysql+EL+JSTL)完成一个登录功能的Servlet,具有增删改查的操作。实现登录身份验证,防止非法登录,防止多点登录,记住用户名密码功能。

项目框架

1.创建数据库表

login表

create table emp(
	empid int(8) auto_increment primary key,
	empname varchar(32),
	job varchar(255),
	salary float(9,2),
	tel varchar(11) unique
);
insert into emp
values 
(default,'tom','程序员',10000.5,'13553126224'),
(default,'jack','程序员',9000,'13553156224'),
(default,'张良','销售员',15000,'13553123456'),
(default,'王丽丽','销售员',15000,'18253123456');

在数据库中存储密码时,要进行加密。加密使用MD5算 法进行加密,MD5算法的特点是,一个字符串通过MD5算法加密后,会得到一个唯一对应的字符串;MD5算法加 密后获得的字符串是不可逆的;通过加盐的方式,让加密的密码更安全。

2.创建Users类

package com.hyxy.emp.vo;

public class Users {
    private String loginname;
    private String passwd;
    private String username;

    public String getLoginname() {
        return loginname;
    }

    public void setLoginname(String loginname) {
        this.loginname = loginname;
    }

    public String getPasswd() {
        return passwd;
    }

    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

3.Emp.java

package com.hyxy.emp.vo;

public class Emp {
    //属性名要和表中的列名相同,可忽略大小写
    private int empid;
    private String empname;
    private String job;
    private double salary;
    private String tel;

    public int getEmpid() {
        return empid;
    }

    public void setEmpid(int empid) {
        this.empid = empid;
    }

    public String getEmpname() {
        return empname;
    }

    public void setEmpname(String empname) {
        this.empname = empname;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }
}

4.EmpServlet.java 

package com.hyxy.emp.servlet;

import com.hyxy.emp.vo.Emp;
import com.oracle.jdbc.util.Dao;

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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

@WebServlet("/emp.do")//用.do区分servlet的路径
public class EmpServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");//设置客户端浏览器解码字符集
        //resp.setCharacterEncoding("UTF-8"); //设置传输内容的编码字符集,浏览器使用相同的字符集才能解码
        //System.out.println("调用Dao,获得数据,拼html发给浏览器");

        //获得请求的操作标志值

        //判断session中是否有key是user的对象,如果没有则向登陆界面进行重定向跳转
        HttpSession session=req.getSession();
        if(session.getAttribute("user")==null){
            PrintWriter pw= resp.getWriter();
            pw.println("<script>");
            pw.println("window.parent.location.href='"+req.getContextPath()+"/index'");//执行js跳转
            //pw.println("window.parent.location.href='${pageContext.request.contextPath}/index'");//执行js跳转

            pw.println("</script>");
            return;
            //resp.sendRedirect();
        }
        String op=req.getParameter("op");
        if("query".equals(op)){
            //查询请求的处理
            query(req,resp);
        }else if("add".equals(op)){
            add(req,resp);
        }else if("save".equals(op)){
            save(req,resp);
        }else if("delete".equals(op)){
            delete(req,resp);
        }else if("edit".equals(op)){
            edit(req,resp);
        }else if("update".equals(op)){
            update(req,resp);
        }else if("back".equals(op)){
            back(req,resp);
        }
    }

    /**
     * 将方法封装
     * @param req
     * @param resp
     */
    protected void query(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //查询
        String sql="select * from emp";
        List<Emp> list = Dao.query(sql,Emp.class);

        //使用JSP便于代码维护
        req.setAttribute("list",list);
        req.getRequestDispatcher("/view/emp/query.jsp").forward(req,resp);
    }
    protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        req.getRequestDispatcher("/view/emp/add.jsp").forward(req,resp);

    }
    protected void save(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接收请求的参数,也就是要保存的数据
        String empname= req.getParameter("empname");
        String job= req.getParameter("job");
        String salary= req.getParameter("salary");
        String tel= req.getParameter("tel");//注意电话号码是唯一约束,不能相同,否则报错

        //向数据库插入数据
        String sql ="insert into emp values(default,?,?,?,?)";
        Dao.executeSql(sql,empname,job,salary,tel);
        //向浏览器返回插入后的查询数据,调用query,显示查询页面的数据
        query(req, resp);
    }
    protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String empid =req.getParameter("id");
        String sql="delete from emp where empid=?";
        Dao.executeSql(sql,empid);
        query(req, resp);
    }
    protected void edit(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String empid = req.getParameter("id");
        String sql = "select * from emp where empid = ?";
        Emp e = Dao.queryOne(sql,Emp.class,empid);
        req.setAttribute("emp",e);
        req.getRequestDispatcher("/view/emp/edit.jsp").forward(req,resp);
    }
    protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String empname= req.getParameter("empname");
        String job= req.getParameter("job");
        String salary= req.getParameter("salary");
        String tel= req.getParameter("tel");
        String empid = req.getParameter("empid");//用表单隐藏

        String sql ="update emp set empname=?,job=?,salary=?,tel=? where empid=?";
        Dao.executeSql(sql,empname,job,salary,tel,empid);
        //向浏览器返回插入后的查询数据,调用query,显示查询页面的数据
        query(req, resp);
    }
    protected void back(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

框架页面设计

index.html

<!doctype html>
<html lang="en">
 <head>
 </head>
<frameset rows="100,*">
	<frame src="/emp/view/frame/top.html">
	<frameset cols="120,*">
		<frameset rows="50%,50%">
			<frame src="/emp/view/frame/catalog.html" name="left"> 
 </frameset>
 <frame src="/emp/view/frame/main.html" name="mainFrame">
 </frameset>
 </frameset>

</html>

 catalog.html  框架左侧目录

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>目录</title>
</head>
<body>
<h2 align='center'>目录</h2>
    <table align='center'>
        <tr align='center'>
            <td align='center'>
                <a href="/emp/emp.do?op=query"  target="mainFrame">员工管理</a><br>
            </td><!--将内容1⽂件的内容指定显⽰给名为rightdown的框架-->
        </tr>
        <tr align='center'>
            <td align='center'>
                <a href="/emp/dept.do?op=query"  target="mainFrame">部门管理</a><br>
            </td>
        </tr>

    </table>
</body><!--上边的target为指定-->

</html>

一、实现登录身份验证功能

1.设计登录界面 IndexServlet.java处理访问登录页面的请求

package com.hyxy.emp.servlet;

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

@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //输入http://localhost:8080/emp/index访问登录页面
        req.setCharacterEncoding("GBK");
        resp.setCharacterEncoding("GBK");
        Cookie[] cookies=req.getCookies();//获得一个cookie数组
        String loginname="";
        String passwd="";
        String rememberMe="";
        for(Cookie cookie:cookies){

            if("rememberMe".equals(cookie.getName())){
                rememberMe=cookie.getValue();
            }
        }
        if("1".equals(rememberMe)){
            for(Cookie cookie:cookies){
                if("loginname".equals(cookie.getName())){
                    loginname=cookie.getValue();
                }
                if("passwd".equals(cookie.getName())){
                    passwd=cookie.getValue();
                }
            }
        }
        PrintWriter pw= resp.getWriter();
        pw.println("<!doctype html>");
        pw.println("<html>");
        pw.println(" <head>");
        pw.println(" 	<script>");
        if(req.getAttribute("msg")!=null){
            pw.println("alert('"+req.getAttribute("msg")+"');");
        }
        pw.println("		function login(){");
        pw.println("			var loginname = document.getElementById('loginname');");
        pw.println("			var passwd = document.getElementById('passwd');");
        pw.println("			if(loginname.value==''){");
        pw.println("				alert('请输入用户名');");
        pw.println("				return;");
        pw.println("			}");
        pw.println("			if(passwd.value==''){");
        pw.println("				alert('请输入密码');");
        pw.println("				return;");
        pw.println("			}");
        pw.println("			loginForm.submit();");
        pw.println("		}");
        pw.println("	</script>");
        pw.println(" </head>");
        pw.println(" <body>");
        pw.println("  <form name='loginForm' method='post' action='"+req.getContextPath()+"/login'>");
        pw.println("  <table width='60%' align='center'>");
        pw.println("	<tr>");
        pw.println("		<td align='right'>用户名:</td>");
        pw.println("		<td align='left'><input type='text' id='loginname' name='loginname' value='"+loginname+"'></td>");
        pw.println("	</tr>");
        pw.println("	<tr>");
        pw.println("		<td align='right'>密  码:</td>");
        pw.println("		<td align='left'><input type='password' id='passwd' name='passwd' value='"+passwd+"'></td>");
        pw.println("	</tr>");
        pw.println("	<tr>");
        pw.println("		<td align='right'><input type='button' value='登录' onclick='login();'></td>");
        pw.println("		<td align='left'><input type='checkbox' "+("1".equals(rememberMe)?"checked":"")+" name='rememberMe' value='1'>记住用户名密码</td>");
        pw.println("	</tr>");
        pw.println("  </table>");
        pw.println("  </form>");
        pw.println(" </body>");
        pw.println("</html>");
    }
}

2.LoginServlet.java处理登录身份认证请求

package com.hyxy.emp.servlet;

import com.hyxy.emp.vo.Users;
import com.oracle.jdbc.util.Dao;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.List;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("GBK");
        resp.setCharacterEncoding("GBK");
        //功能一:登录身份认证
        String loginname=req.getParameter("loginname");
        String passwd=req.getParameter("passwd");
        String rememberMe=req.getParameter("rememberMe");
        //如果选中记住用户名密码勾选框,rememberMe的值是1

        //将用户输入的登录名和密码在数据库中进行查找
        String sql="select * from users where loginname=? and passwd=md5(?)";//第二个?是用户名加密码
        List<Users> list = Dao.query(sql,Users.class,loginname,loginname+passwd);
        if(list==null||list.size()==0){
            //未找到,登录失败
            //显示登陆页面,调用IndexServlet对象的service方法(无法实现),使用跳转
            // 给出提示
            //向IndexServlet进行跳转,使用请求转发跳转
            req.setAttribute("msg","登录失败!");//存到Map中,msg是key,后面是value
            req.getRequestDispatcher("/index").forward(req,resp);
        }else{
            //登录成功,重定向跳转
            //显示主页面,LoginServlet
           // resp.sendRedirect(req.getContextPath()+"/view/index.html");
            //功能二:防止非法登录
            //例如直接在浏览器输入链接http://localhost:8080/emp/emp.do?op=edit&id=2就能修改表中信息,不需要经过登陆界面
            //实现方法,在每个页面都添加session进行判断,否则返回登陆界面
            HttpSession session=req.getSession();
            session.setAttribute("user",list.get(0));
            ServletContext servletContext=this.getServletContext();
            if(servletContext.getAttribute(loginname)!=null){
                HttpSession otherSession=(HttpSession)servletContext.getAttribute(loginname);
                if(!session.getId().equals(otherSession.getId())){//防止当前同一个用户登录多次时,自己将自己踢出
                    otherSession.invalidate();
                }
            }
            servletContext.setAttribute(loginname,session);
            if(rememberMe!=null){
                Cookie cookie=new Cookie("loginname",loginname);
                cookie.setMaxAge(60*60*24*30);
                resp.addCookie(cookie);
                cookie=new Cookie("passwd",passwd);
                cookie.setMaxAge(60*60*24*30);
                resp.addCookie(cookie);
            }
            Cookie cookie=new Cookie("rememberMe",rememberMe);
            cookie.setMaxAge(60*60*24*30);
            resp.addCookie(cookie);
            //显示主页面
            resp.sendRedirect(req.getContextPath()+"/view/index.html");

            /*
              功能三:防止多点登录
              使别人的session失效,即可实现让对方下线
              当登陆成功时,将登陆的用户名作为key,当前用户的session作为value存储到ServletContext容器中
              登录成功时,判断Servlet Context中 是否有登陆用户的key-value,
              如果有,则将Servlet Context中存储的session失效,将登陆用户的session存到Servlet Context中
              无论Servlet Context中是否有别人登录的session,都要将新登陆的用户的session存到其中,以便实现相互踢出功能
             */
            /*
                功能四:记住用户名密码
                勾选框选中,写Cookie
             */
        }
    }
}

3.点击登录按钮,用输入的用户名和密码与数据库的用户名密码 进行校验

IndexServlet:

pw.println(" <form name='loginForm' method='post' action='"+request.getContextPath()+"/login'>");

 LoginServlet.java

List<Users> list = Dao.query(sql, Users.class,loginname,loginname+passwd);
if(list==null||list.size()==0){
    //登录失败
    //显示登录页面,给出提示
    //调用 IndexServlet对象的service方法 无法实现
    // 向IndexServlet进行跳转,需要传数据(登录失败的消息)
    request.setAttribute("msg","登录失败!");
    //请求转发跳转自动加上下文路径,因为调用的是request的方法
    request.getRequestDispatcher("/index").forward(request,response);
}else{
    //登录成功
    //显示主页面
    response.sendRedirect(request.getContextPath()+"/view/index.html");
}

IndexServlet中获得request的Attribute值判断是否提示 登录失败

pw.println(" <script>");
if(request.getAttribute("msg")!=null){
    pw.println("alert('"+request.getAttribute("msg")+"');");
}

二、实现防止非法登录功能

访问系统功能时,只能先从登录页面进行,登录成功后,再能使用其他的功能。

LoginServlet中

//登录成功,向session中存储Users对象
HttpSession session = request.getSession();
session.setAttribute("user",list.get(0));

EmpServlet中

if(session.getAttribute("user")==null){
    PrintWriter pw = response.getWriter();
    pw.println("<script>");
    pw.println("window.parent.location.href='"+request.getContextPath()+"/index'");
    pw.println("</script>");
    return;
    //response.sendRedirect(request.getContextPath()+"/index");
}

三、实现防止多点登录功能

LoginServlet中:

else{
    //登录成功,向session中存储Users对象
    HttpSession session = request.getSession();
    session.setAttribute("user",list.get(0));
    //判断ServletContext中是否有登录的用户名key的value
    ServletContext servletContext = this.getServletContext();
    if(servletContext.getAttribute(loginname)!=null){
        HttpSession otherSession = (HttpSession)servletContext.getAttribute(loginname);
        //if(session!=otherSession)
        if(!session.getId().equals(otherSession.getId()))
            otherSession.invalidate();
        }
        //存入当前的Session对象
        servletContext.setAttribute(loginname,session);
        //显示主页面
        response.sendRedirect(request.getContextPath()+"/view/index.html");
}

四、记住用户名密码功能

1. 如果勾选了 rememberMe的勾选框并登录成功时,向客户端发送用户名、密码、勾选框是否选中的Cookie;

pw.println("<td align='left'><input type='checkbox' "+("1".equals(rememberMe)?"checked":"")+" name='rememberMe' value='1'>记住用户名密码</td>");

LoginServlet.java

else{
    //登录成功,向session中存储Users对象
    HttpSession session = request.getSession();
    session.setAttribute("user",list.get(0));
    //判断ServletContext中是否有登录的用户名key的value
    ServletContext servletContext = this.getServletContext();
    if(servletContext.getAttribute(loginname)!=null){
        HttpSession otherSession =(HttpSession)servletContext.getAttribute(loginname);
        //if(session!=otherSession)
        if(!session.getId().equals(otherSession.getId()))
            otherSession.invalidate();
        }
        //存入当前的Session对象
        servletContext.setAttribute(loginname,session);
        if(rememberMe!=null){
            //向客户端响应Cookie
            Cookie cookie = new Cookie("loginname",loginname);
            cookie.setMaxAge(60*60*24*30);
            response.addCookie(cookie);
            cookie = new Cookie("passwd",passwd);
            cookie.setMaxAge(60*60*24*30);
            response.addCookie(cookie);
        }
        Cookie cookie = new Cookie("rememberMe",rememberMe);
        cookie.setMaxAge(60*60*24*30);
        response.addCookie(cookie);
        //显示主页面
        response.sendRedirect(request.getContextPath()+"/view/index.html");
}

2. 进入到登录页面先访问IndexServlet,在IndexServlet中可以获得三个Cookie,如果勾选框是选中状态,就将 用户名、密码、勾选状态写到html中,IndexServlet发回浏览器

运行效果:

浏览器访问  http://localhost:8080/emp/index  为登录界面

 2.勾选记住用户名密码,点击登录按钮,进入到主页 

 3.点击左侧目录中的“员工管理”

4. 点击新增按钮,填写信息,保存

5.点击“修改”,修改信息,保存 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

aigo-2021

您的鼓励是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值