javaweb-实验8--期末复盘

实验八 JSP内置对象(二)

需要相关资料的,详见文章末尾,免费自提

一、实验目的:

1、掌握session的基本用法。
2、理解各类域对象的区别。

二、 实验内容:

实现基于验证码的用户登录。
在这里插入图片描述

【实验步骤】(补全代码一 ~ 代码七

(1)新建一个名为”web8”的项目(Web应用程序)。在项目中,新建JSP,命名为“login”。

<%@ page contentType="text/html;charset=UTF-8" language="java"  %>
<html>
    <head>
        <title>login</title>
        <script>
            function _change() {
    
    
                //获取<img>元素
                var imgEle = document.getElementById("vCode");
                imgEle.src = "<%=request.getContextPath()%>/checkCodeServlet?"+new Date().getTime();
                //因为某些浏览器会对src缓存,所以需要添加不同的参数,保证每次的URL参数都不同            
            }
        </script>
        <style>
            div{
    
    
                color: red;
            }
        </style>
    </head>
    <body>
        <form action="<%= request.getContextPath()%>/login" method="post">
            <table>
                <tr>
                    <td>用户名</td><td><input type="text" name="username"></td></tr>
                <tr>
                    <td>密码</td><td><input type="password" name="userpass"></td>
                    <td><div><%=request.getAttribute("login_error") == null ? "" : request.getAttribute("login_error")%></div></td></tr>
                <tr>
                    <td>验证码</td><td><input type="text" name="checkCode"></td> 
                    <td><div><%= request.getAttribute("code_error") == null ? "" : request.getAttribute("code_error")%></div></td></tr>
                <tr>
                    <td colspan="2">
                        <img id="vCode" src="<%=request.getContextPath()%>/checkCodeServlet">
                        <a href="javascript:_change()">看不清,换一张</a>
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="submit" value="登录">
                        <input type="reset" value="重置">
                    </td>
                </tr>
            </table>
        </form>
    </body>
</html>

(2)新建java包“it.servlet”。在该包中新建java类,命名为“CheckCodeServlet”。
CheckCodeServlet.java的主要功能:生成验证码,将验证码显示在浏览器中,并将验证码存储于session对象。

package it.servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
    
    

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        int width = 100;
        int height = 40;
        //创建验证码图片对象
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //美化图片
        //1.填充背景色
        Graphics g = image.getGraphics();
        g.setColor(Color.blue);
        g.fillRect(0, 0, width, height);
        //2.画边框
        g.setColor(Color.CYAN);
        g.drawRect(0, 0, width - 1, height - 1);
        //3.写验证码
        //验证码的字符
        String str = "ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789";
        //生成随机字符串
        Random ran = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= 4; i++) {
    
    
            int index = ran.nextInt(str.length());
            char ch = str.charAt(index);//随机字符
            sb.append(ch);
            g.setFont(new Font("TimesRoman", Font.PLAIN, 16));
            g.drawString(ch + "", width / 5 * i, height / 2);
        }
        String checkCode_session = sb.toString();

        //【代码一】将验证码存入session,属性名为checkCode_session
 

        //4.画干扰线
        g.setColor(Color.green);
        //随机生成坐标点
        for (int i = 1; i <= 10; i++) {
    
    
            int x1 = ran.nextInt(width);
            int x2 = ran.nextInt(width);

            int y1 = ran.nextInt(height);
            int y2 = ran.nextInt(height);
            g.drawLine(x1, y1, x2, y2);
        }
        //将图片输出到页面展示
        ImageIO.write(image, "jpg", /*【代码二】*/);

    }
}

(3)在“it.servlet”包中新建名为“LoginServlet”的Java类。LoginServlet.java用于检查用户名、密码以及验证码是否正确:登录成功,跳转到welcome.jsp;登录失败,跳转回login.jsp,并显示相应的错误提示。

package it.servlet;

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

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    
    

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        //【代码三】设置请求体的编码
       

        //获取参数
        String username = req.getParameter("username");
        String password = req.getParameter("userpass");
        String checkCode = req.getParameter("checkCode");
        //【代码四】获取生成的验证码

             
        //先判断验证码是否正确,忽略大小写比较
        if (checkCode_session != null && checkCode_session.equalsIgnoreCase(checkCode)) {
    
    
            if ("张三".equals(username) && "123".equals(password)) {
    
    
                //【代码五】登录成功,存储用户名到session,并重定向到welcome.jsp
            
            } else {
    
    
                //【代码六】登录失败,存储提示信息“用户名或密码错误”到request,
				// 并转发到login.jsp
             
            }
        } else {
    
    
            //验证码不一致,存储提示信息到request
            req.setAttribute("code_error", "验证码错误");
            //转发到登录页面
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
        }
    }

}

(4)新建JSP文件,命名为“welcome“。
welcome.jsp检查用户是否登录成功;如果没有登录,则跳转回login.jsp;否则显示欢迎信息“***,欢迎您”,效果如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
   <head>
       <title>Title</title>
       <style>
           span{
    
    
               color:red;
               font-weight: bold
           }
       </style>
   </head>
   <body>
      
   <%--【代码七】--%>

   </body>
</html>

具体实现

package it.servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
    
    

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        int width = 100;
        int height = 40;
        //创建验证码图片对象
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //美化图片
        //1.填充背景色
        Graphics g = image.getGraphics();
        g.setColor(Color.blue);
        g.fillRect(0, 0, width, height);
        //2.画边框
        g.setColor(Color.CYAN);
        g.drawRect(0, 0, width - 1, height - 1);
        //3.写验证码
        //验证码的字符
        String str = "ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789";
        //生成随机字符串
        Random ran = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= 4; i++) {
    
    
            int index = ran.nextInt(str.length());
            char ch = str.charAt(index);//随机字符
            sb.append(ch);
            g.setFont(new Font("TimesRoman", Font.PLAIN, 16));
            g.drawString(ch + "", width / 5 * i, height / 2);
        }
        String checkCode_session = sb.toString();

        //【代码一】将验证码存入session,属性名为checkCode_session
        HttpSession session = req.getSession();
        session.setAttribute("checkCode_session",checkCode_session);

        //4.画干扰线
        g.setColor(Color.green);
        //随机生成坐标点
        for (int i = 1; i <= 10; i++) {
    
    
            int x1 = ran.nextInt(width);
            int x2 = ran.nextInt(width);

            int y1 = ran.nextInt(height);
            int y2 = ran.nextInt(height);
            g.drawLine(x1, y1, x2, y2);
        }

		ImageIO.setUseCache(false); //禁用图像缓存的设置 由于个人原因验证码无法显示
        //将图片输出到页面展示
        ImageIO.write(image, "jpg", resp.getOutputStream()/*【代码二】*/);

    }
}
package it.servlet;

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

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    
    

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        //【代码三】设置请求体的编码
        req.setCharacterEncoding("UTF-8");

        //获取参数
        String username = req.getParameter("username");
        String password = req.getParameter("userpass");
        String checkCode = req.getParameter("checkCode");
        //【代码四】获取生成的验证码
HttpSession session = req.getSession();
        String checkCode_session = (String) session.getAttribute("checkCode_session");//返回的是object
             
        //先判断验证码是否正确,忽略大小写比较
        if (checkCode_session != null && checkCode_session.equalsIgnoreCase(checkCode)) {
    
    
            if ("张三".equals(username) && "123".equals(password)) {
    
    
                //【代码五】登录成功,存储用户名到session,并重定向到welcome.jsp
               HttpSession userSession= req.getSession();
               userSession.setAttribute("username",username);
               resp.sendRedirect(req.getContextPath() + "/welcome.jsp");
            } else {
    
    
                //【代码六】登录失败,存储提示信息“用户名或密码错误”到request,
// 并转发到login.jsp
                req.setAttribute("error_message","用户名或密码错误");
                req.getRequestDispatcher("/login.jsp").forward(req,resp);
            }
        } else {
    
    
            //验证码不一致,存储提示信息到request
            req.setAttribute("code_error", "验证码错误");
            //转发到登录页面
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
        }
    }

}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
        <style>
            span{
    
    
                color:red;
                font-weight: bold
            }
        </style>
    </head>
    <body>
       
	<%--【代码七】--%>
 <%
    // 从 session 中获取用户名
    String username = (String) session.getAttribute("username");
    // 检查用户是否登录
    if (username == null) {
    
    
        // 用户未登录,重定向到登录页面
        response.sendRedirect(request.getContextPath() + "/login.jsp");
    } else {
    
    
%>
<span><%= username %></span>,欢迎您!
<%
    }
%>
    </body>
</html>

报错解决

1、若出现login.jsp页面的验证码不显示的问题

HTTP状态 500 - 内部服务器错误
类型 异常报告

消息 Can't create output stream!

描述 服务器遇到一个意外的情况,阻止它完成请求。

例外情况

javax.imageio.IIOException: Can't create output stream!
  javax.imageio.ImageIO.write(ImageIO.java:1574)
  com.neuedu.his.controller.CheckCodeServlet.doPost(CheckCodeServlet.java:85)
  com.neuedu.his.controller.CheckCodeServlet.doGet(CheckCodeServlet.java:89)
  javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
  javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
  org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
  com.neuedu.his.filter.LoginFilter.doFilter(LoginFilter.java:57)
  com.neuedu.his.filter.CharsetFilter.doFilter(CharsetFilter.java:37)
  com.neuedu.his.filter.Filter1.doFilter(Filter1.java:29)
根本原因。

javax.imageio.IIOException: Can't create cache file!
  javax.imageio.ImageIO.createImageOutputStream(ImageIO.java:423)
  javax.imageio.ImageIO.write(ImageIO.java:1572)
  com.neuedu.his.controller.CheckCodeServlet.doPost(CheckCodeServlet.java:85)
  com.neuedu.his.controller.CheckCodeServlet.doGet(CheckCodeServlet.java:89)
  javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
  javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
  org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
  com.neuedu.his.filter.LoginFilter.doFilter(LoginFilter.java:57)
  com.neuedu.his.filter.CharsetFilter.doFilter(CharsetFilter.java:37)
  com.neuedu.his.filter.Filter1.doFilter(Filter1.java:29)
根本原因。

java.nio.file.AccessDeniedException: D:\Program Files\apache\apache-tomcat-8.5.60\temp\imageio8447768555205008617.tmp
  sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)
  sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
  sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
  sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230)
  java.nio.file.Files.newByteChannel(Files.java:361)
  java.nio.file.Files.createFile(Files.java:632)
  java.nio.file.TempFileHelper.create(TempFileHelper.java:138)
  java.nio.file.TempFileHelper.createTempFile(TempFileHelper.java:161)
  java.nio.file.Files.createTempFile(Files.java:897)
  javax.imageio.stream.FileCacheImageOutputStream.<init>(FileCacheImageOutputStream.java:88)
  com.sun.imageio.spi.OutputStreamImageOutputStreamSpi.createOutputStreamInstance(OutputStreamImageOutputStreamSpi.java:68)
  javax.imageio.ImageIO.createImageOutputStream(ImageIO.java:419)
  javax.imageio.ImageIO.write(ImageIO.java:1572)
  com.neuedu.his.controller.CheckCodeServlet.doPost(CheckCodeServlet.java:85)
  com.neuedu.his.controller.CheckCodeServlet.doGet(CheckCodeServlet.java:89)
  javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
  javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
  org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
  com.neuedu.his.filter.LoginFilter.doFilter(LoginFilter.java:57)
  com.neuedu.his.filter.CharsetFilter.doFilter(CharsetFilter.java:37)
  com.neuedu.his.filter.Filter1.doFilter(Filter1.java:29)
):注意 主要问题的全部 stack 信息可以在 server logs 里查看

Apache Tomcat/9.0.38

没有办法创建输出流
没有办法创建缓冲文件
没有办法在D:\Program Files\apache\apache-tomcat-8.5.60\temp目录生成imageio8447768555205008617.tmp文件

可能原因:

1、tomcat目录下没有temp文件,没有这个文件夹自然无法存放缓存文件,因为默认的是存放在这个文件夹。
2、ImageIO默认是true,使用缓存目录,不使用文件目录缓存,使用内存缓存。

解决方案

扫描二维码关注公众号,回复: 17349852 查看本文章

1.在tomcat文件夹里创建个temp文件夹
2.在CheckCodeServlet类中

ImageIO.write(image, "jpg", resp.getOutputStream()/*【代码二】*/);
//前添加ImageIO.setUseCache(false);语句
ImageIO.setUseCache(false);
ImageIO.write(image, "jpg", resp.getOutputStream()/*【代码二】*/);

资料自提(若过期,请留言)

链接:https://pan.baidu.com/s/1nQvEeV-GNvBdPkH_Ah4wFQ?pwd=m114
提取码:m114

猜你喜欢

转载自blog.csdn.net/qq_52495761/article/details/134683074