Servlet请求转发与重定向

news2024/11/26 16:26:31

目录

一、请求转发

1、RequestDispatcher 接口

2、请求转发的工作原理

3、request 域对象

4、示例

二、重定向

1、response.sendRedirect()

2、示例

3、转发和重定向的区别


一、请求转发

        Web 应用在处理客户端请求时,经常需要多个 Web 资源共同协作才能生成响应结果。但由于 Servlet 对象无法直接调用其他 Servlet 的 service() 方法,所以 Servlet 规范提供了 2 种解决方案:

  • 请求转发
  • 请求包含(了解即可)

        请求转发属于服务器行为。容器接收请求后,Servlet 会先对请求做一些预处理,然后将请求传递给其他 Web 资源,来完成包括生成响应在内的后续工作。

1、RequestDispatcher 接口

        在 jakarta.servlet 包中定义了一个 RequestDispatcher 接口。继承关系如下图所示:

        RequestDispatcher 对象由 Servlet 容器创建,用于封装由路径所标识的 Web 资源。利用 RequestDispatcher 对象可以把请求转发给其他的 Web 资源。

1)Servlet 可以通过以下2种方式获得 RequestDispatcher 对象:

  • 调用 ServletContext 的 getRequestDispatcher(String path) 方法,参数 path 指定目标资源的路径,必须为绝对路径;
  • 调用 ServletRequest 的 getRequestDispatcher(String path) 方法,参数 path 指定目标资源的路径,可以为绝对路径,也可以为相对路径;

绝对路径是指:以正斜杠 "/" 开头的路径,"/" 表示当前 Web 应用的根目录。

相对路径是指:相对当前 Web 资源的路径,不以正斜杠 "/" 开头。

2)RequestDispatcher 接口中提供了以下方法:

返回值类型方法描述
voidforward(ServletRequest request, ServletResponse response)用于将请求转发给另一个 Web 资源。该方法必须在响应给客户端之前被调用,否则将抛出 IllegalStateException 异常。
voidinclude(ServletRequest request, ServletResponse response)用于将其他的资源作为当前响应内容包含进来。

2、请求转发的工作原理

        在 Servlet 中,通常使用 forward() 方法将当前请求转发给其他的 Web 资源进行处理。请求转发的工作原理如下图所示:

请求转发具有以下特点:

  • 请求转发不支持跨域访问,只能跳转到当前应用中的资源;
  • 请求转发之后,浏览器地址栏中的 URL 不会发生变化。因此浏览器不知道在服务器内部发生了转发行为,更无法得知转发的次数;
  • 参与请求转发的 Web 资源之间共享同一 request 对象和 response 对象;
  • 由于 forward() 方法会先清空 response 缓冲区,因此只有转发到最后一个 Web 资源时,生成的响应才会被发送到客户端;

3、request 域对象

        request 是 Servlet 的三大域对象之一,它需要与请求转发配合使用,才可以实现动态资源间的数据传递。在 ServletRequest 接口中定义了一系列操作属性的方法,如下表:

返回值类型方法描述
voidsetAttribute(String name, Object o)将 Java 对象与属性名绑定,并将它作为一个属性存放到 request 对象中。参数 name 为属性名,参数 object 为属性值。
ObjectgetAttribute(String name)根据属性名 name,返回 request 中对应的属性值。
voidremoveAttribute(String name)用于移除 request 对象中指定的属性。
Enumeration<String>getAttributeNames()用于返回 request 对象中的所有属性名的枚举集合。 

4、示例

        创建一个名为 RequestDispatcherServletDemo 的类,代码如下:

package com.hoperun.www;

import java.io.IOException;
import java.io.PrintWriter;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/RequestDispatcherServlet")
public class RequestDispatcherServletDemo extends HttpServlet {

	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		// 设置向页面输出内容格式
		response.setContentType("text/html;charset=UTF-8");

		PrintWriter writer = response.getWriter();

		// 尝试在请求转发前,向 response 缓冲区写入内容,最后在页面查看是否展示.
		writer.write("<h1>这是转发前响应信息里的内容。</h1>");

		// 向 request 域对象中添加属性,传递给下一个 Web 资源.
		request.setAttribute("属性名1", "属性值1");
		request.setAttribute("属性名2", "属性值2");
		request.setAttribute("属性名3", "属性值3");

		// 转发
		request.getRequestDispatcher("/DoServlet").forward(request, response);
	}

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

        然后,再创建一个名称为 DoServlet 的类,代码如下:

package com.hoperun.www;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/DoServlet")
public class DoServletDemo extends HttpServlet {

	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 设置向页面输出内容格式
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter writer = response.getWriter();

		// 获取 request 域对象中的属性值
		String value1 = (String) request.getAttribute("属性名1");
		String value2 = (String) request.getAttribute("属性名2");
		String value3 = (String) request.getAttribute("属性名3");
		if (value1 != null) {
			writer.write("<h3>" + value1 + "</h3>");
		}
		if (value2 != null) {
			writer.write("<h3>" + value2 + "</h3>");
		}
		if (value3 != null) {
			writer.write("<h3>" + value3 + "</h3>");
		}
		// 获取用户名
		String username = request.getParameter("username");
		// 获取密码
		String password = request.getParameter("password");
		// 获取性别
		String sex = request.getParameter("sex");
		// 获取城市
		String city = request.getParameter("city");
		// 获取使用语言
		String[] languages = request.getParameterValues("language");
		writer.write("用户名: " + username + "<br/>" + "密码: " + password + "<br/>" + "性别: " + sex + "<br/>" + "城市: " + city
				+ "<br/>" + "使用过的语言: " + Arrays.toString(languages));
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

在 webapp 根目录下,创建 index.html,代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action="/servletDemo/RequestDispatcherServlet" method="GET">
        <table border="1">
            <tr>
                <td colspan="2" align="center">CSDN</td>
            </tr>
            <tr>
                <td>姓名</td>
                <td>
                	<input type="text" name="username" />
                </td>
            </tr>
            <tr>
                <td>密码</td>
                <td>
                	<input type="password" name="password" />
				</td>
            </tr>
            <tr>
                <td>性别</td>
                <td>
                	<input type="radio" name="sex" value="男" />男
                	<input type="radio" name="sex" value="女" />女
				</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="PHP" />PHP
                    <input type="checkbox" name="language" value="Python" />Python
				</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 colspan="2" align="center" >
                	<input type="submit" value="提交" />
                </td>
            </tr>
        </table>
    </form>
</body>
</html>

        启动 Tomcat 服务器,在地址栏输入 http://localhost:8080/servletDemo/index.html,访问 index.html,结果如下图:

         填写表单信息,点击提交,结果如下图:

二、重定向

        重定向属于客户端行为。服务器在收到客户端请求后,会通知客户端浏览器重新向另外一个 URL 发送请求,这称为请求重定向。它本质上是两次 HTTP 请求,对应两个 request 对象和两个 response 对象。

        重定向的工作流程如下:

  • 用户在浏览器中输入URL请求访问服务器端的 Web 资源;
  • 服务器端的 Web 资源返回一个状态码为 302 的响应。该响应的含义为:通知浏览器再次发送请求,访问另一个 Web 资源(在响应信息中提供了另一个资源的 URL);
  • 当浏览器接收到响应后,立即自动访问另一个指定的 Web 资源;
  • 该 Web 资源将请求处理完成后,由容器把响应信息返回给浏览器进行展示;

1、response.sendRedirect()

        HttpServletResponse 接口中的 sendRedirect() 方法用于实现重定向。

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

2、示例

        在 servletDemo 的 webapp 中,创建登录页面 login.html,代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="/servletDemo/ReDirectServlet" method="GET">
        <table border="1">
            <tr>
                <td colspan="2" align="center">CSDN</td>
            </tr>
            <tr>
                <td>姓名</td>
                <td>
                	<input type="text" name="username" />
                </td>
            </tr>
            <tr>
                <td>密码</td>
                <td>
                	<input type="password" name="password" />
				</td>
            </tr>
            <tr>
                <td>性别</td>
                <td>
                	<input type="radio" name="sex" value="男" />男
                	<input type="radio" name="sex" value="女" />女
				</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="PHP" />PHP
                    <input type="checkbox" name="language" value="Python" />Python
				</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="/servletDemo/CheckCodeServlet" />
	                <a href="#" onclick="run()">看不清,换一张</a>
	            </td>
			</tr>
            <tr>
                <td colspan="2" align="center" >
                	<input type="submit" value="提交" />
                </td>
            </tr>
        </table>
    </form>
</body>
<script type="text/javascript">
    // 看不清,换一张,时间戳
    function run() {
        // 获取图片
        var image = document.getElementById("imgId");
        image.src = "/servletDemo/CheckCodeServlet?" + new Date().getTime();
    }
</script>
</html>

        创建名称为 CheckCodeServlet 的 Servlet 类,代码如下:

package com.hoperun.www;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * 使用 Java 生成验证码图片,并通过 response 对象展示在页面上.
 */
@WebServlet("/CheckCodeServlet")
public class CheckCodeServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, 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);
		// 设置颜色
		g.setColor(Color.YELLOW);
		// 设置字体
		g.setFont(new Font("隶书", Font.BOLD, 20));
		// 准备数据,随机获取4个字符
		String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
		String code = "";
		// 构造存储字符串的集合
		List<String> list = new ArrayList<String>();
		Random random = new Random();
		int x = 20;
		int y = 20;
		for (int i = 0; i < 4; i++) {
			// 获取正负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;
		}
		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);
		}
		// 输出到客户端
		ImageIO.write(image, "jpg", response.getOutputStream());
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

        创建名称为 ReDirectServletDemo 的 Servlet 类,代码如下:

package com.hoperun.www;

import java.io.IOException;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * 验证提交的信息
 */
@WebServlet("/ReDirectServlet")
public class ReDirectServletDemo extends HttpServlet {

	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 获取用户名
		String username = request.getParameter("username");

		// 获取密码
		String password = request.getParameter("password");

		// 获取验证码
		String code = request.getParameter("code");

		// 设置是否成功标识
		Boolean IsSuccess = true;

		// 从上下文获取存储的验证码
		String code1 = (String) getServletContext().getAttribute("code");

		// 账号密码为admin.且验证码(忽略大小写)输入正确,则跳转到登陆成功页面
		if (code != null && !code.isEmpty() && code.equalsIgnoreCase(code1) && "admin".equals(username)
				&& "admin".equals(password)) {
			response.sendRedirect("/servletDemo/SuccessServlet");
			// 账号密码不为admin,设置错误信息
		} else if (!"admin".equals(username) || !"admin".equals(password)) {
			getServletContext().setAttribute("msg", "账号或密码不正确!");
			IsSuccess = false;
			// 验证码错误,设置错误信息
		} else if (code == null || code.isEmpty() || !code.equalsIgnoreCase(code1)) {
			getServletContext().setAttribute("msg", "验证码输入错误!");
			IsSuccess = false;
		}

		if (!IsSuccess) {
			// 设置自动跳转的时间,存储在上下文中
			getServletContext().setAttribute("time", 5);

			// 向request对象中设置属性requestAttr,在重定向之后取值。
			request.setAttribute("requestAttr", "重定向中使用request域对象传递的数据");
			response.sendRedirect("/servletDemo/RefreshServlet");
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

        创建名称为 RefreshServletDemo 的 Servlet 类,代码如下:

package com.hoperun.www;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * 登录失败后,提示错误信息并定时跳转回登录页面. 通过设置响应头字段(refresh)实现页面的定时跳转
 */
@WebServlet("/RefreshServlet")
public class RefreshServletDemo extends HttpServlet {

	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		Object requestAttr = request.getAttribute("requestAttr");
		// 获取存在上下文中的跳转时间
		int times = (int) getServletContext().getAttribute("time");
		// 获取存在上下文中的错误信息
		String msg = (String) getServletContext().getAttribute("msg");
		/**
		 * 设置三个头信息,禁用浏览器缓存 Expires: -1 值是日期类型 Pragma : no-cache
		 */
		// 设置三个头信息:
		// 设置禁用浏览器缓存
		response.setHeader("Cache-Control", "no-cache");
		response.setHeader("Pragma", "no-cache");
		// 这个头信息指定内容过期的时间,在这之后内容不再被缓存。-1:立即过期
		response.setDateHeader("Expires", -1);
		// 设置向页面输出的格式
		response.setContentType("text/html;charset=UTF-8");
		// 设置提示
		String title = msg + ",即将在" + times + "秒钟后跳转到登录页";
		// 使用默认时区和语言环境获得一个日历
		Calendar cale = Calendar.getInstance();
		// 将Calendar类型转换成Date类型
		Date tasktime = cale.getTime();
		// 设置日期输出的格式
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		// 格式化输出
		String nowTime = df.format(tasktime);
		// 只要倒计时时间没有到0,就直至输出下面内容
		if (times != 0) {
			response.getWriter()
					.write("<html>\n" + "<head><title >" + title + "</title></head>\n" + "<body bgcolor=\"#f0f0f0\">\n"
							+ "<h1 align=\"center\">CSDN  提醒您:</h1>"
							+ "<h1 align=\"center\" style=\"font-family:arial;color:red;\">" + title + "</h1>\n"
							+ "<h1 align=\"center\">当前时间是: " + nowTime + "</h1>\n"
							+ "<h1 align=\"center\">重定向通过request传递的数据为: " + requestAttr + "</h1>\n");
			// 倒计时
			times--;
			// 将倒计时的时间重新存入上下文中覆盖原来的值
			getServletContext().setAttribute("time", times);
			// 通过refresh头完成页面刷新
			response.setHeader("refresh", "1;url=/servletDemo/RefreshServlet");
		} else {
			// 倒计时归零,则跳转到登陆页面
			response.sendRedirect("/servletDemo/login.html");
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

        创建名称为 SuccessServletDemo 的 Servlet 类,代码如下:

package com.hoperun.www;

import java.io.IOException;
import java.io.PrintWriter;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * 登录成功
 */
@WebServlet("/SuccessServlet")
public class SuccessServletDemo extends HttpServlet {

	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 设置响应输出的格式
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter writer = response.getWriter();
		writer.write("<h1>登录成功</h1>");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

        启动 Tomcat,在地址栏输入http://localhost:8080/servletDemo/login.html,访问登录页,如下图所示:

        在登录页面输入账号、密码、验证码等信息(当账号和密码都为 admin 时验证成功,否则验证失败),这里我们输入错误的验证码点击提交按钮,结果如下图:

         输入正确信息,点击提交,结果如下图:

3、转发和重定向的区别

        转发和重定向都能实现页面的跳转,两者区别如下:

区别转发重定向
浏览器地址栏 URL 是否发生改变
是否支持跨域跳转
请求与响应的次数一次请求和一次响应两次请求和两次响应
是否共享 request 对象和 response 对象    
是否能通过 request 域对象传递数据
速度相对要快相对要慢
行为类型服务器行为客户端行为

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/42545.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

工作中规范使用Java集合

目录 一、前言 二、规范使用Java集合 1.【强制】关于 hashCode 和 equals 的处理&#xff0c;遵循如下规则&#xff1a; 2.【强制】判断所有集合内部的元素是否为空&#xff0c;使用 isEmpty() 方法&#xff0c;而不是 size() 0 的方式。 3.【强制】在使用 java.util.str…

防火墙原理讲解——练习实验

♥️作者&#xff1a;小刘在C站 ♥️每天分享云计算网络运维课堂笔记&#xff0c;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的&#xff0c;绽放。 目录 一防火墙基础 二防火墙配置 三防火墙的高级应用 四.实验图纸 五.实验命令 一防火…

使用SPARK进行特征工程

文章目录特征工程预处理特征选择归一化离散化Embedding向量计算效果对比特征工程 在机器学习领域&#xff0c;有一条尽人皆知的“潜规则”&#xff1a;Garbage in&#xff0c;garbage out。它的意思是说&#xff0c;当我们喂给模型的数据是“垃圾”的时候&#xff0c;模型“吐…

1. Vue 3.0介绍

Vue3.0介绍 1.Vue.js 3.0 源码组织方式 Vue2.x与Vue3.0的区别 源码组织方式的变化 Vue3.0的源码全部采用TypeScript重写使用Monorepo方式来组织项目结构&#xff0c;把独立的功能模块都提取到不同的包中。 packages下都是独立发行的包&#xff0c;可以独立使用。 Compositi…

[U3D ShaderGraph] 全面学习ShaderGraph节点 | 第二课 | Input/Geometry

ShaderGraph是可视化的着色器编辑工具。您可以使用此工具以可视方式创建着色器。 本专栏可以让你更了解ShaderGraph中每个节点的功能&#xff0c;更自如的在做出自己想要的效果。 如果你想学习在unity中如何制作一个特效&#xff0c;如何在unity中让模型更炫酷&#xff0c;那就…

Python实现导弹自动追踪

自动追踪算法&#xff0c;在我们制作射击类游戏时经常会用到。这个听起来很高大上的东西&#xff0c;其实并不是军事学的专利&#xff0c;从数学上来说就是解微分方程。 这个没有点数学基础是很难算出来的。但是我们有了计算机就不一样了&#xff0c;依靠计算机极快速的运算速…

【Scala专栏】走进Scala

官方文档: https://www.scala-lang.org/ 一、What is Scala? Scala是一种针对JVM 将面向函数和面向对象技术组合在一起的编程语言。Scala编程语言近来抓住了很多开发者的眼球。它看起来像是一种纯粹的面向对象编程语言&#xff0c;而又无缝地结合了命令式和函数式的编程风格…

服务访问质量(QoS)——流量整形与拥塞管理

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.流量整形和监管配置 1.流量整形配置两种方式 ①流量整形的命…

从零开始上手 MQTT over QUIC:快速体验下一代物联网标准协议

前言 QUIC(RFC9000) 是下一代互联网协议 HTTP/3 的底层传输协议&#xff0c;与 TCP/TLS 协议相比&#xff0c;它在减少连接开销与消息延迟的同时&#xff0c;为现代移动互联网提供了有效灵活的传输层。 EMQX 5.0 是首个将 QUIC 引入 MQTT 的开创性产品。在长期的客户服务和技…

eunomia-bpf项目重磅开源!eBPF 轻量级开发框架来了

近日&#xff0c;在 2022 云栖大会龙蜥峰会 eBPF & Linux 稳定性专场上&#xff0c;来自 eBPF 技术探索 SIG Maintainer 、浙江大学的郑昱笙分享了《eunomia-bpf&#xff1a;eBPF 轻量级开发框架》技术演讲&#xff0c;以下为本次演讲内容&#xff1a; 大家好&#xff01;…

【新知实验室-TRTC开发】实时音视频之web端云监工系统(Vue3+Element plus+TS+Pinia)

在线上线下一体化、虚拟现实加速融合的趋势下&#xff0c;音视频已经演进成一种基本能力&#xff0c;深刻变革了社会的交互方式。未来&#xff0c;音视频作为全真互联时代的重要基石&#xff0c;将持续推动互联网和实体产业的数字化创新与升级。 今天我们将体验腾讯的实时音视…

vue3 antd table表格的增删改查(一)input输入框根据关键字搜索【后台管理系统纯前端filter过滤】

input输入框——关键字模糊搜索引言铺垫场景复现解决方案筛选的实现重置筛选信息优化处理&#xff08;监听的实现&#xff09;功能实现可能要用到的知识&#xff1a;vue3数据变化侦测&&信息筛选过滤.filter() .map() .forEach(). find()&#x1f525;vue3【watch检测/监…

[附源码]Python计算机毕业设计Django4S店汽车售后服务管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【服务器数据恢复】IBM服务器RAID控制器出错的数据恢复案例

服务器数据恢复环境&#xff1a; 北京某公司IBM X系列某型号服务器&#xff1b; 服务器上共8块硬盘组建raid5磁盘阵列&#xff1b; 服务器上部署有oracle数据库。 服务器故障&分析&#xff1a; 服务器在运行过程中&#xff0c;raid5磁盘阵列中有2块硬盘报警&#xff0c;服务…

CRM(Mapper层)详细代码

Mapper详细代码&#xff1a; DicValueMapper&#xff1a; package com.bjpowernode.crm.settings.mapper;import com.bjpowernode.crm.settings.domain.DicValue;import java.util.List;public interface DicValueMapper {/*** This method was generated by MyBatis Generato…

制作覆盖手绘图的导游地图,非常简单,你也可以

目录 1 前言 2 手绘地图的准备 3 下载软件 4 切图软件基本设置 5 配准设置 6 从平台取得上传切片所需要的3个参数 7 程序切片 8 增加位置点 1 前言 上一篇介绍了制作“简版导游地图”的步骤&#xff0c;真的是特别简单&#xff0c;如果提前准备好了文字材料&#xff0c…

PHP转Go,框架选什么?

文章目录内功心法PHP转Go&#xff0c;优选哪个框架&#xff1f;为什么&#xff1f;为什么不火&#xff1f;GoFrame特点优势&#xff1a;劣势&#xff1a;框架选型谁适合用GoFrame谁不适合用GoFrameGoFrame框架设计思想开发流程从0到1核心步骤总结视频一起学习这是一期会引起广泛…

即时通讯赛道开打信创牌,WorkPlus为何独树一帜?

近期&#xff0c;信创火了。 随着近期国家相关政策文件的推出&#xff0c;未来三年&#xff0c;党政信创、行业信创以及央国企信创的建设&#xff0c;将迎来全面加速。业内人士认为&#xff1a;“大信创”时代或已来临&#xff01; 信创是什么&#xff1f; 信创&#xff0c;…

加载用户数据至用户维度表

目录 1.创建转换 2.配置表输入 3.配置表输入2 4.创建新转换 5.配置映射输入规范 6.配置数据库查询 7.配置数据库查询2 8.配置数据库查询3 9.配置过滤记录 10配置JavaScript代码 11.配置字段选择 12.配置映射输出规范 13.配置映射&#xff08;子转换&#xff09; 1…

JS进阶第一篇:手写call apply bind

文章目录手写call apply bind深入理解 call 方法手写call手写apply手写bind手写call apply bind 深入理解 call 方法 call 理解了&#xff0c;apply和bind就都迎刃而解了&#xff0c;他们都是大同小异。在此对call和apply不做过多的定义性解释&#xff0c;先来看下调用了call…