javaweb-experiment 8--final review

Experiment 8 JSP built-in objects (2)

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

1. Experimental purpose:

1. Master the basic usage of session.
2. Understand the differences between various domain objects.

2. Experimental content:

Implement user login based on verification code.
Insert image description here

【Experimental steps】( 补全代码一 ~ 代码七)

(1) Create a new project (Web application) named "web8". In the project, create a new JSP and name it "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) Create a new java package "it.servlet". Create a new java class in this package and name it "CheckCodeServlet".
The main functions of CheckCodeServlet.java: generate verification codes, display the verification codes in the browser, and store the verification codes in the session object.

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) Create a new Java class named "LoginServlet" in the "it.servlet" package. LoginServlet.java is used to check whether the user name, password and verification code are correct: if the login is successful, it will jump to welcome.jsp; if the login fails, it will jump back to login.jsp and display the corresponding error prompt.

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) Create a new JSP file and name it "welcome".
welcome.jsp checks whether the user has successfully logged in; if not, jumps back to login.jsp; otherwise, the welcome message "***, welcome" is displayed. The effect is as follows:

<%@ 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>

Implementation

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>

Error reporting and resolution

1. If there is a problem that the verification code on the login.jsp page does not display

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

There is no way to create an output stream.
There is no way to create a buffer file.
There is no way to generate the imageio8447768555205008617.tmp file in the D:\Program Files\apache\apache-tomcat-8.5.60\temp directory.

Possible Causes:

1. There is no temp file in the tomcat directory. Without this folder, cache files cannot be stored, because the default is to store them in this folder.
2. ImageIO defaults to true, using the cache directory, not using the file directory cache, and using the memory cache.

solution

1. Create a temp folder in the tomcat folder
2. In the CheckCodeServlet class

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

Self-pickup of information (if expired, please leave a message)

Link: https://pan.baidu.com/s/1nQvEeV-GNvBdPkH_Ah4wFQ?pwd=m114
Extraction code: m114

Guess you like

Origin blog.csdn.net/qq_52495761/article/details/134683074