JavaWeb开发实战(二)

本文涉及的产品
函数计算FC,每月15万CU 3个月
简介: JavaWeb开发实战(二)

6.5 创建登录业务的Filter

创建UserLoginFilter实现未登录拦截。

package com.zj.web.filter;
import com.sun.org.apache.bcel.internal.Const;
import com.zj.commons.Constants;
import com.zj.pojo.User;
import jdk.nashorn.internal.objects.NativeArray;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import java.io.IOException;
/*判断当前客户端浏览器是否登录的Filter*/
@WebFilter("/*")
public class UserLoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String uri = request.getRequestURI();
        //判断当前路径是否是login.jsp或者login.do,放行这两个资源,还需要放行验证码图片。
        if (uri.indexOf("login.jsp") != -1 || uri.indexOf("login.do") != -1 || uri.indexOf("ValidateCodeServlet.do")!= -1) {
            filterChain.doFilter(request,response);
        }else {
            HttpSession session = request.getSession();
            User user = (User) session.getAttribute(Constants.USER_SESSION_KEY);
            if (user != null) {
                filterChain.doFilter(request,response);
            }else {
                request.setAttribute(Constants.REQUEST_MSG,"不登陆不好使!(⊙o⊙)?");
                request.getRequestDispatcher("login.jsp").forward(request, response);
            }
        }
    }
    @Override
    public void destroy() {
    }
}

6.6 实现用户只能在一处登录

当前的一个账号可以在多个浏览器登录,我们要实现的是账号在另一个浏览器登陆的时候会挤掉当前浏览器的账户。

实现的原理是将当前用户的session放在context中缓存,用户在当前浏览器登录的时候首先查看context中是否存在当前用户的session信息,存在的话表示当前用户在其他浏览器已经登录过了,则删除该之前浏览器和服务端之间的会话session,重新建立当前浏览器与服务端的session连接,并将该session保存到context中。

6.7 解决HttpSession超时销毁时的异常问题

6.6实现了用户只能在一处登录,但是session有自动销毁的时间是半个小时。此时session被tomcat销毁但是context还保存着已经被销毁的session的信息,再使用另一个浏览器登陆时仍然能拿到这个被销毁的session,再一次销毁这个session的时候就会报错,因为之前已经被tomcat销毁了嘛。此时可以通过listener监听器来监听session的声明周期。

package com.zj.web.listener;
import com.zj.commons.Constants;
import com.zj.pojo.User;
import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class HttpSessionLifeListener implements HttpSessionListener {
    /*HttpSession被销毁之前触发该方法*/
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        //获取servletContext对象,将保存在context中的即将被销毁的session删除。
        HttpSession session = se.getSession();
        ServletContext servletContext = session.getServletContext();
        User user = (User) servletContext.getAttribute(Constants.USER_SESSION_KEY);
        servletContext.removeAttribute(user.getUserid()+"");
    }
}

6.8 在登录中添加验证码功能

首先将生成验证码的servlet工具类添加到项目中

package com.zj.commons;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet("/ValidateCodeServlet.do")
public class ValidateCodeServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 在内存中创建图象
        int width = 70, height = 45;
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        // 获取图形上下文
        Graphics g = image.getGraphics();
        // 生成随机类
        Random random = new Random();
        // 设定背景色
        g.setColor(getRandColor(200, 250));
        g.fillRect(0, 0, width, height);
        // 设定字体
        g.setFont(new Font("Times New Roman", Font.PLAIN, 20));
        // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
        g.setColor(getRandColor(160, 200));
        for (int i = 0; i < 155; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            g.drawLine(x, y, x + xl, y + yl);
        }
        // 取随机产生的认证码(4位数字)
        String sRand = "";
        for (int i = 0; i < 4; i++) {
            String rand = String.valueOf(random.nextInt(10));
            sRand += rand;
            // 将认证码显示到图象中
            g.setColor(new Color(20 + random.nextInt(110), 20 + random
                    .nextInt(110), 20 + random.nextInt(110)));
            // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
            g.drawString(rand, 13 * i + 6, 16);
        }
        // 图象生效
        g.dispose();
        try {
            ImageIO.write(image, "JPEG", response.getOutputStream());
        } catch (Exception e) {
            System.out.println("验证码图片产生出现错误:" + e.toString());
        }
        //保存验证码到Session
        request.getSession().setAttribute("randStr", sRand);
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
    /*
     * 给定范围获得随机颜色
     */
    private Color getRandColor(int fc, int bc) {
        Random random = new Random();
        if (fc > 255)
            fc = 255;
        if (bc > 255)
            bc = 255;
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }
}

修改登录页面在login.jsp中添加验证码标签img,定义函数change每次点击验证码都会更换。

<img id="code" src="ValidateCodeServlet.do" onclick="change"/>
/*点击验证码图片生成验证码*/
        function change() {
           $("#code").attr("src","ValidateCodeServlet.do?"+Math.random())
        }

在 UserLoginFilter过滤器中放行验证码图片资源。

if (uri.indexOf("login.jsp") != -1 || uri.indexOf("login.do") != -1 || uri.indexOf("ValidateCodeServlet.do")!= -1) {
            filterChain.doFilter(request,response);
}

在UserLoginServlet中实现验证码的校验。

 

6.9 用户退出功能

在left.jsp页面添加退出功能的标签。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
</html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    <link href="css/style.css" rel="stylesheet" type="text/css" />
    <script language="JavaScript" src="js/jquery.js"></script>
    <script type="text/javascript">
        $(function(){
            //导航切换
            $(".menuson .header").click(function(){
                var $parent = $(this).parent();
                $(".menuson>li.active").not($parent).removeClass("active open").find('.sub-menus').hide();
                $parent.addClass("active");
                if(!!$(this).next('.sub-menus').size()){
                    if($parent.hasClass("open")){
                        $parent.removeClass("open").find('.sub-menus').hide();
                    }else{
                        $parent.addClass("open").find('.sub-menus').show();
                    }
                }
            });
            // 三级菜单点击
            $('.sub-menus li').click(function(e) {
                $(".sub-menus li.active").removeClass("active")
                $(this).addClass("active");
            });
            $('.title').click(function(){
                var $ul = $(this).next('ul');
                $('dd').find('.menuson').slideUp();
                if($ul.is(':visible')){
                    $(this).next('.menuson').slideUp();
                }else{
                    $(this).next('.menuson').slideDown();
                }
            });
        })
    </script>
</head>
<body style="background:#f0f9fd;">
<div class="lefttop"><span></span>导航菜单</div>
<dl class="leftmenu">
    <dd>
        <div class="title"><span><img src="images/leftico03.png" /></span>用户管理</div>
        <ul class="menuson">
            <li><cite></cite><a href="userAdd.jsp" target="rightFrame">添加用户</a><i></i></li>
            <li><cite></cite><a href="findUser.jsp" target="rightFrame">查询用户</a><i></i></li>
            <li><cite></cite><a href="logout.do" target="rightFrame">退出登录</a><i></i></li>
        </ul>
    </dd>
</dl>
</body>
</html>

创建用户退出登录的servlet

package com.zj.web.servlet;
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;
/*用户退出*/
@WebServlet("/logout.do")
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        //因为配置了监听器,在session销毁的时候会调用监听器的方法,删除context中的session
        session.invalidate();
        //重定向到登录页面
        resp.sendRedirect("login.jsp");
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

七、添加用户业务

7.1 创建添加用户持久层

创建接口和实现类

package com.zj.dao;
import com.zj.pojo.User;
public interface UserManageDao {
    //用户添加
    void insertUser(User user);
}
package com.zj.dao.impl;
import com.zj.commons.jdbcUtils;
import com.zj.dao.UserManageDao;
import com.zj.pojo.User;
import java.sql.Connection;
import java.sql.PreparedStatement;
public class UserManageDaoImpl implements UserManageDao {
    @Override
    public void insertUser(User user) {
        Connection con = null;
        try {
            con = jdbcUtils.getConnection();
            //关闭自动提交事务,加深对事务印象
            con.setAutoCommit(false);
            PreparedStatement ps = con.prepareStatement("INSERT INTO users values (default ,?,?,?,?,?)");
            ps.setString(1, user.getUsername());
            ps.setString(2, user.getUserpwd());
            ps.setString(3, user.getUsersex());
            ps.setString(4, user.getPhonenumber());
            ps.setString(5, user.getQqnumber());
            ps.executeUpdate();
            con.commit();
        }catch (Exception e) {
            e.printStackTrace();
            //出现异常回滚
            jdbcUtils.rollbackConnection(con);
        }finally {
           jdbcUtils.closeConnection(con);
        }
    }
}

7.2 创建添加用户业务层

创建添加用户的接口和实现类

package com.zj.service;
import com.zj.pojo.User;
public interface UserManageService {
    void addUser(User user);
}
package com.zj.service.Impl;
import com.zj.dao.UserManageDao;
import com.zj.dao.impl.UserManageDaoImpl;
import com.zj.pojo.User;
import com.zj.service.UserManageService;
public class UserManageServiceImpl implements UserManageService {
    /*添加用户*/
    @Override
    public void addUser(User user) {
        UserManageDao userManageDao = new UserManageDaoImpl();
        userManageDao.insertUser(user);
    }
}

7.3 创建添加用户servlet

package com.zj.web.servlet;
import com.zj.pojo.User;
import com.zj.service.Impl.UserManageServiceImpl;
import com.zj.service.UserManageService;
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;
@WebServlet("/userManage.do")
public class UserManageServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String flag = req.getParameter("flag");
        if ("add".equals(flag)) {
                addUser(req, resp);
        }
    }
    //添加用户
    private void addUser(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        User user = this.createUser(request, response);
        try {
         UserManageService userManagerService = new UserManageServiceImpl();
         userManagerService.addUser(user);
         response.sendRedirect("ok.jsp"); //重定向防止数据重复提交
        }catch (Exception e) {
            e.printStackTrace();
            response.sendRedirect("error.jsp");
        }
    }
    //获取用户提交的数据
    private User createUser(HttpServletRequest request,HttpServletResponse response){
        String username = request.getParameter("username");
        String userpwd = request.getParameter("userpwd");
        String usersex = request.getParameter("usersex");
        String phonenumber = request.getParameter("phonenumber");
        String qqnumber = request.getParameter("qqnumber");
        User user = new User(0,username, userpwd, usersex, phonenumber, qqnumber);
        return user;
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

7.4 创建添加用户页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    <link href="../css/style.css" rel="stylesheet" type="text/css" />
    <link href="../css/style.css" rel="stylesheet" type="text/css" />
    <link href="../css/select.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="../js/jquery.js"></script>
    <script type="text/javascript" src="../js/jquery.idTabs.min.js"></script>
    <script type="text/javascript" src="../js/select-ui.min.js"></script>
    <script type="text/javascript" src="editor/kindeditor.js"></script>
    <script type="text/javascript" src="My97DatePicker/WdatePicker.js"></script>
    <script type="text/javascript">
        $(document).ready(function(e) {
            $(".select1").uedSelect({
                width : 345
            });
        });
        function save(){
            window.location='ok.html';
        }
    </script>
    <script type="text/javascript">
        KE.show({id:"ecp",width:"800px",height:"300px"});
    </script>
</head>
<body>
<div class="place">
    <span>位置:</span>
    <ul class="placeul">
        <li><a href="#">用户管理</a></li>
        <li><a href="#">添加用户</a></li>
    </ul>
</div>
<div class="formbody">
    <div class="formtitle"><span>添加用户</span></div>
    <form action="../userManage.do" method="post">
        <%--当前是添加用户信息--%>
   <input type="hidden" name="flag" value="add"/>
    <ul class="forminfo">
        <li>
            <label>用户名</label>
            <input name="username" type="text" class="dfinput" /></li>
        <li>
        <li>
            <label>用户密码</label>
            <input name="userpwd" type="text" class="dfinput" /><i></i></li>
        <li>
            <label>性别</label>
            <input name="usersex" type="radio" value="1" checked="checked" />男&nbsp;&nbsp;&nbsp;&nbsp;
            <input name="usersex" type="radio" value="0" />女
        </li>
        <li>
            <label>联系方式</label>
            <input name="phonenumber" type="text" class="dfinput" />
        </li>
        <li>
            <label>QQ号</label>
            <input name="qqnumber" type="text" class="dfinput" />
        </li>
        <li>
            <label>&nbsp;</label>
            <input  type="submit"  class="btn" value="确认保存" />
        </li>
    </ul>
    </form>
</div>
</body>
</html>

创建添加成功的页面ok.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <link href="css/style.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript">
        function submitForm(){
            window.close();
        }
    </script>
</head>
<body>
<div class="place">
    <span>位置:</span>
    <ul class="placeul">
        <li><a href="#">操作提示</a></li>
    </ul>
</div>
操作成功!
</body>
</html>


相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
1天前
|
Java 应用服务中间件 API
【潜意识Java】javaee中的SpringBoot在Java 开发中的应用与详细分析
本文介绍了 Spring Boot 的核心概念和使用场景,并通过一个实战项目演示了如何构建一个简单的 RESTful API。
19 5
|
1天前
|
前端开发 Java 数据库连接
【潜意识Java】深度解读JavaWeb开发在Java学习中的重要性
深度解读JavaWeb开发在Java学习中的重要性
18 4
|
1天前
|
SQL Java API
|
1天前
|
前端开发 Java 数据库连接
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
10 2
|
13天前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
|
Java 开发工具 git
Java开发初级6.24.3
5.在Git使用过程中,进行Git配置的操作命令是哪个() A. config B. config -g C. config -a D. git config 相关知识点: 在git中,经常使用git config 命令用来配置git的配置文件,git配置级别主要有:仓库级别 local 【优先级最高】、用户级别 global【优先级次之】、系统级别 system【优先级最低】 正确答案:D 10.RDBMS是什么? A. Rela Database Management Systems B. Relational Database Management Systems C. Relation
145 0
|
SQL 前端开发 JavaScript
Java开发初级6.24.2
3.Java网站src/main/java目录保存的是什么资源? A. Java源代码文件 B. 测试代码 C. JavaScript、CSS等文件 D. 图片资源 正确答案:A 4.什么是索引Index? A. SQL数据库里的表管理工具 B. SQL数据库里的查询工具 C. SQL数据库里的目录工具 D. SQL数据库用来加速数据查询的特殊的数据结构 正确答案:D
152 0
|
Java
Java开发初级6.24.1
1.下面关于泛型的描述中错误的一项是? A. “? extends 类”表示设置泛型上限 B. “? super 类”表示设置泛型下限 C. 利用“?”通配符可以接收全部的泛型类型实例,但却不可修改泛型属性内容 D. 如果类在定义时使用了泛型,则在实例化类对象时需要设置相应的泛型类型,否则程序将无法编译通过 相关知识点: https://edu.aliyun.com/course/35 正确答案:D 2.下列选项中属于SVN中控制鉴权用户访问版本库的权限默认权限的是() A. write B. read C. none D. null 相关知识点: auth-access:取值范围为"writ
247 0
|
Java 开发工具 git
Java开发初级6.23.3
5.在Git使用过程中,进行Git配置的操作命令是哪个() A. config B. config -g C. config -a D. git config 相关知识点: 在git中,经常使用git config 命令用来配置git的配置文件,git配置级别主要有:仓库级别 local 【优先级最高】、用户级别 global【优先级次之】、系统级别 system【优先级最低】 正确答案:D 10.RDBMS是什么? A. Rela Database Management Systems B. Relational Database Management Systems C. Relation
135 0
|
SQL 前端开发 JavaScript
Java开发初级6.23.2
3.Java网站src/main/java目录保存的是什么资源? A. Java源代码文件 B. 测试代码 C. JavaScript、CSS等文件 D. 图片资源 正确答案:A 4.什么是索引Index? A. SQL数据库里的表管理工具 B. SQL数据库里的查询工具 C. SQL数据库里的目录工具 D. SQL数据库用来加速数据查询的特殊的数据结构 正确答案:D
232 0