9.18JavaWeb之Servlet重定向

9.18JavaWeb之Servlet重定向

什么是重定向?

本质:

两次Http请求,有两个Request对象和Response对象

过程:

服务器在收到客户端请求后,会通知客户端浏览器重新向另外一个 URL 发送请求

重定向工作流程图

 

注意:

服务器端的 Web 资源返回一个状态码为 302 的响应信息,该响应的含义为:通知浏览器再次发送请求,访问另一个 Web 资源(在响应信息中提供了另一个资源的 URL)

转发和重定向的区别

两个比较重要的点:

  • 转发属于服务端内部行为,重定向属于客户端行为

  • 转发不支持跨域跳转,重定向支持

HttpServletResponse接口当中提供的重定向的方法

返回值类型方法描述
void sendRedirect(String location) 向浏览器返回状态码为 302 的响应结果,让浏览器访问新的 URL。若指定的 URL 是相对路径,Servlet 容器会将相对路径转换为绝对路径。参数 location 表示重定向的URL。

示例代码:

需求:

  • 写一个登陆界面

  • 一个验证类

  • 一个处理请求后重定向类

  • 一个被重定向的最终位置类

验证类:

package com.example.HttpServletRequestDemo;

import javax.imageio.ImageIO;
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.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
* 这是一个检查验证码的类,画出验证码然后让别人调用并且输入
* @since JDK 1.8
* @date 2021/09/18
* @author Lucifer
*/
@WebServlet(name = "CheckcodeServlet", value = "/CheckcodeServlet")
public class CheckcodeServlet extends HttpServlet {
   //设置UID
   private static final long serialVersionUID = 1L;

   //Get
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //调用生成验证码的方法
       codeCheck(req, resp);
  }

   //随机生成验证码
   private Boolean codeCheck(HttpServletRequest req, HttpServletResponse resp) throws IOException {
       //设置宽、高
       int width = 120;
       int height = 30;

       //内存中生成图片
       BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
       //获取对象画笔
       Graphics2D g = (Graphics2D) image.getGraphics();
       //设置颜色
       g.setColor(Color.GRAY);
       //填充矩形
       g.fillRect(0, 0, width, height);
       //设置颜色
       g.setColor(Color.BLUE);
       //画边框
       g.drawRect(0, 0, width-1, height-1);

       //准备数据
       String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
       //设置字体颜色
       g.setColor(Color.YELLOW);
       //设置字体样式
       g.setFont(new Font("隶书", Font.BOLD, 20));
       String code = "";
       //构造存储字符的数组
       char[] cd = {};
       //构造存储字符串的集合
       List<String> list = new ArrayList<String>();
       //随机数
       Random random = new Random();
       int x = 20;
       int y = 20;
       //循环获取4个字符
       for (int i = 0; i < 4; i++){
           // void rotate(double theta, double x, double y)
           // theta 弧度
           // hudu = jiaodu * Math.PI / 180;
           // 获取正负30之间的角度
           int jiaodu = random.nextInt(60) - 30;
           double hudu = jiaodu * Math.PI / 180;
           g.rotate(hudu, x, y);
           // 获取下标
           int index = random.nextInt(words.length());
           // 返回指定下标位置的字符,随机获取下标
           char ch = words.charAt(index);
           //将字符存入字符数组中
           char[] chc = {ch};
           //使用字符数组构造字符串
           String string = new String(chc);
           //将构造好的字符串添加进list集合中
           list.add(string);
           // 写字符串
           g.drawString("" + ch, x, y);
           g.rotate(-hudu, x, y);
           x += 20;
      }
       //获取list里面的值
       for (int i = 0; i < list.size(); i++){
           code += list.get(i);
      }
       //将验证码存入上下文中
       getServletContext().setAttribute("code", code);
       // 设置颜色
       g.setColor(Color.GREEN);
       int x1, x2, y1, y2;
       // 画干扰线
       for (int i = 0; i < 4; i++) {
           x1 = random.nextInt(width);
           y1 = random.nextInt(height);
           x2 = random.nextInt(width);
           y2 = random.nextInt(height);
           g.drawLine(x1, y1, x2, y2);
      }
       // 输出到客户端
       return ImageIO.write(image, "jpg", resp.getOutputStream());
  }

   //Post
   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
       doGet(req, resp);
  }
}

处理登录请求类:

package com.example.HttpServletRequestDemo;

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.io.PrintWriter;

/**
* 验证提交的信息的Servlet类
* @since JDK 1.8
* @date 2021/09/18
* @author Lucifer
*/
@WebServlet(name = "DoServletNo2", value = "/DoServletNo2")
public class DoServletNo2 extends HttpServlet {
   //定义UID
   private static final long serialVersionUID = 1L;

   //Get
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
       //设置响应字符集
       resp.setContentType("text/html;charset=UTF-8");
       //向页面输出内容
       PrintWriter writer = resp.getWriter();

       //获取相应的内容
       String username = req.getParameter("username");
       String password = req.getParameter("password");
       String sex = req.getParameter("sex");
       String city = req.getParameter("city");
       //获取爱好--->对象是一个数组
       String language = req.getParameter("language");
       //获取验证码
       String code = req.getParameter("code");

       //设置成功标识符
       Boolean isSuccess = true;
       //上下文获取验证码--->通过Servlet容器的Context对象获取到验证码
       String code1 = (String) getServletContext().getAttribute("code");
       //账号密码为admin,验证码(忽略大小写)正确,跳转到登录成功界面
       if (!"".equals(code) && code!=null && code.equalsIgnoreCase(code1) && "admin".equals(username) && "admin".equals(password)){
           //重定向至登录成功界面
           resp.sendRedirect("/HttpServletRequestDemo_war_exploded/Success");
      }else if (!"admin".equals(username) || !"admin".equals(password)){
           //账号或者密码不为admin
           getServletContext().setAttribute("msg", "账号或密码不正确");
           isSuccess = false;
      }else if ("".equals(code) || code == null || !code.equalsIgnoreCase(code1)){
           //验证码错误,设置错误信息
           getServletContext().setAttribute("msg", "验证码输入错误");
           isSuccess = false;
      }
       if (!isSuccess){
           //设置自动跳转时间,存储在上下文中(Context)
           getServletContext().setAttribute("time", 5);
           //向request对象中设置属性requestAttr,在重定向之后取值。
           req.setAttribute("requestAttr", "重定向中使用request域对象传递的数据");
//           resp.sendRedirect("/HttpServletRequestDemo_war_exploded/RefreshServlet");
           resp.sendRedirect("/HttpServletRequestDemo_war_exploded/RefreshServletNo2");
      }
  }

   //Post
   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doGet(req, resp);
  }
}

重定向类:

package com.example.HttpServletRequestDemo;

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.io.PrintWriter;
import java.util.Arrays;

/**
* 创建获取表单信息的Servlet容器类,用于接收表单的信息并输出到控制台
* @since JDK 1.8
* @date 2021/09/17
* @author Lucifer
*/
@WebServlet(name = "RequestParam", value = "/RequestParam")
public class RequestParam extends HttpServlet {
   //设置UID
   private static final long serialVersionUID = 1L;

   //Get
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //设置响应字符集
       resp.setContentType("text/html;charset=UTF-8");
       PrintWriter writer = resp.getWriter();
       // 获取内容,做其他操作
       //修改request缓冲区的字符集为UTF-8
       req.setCharacterEncoding("utf-8");
       // 获取姓名
       String username = req.getParameter("username");
       // 获取密码
       String password = req.getParameter("password");
       // 获取性别
       String sex = req.getParameter("sex");
       // 获取城市
       String city = req.getParameter("city");
       // 获取语言
       String[] languages = req.getParameterValues("language");
       writer.write(
       "用户名:" + username + "<br/>"
           + "密码:" + password + "<br/>"
           + "性别:" + sex + "<br/>"
           + "城市:" + city + "<br/>"
           + "使用过的语言:" + Arrays.toString(languages) + "<br/>"
      );
  }

   //Post
   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doGet(req, resp);
  }
}

成功类:

package com.example.HttpServletRequestDemo;

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.io.PrintWriter;

/**
* 响应成功的Servlet类
* @since JDK 1.8
* @date 2021/09/18
* @author Lucifer
*/
@WebServlet(name = "Success", value = "/Success")
public class SuccessServlet extends HttpServlet {
   //设置UID
   private static final long serialVersionUID = 1L;

   //Get
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
       //设置响应字符集
       resp.setContentType("text/html;charset=UTF-8");
       //输出内容到控制台
       PrintWriter writer = resp.getWriter();
       writer.write("<h1>登录成功</h1>");
  }

   //Post
   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doGet(req, resp);
  }
}

登陆表单:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>This is a login form</title>
</head>
<body>
 <form action="/HttpServletRequestDemo_war_exploded/DoServletNo2" method="get">
   <table border="1" width="80%">
     <tr>
       <td colspan="2" align="center">
        Welcome to JunkingBoy Home
       </td>
     </tr>
     <tr>
       <td>
        账号:
       </td>
       <td>
         <input type="text" name="username" />
       </td>
     </tr>
     <tr>
       <td>
        密码:
       </td>
       <td>
         <input type="text" name="password" />
       </td>
     </tr>
     <tr>
       <td>
        选择性别:
       </td>
       <td>
         <input type="radio" name="sex" value="male" />男
         <input type="radio" name="sex" value="female" />女
       </td>
     </tr>
     <tr>
       <td>
        选择使用的语言:
       </td>
       <td>
         <input type="checkbox" name="language" value="Java" />Java
         <input type="checkbox" name="language" value="C" />C
         <input type="checkbox" name="language" value="Go" />Go
         <input type="checkbox" name="language" value="C++" />C++
       </td>
     </tr>
     <tr>
       <td>
        选择城市:
       </td>
       <td>
         <select name="city">
           <option value="none">---请选择---</option>
           <option value="柳州">柳州</option>
           <option value="桂林">桂林</option>
           <option value="南宁">南宁</option>
         </select>
       </td>
     </tr>
     <tr>
       <td>
        验证码:
       </td>
       <td>
         <input type="text" name="code" />
         <img id="imgId" src="/HttpServletRequestDemo_war_exploded/CheckcodeServlet">
         <a href="#" onclick="run()">看不清楚,更换一张</a>
       </td>
     </tr>
     <tr>
       <td colspan="2" align="center">
         <input type="submit" value="提交" />
       </td>
     </tr>
   </table>
 </form>
</body>
<!--定义run方法-->
<script type="text/javascript">
 //看不清换一张时间戳
 function run(){
   //获取图片
   var image = document.getElementById("imgId");
   image.src = "/HttpServletRequestDemo_war_exploded/CheckcodeServlet?" + new Date().getTime();
}
</script>
</html>

 

It's a lonely road!!!
原文地址:https://www.cnblogs.com/JunkingBoy/p/15308490.html