[Java Web]Request对象 | 超1w字带你熟悉Servlet中的request请求
⭐作者介绍:大二本科网络工程专业在读,持续学习Java,输出优质文章
⭐所属专栏:Java Web
⭐如果觉得文章写的不错,欢迎点个关注😉有写的不好的地方也欢迎指正,一同进步😁
目录
Request对象
1、Request继承体系
2、Request获取请求数据
2.1、获取请求行数据
2.2、获取请求头数据
2.3、获取请求体数据
2.4、获取请求参数的通用方式
2.5、完整代码
3、IDEA快速创建Servlet
4、请求参数中文乱码问题
4.1、🔺POST请求解决方案
4.2、🔺🔺GET请求解决方案
5、Request请求转发
Request对象
1、Request继承体系
在学习这节内容之前,先思考一个问题,前面在介绍Request和Reponse对象的时候:
- 当Servlet类实现的是Servlet接口的时候,service方法中的参数是ServletRequest和ServletResponse
- 当Servlet类继承的是HttpServlet类的时候,doGet和doPost方法中的参数就变成HttpServletRequest和HttpServletReponse
那么:
- ServletRequest和HttpServletRequest的关系是什么?
- request对象是有谁来创建的?
- request提供了哪些API,这些API从哪里查?
首先,先看Request的继承体系:
从上图中可以看出,ServletRequest和HttpServletRequest都是Java提供的,所以我们可以打开JavaEE提供的API文档查看:
所以ServletRequest和HttpServletRequest是继承关系,并且两个都是接口,接口是无法创建对象,这个时候就引发了下面这个问题:方法参数中传递的对象是由谁创建的
这个时候,就需要用到Request继承体系中的RequestFacade:
- 该类实现了HttpServletRequest接口,也间接实现了ServletRequest接口。
- Servlet类中的service方法、doGet方法或者是doPost方法最终都是由Web服务器[Tomcat]来调用的,所以Tomcat提供了方法参数接口的具体实现类,并完成了对象的创建
- 要想了解RequestFacade中都提供了哪些方法,可以直接查看JavaEE的API文档中关于ServletRequest和HttpServletRequest的接口文档,因为RequestFacade实现了其接口就需要重写接口中的方法
对于上述结论,要想验证,可以编写一个Servlet,在方法中把request对象打印下,就能看到最终的对象是不是RequestFacade,代码如下:
@WebServlet("/demo2")
public class Demo2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println(request);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
启动服务器,运行访问,得到运行结果:
小结:
- Request的继承体系为ServletRequest-->HttpServletRequest-->RequestFacade
- Tomcat需要解析请求数据,封装为request对象,并且创建request对象传递到service方法
- 使用request对象,可以查阅JavaEE API文档的HttpServletRequest接口中方法说明
2、Request获取请求数据
HTTP请求数据总共分为三部分内容,分别是请求行、请求头、请求体,对于这三部分内容的数据,分别该如何获取,首先我们先来学习请求行数据如何获取?
2.1、获取请求行数据
请求行包含三块内容,分别是请求方式、请求资源路径、HTTP协议及版本
对于这三部分内容,request对象都提供了对应的API方法来获取,具体如下:
- 获取请求方式:
GET->String getMethod()
- 获取虚拟目录(项目访问路径):
/Servlet->String getContextPath()
- 获取URL(统一资源定位符):
http://localhost:8080/Servlet/req1->StringBuffer getRequestURL()
- 获取URI(统一资源标识符):
/Servlet/req1->String getRequestURI()
- 获取请求参数(GET方式):
username=zhangsan&password=123->String getQueryString()
介绍完上述方法后,下面通过代码把上述方法都使用下:
package com.xzl.Request_Response;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;/*** @author ︶ㄣ释然* @date 2023/3/10 8:46* request 获取请求数据*/
@WebServlet("/demo3")
public class Demo3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// String getMethod():获取请求方式: GETString method = req.getMethod();System.out.println(method);//GET// String getContextPath():获取虚拟目录(项目访问路径)://ServletString contextPath = req.getContextPath();System.out.println(contextPath);// StringBuffer getRequestURL(): 获取URL(统一资源定位符):http://localhost:8080/Servlet/demo3StringBuffer url = req.getRequestURL();System.out.println(url.toString());// String getRequestURI():获取URI(统一资源标识符): /Servlet/demo3String uri = req.getRequestURI();System.out.println(uri);// String getQueryString():获取请求参数(GET方式): name=ZiLin+XString queryString = req.getQueryString();System.out.println(queryString);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}
启动服务器,访问http://localhost:8080/Servlet/demo3?name=ZiLin+X,获取的结果如下:
2.2、获取请求头数据
对于请求头的数据,格式为key: value如下:
所以根据请求头名称获取对应值的方法为:->String getHeader(String name)
接下来,在代码中如果想要获取客户端浏览器的版本信息,则可以使用
/*** request 获取请求数据*/
@WebServlet("/version")
public class version extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取请求头: user-agent: 浏览器的版本信息String agent = req.getHeader("user-agent");System.out.println(agent);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}
重新启动服务器后,获取的结果如下:
2.3、获取请求体数据
浏览器在发送GET请求的时候是没有请求体的,所以需要把请求方式变更为POST,请求体中的数据格式如下:
对于请求体中的数据,Request对象提供了如下两种方式来获取其中的数据,分别是:
- 获取字节输入流,如果前端发送的是字节数据,比如传递的是文件数据,则使用该方法
ServletInputStream getInputStream() 该方法可以获取字节
- 获取字符输入流,如果前端发送的是纯文本数据,则使用该方法
BufferedReader getReader()
接下来,需要思考,要想获取到请求体的内容该如何实现?
具体实现的步骤如下:
1.准备一个页面,在页面中添加form表单,用来发送post请求
2.在Servlet的doPost方法中获取请求体数据
3.在doPost方法中使用request的getReader()或者getInputStream()来获取
4.访问测试
详细步骤:
1、在项目的webapp目录下添加一个html页面,名称为:req.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--action:form表单提交的请求地址method:请求方式,指定为post
-->
<form action="/Servlet/req1" method="post"><input type="text" name="username"><input type="password" name="password"><input type="submit">
</form>
</body>
</html>
2、在Servlet的doPost方法中获取数据
调用getReader()或者getInputStream()方法,因为目前前端传递的是纯文本数据,所以我们采用getReader()方法来获取
package com.xzl.Request_Response;/*** @author ︶ㄣ释然* @date 2023/3/10 10:27*/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.BufferedReader;
import java.io.IOException;/*** request 获取请求数据*/
@WebServlet("/req1")
public class req1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//在此处获取请求体中的数据//获取post 请求体:请求参数//1. 获取字符输入流BufferedReader br = req.getReader();//2. 读取数据String line = br.readLine();System.out.println(line);}
}
3、启动服务器,通过浏览器访问http://localhost:8080/Servlet/req.html
点击提交按钮后,就可以在控制台看到前端所发送的请求数据
注意
BufferedReader流是通过request对象来获取的,当请求完成后request对象就会被销毁,request对象被销毁后,BufferedReader流就会自动关闭,所以此处就不需要手动关闭流了。
小结
HTTP请求数据中包含了请求行、请求头和请求体,针对这三部分内容,Request对象都提供了对应的API方法来获取对应的值:
- 请求行
- getMethod()获取请求方式
- getContextPath()获取项目访问路径
- getRequestURL()获取请求URL
- getRequestURI()获取请求URI
- getQueryString()获取GET请求方式的请求参数
- 请求头:getHeader(String name)根据请求头名称获取其对应的值
- 请求体
- 注意: 浏览器发送的POST请求才有请求体
- 如果是纯文本数据:getReader()
- 如果是字节数据如文件数据:getInputStream()
2.4、获取请求参数的通用方式
在介绍下面内容之前,先提出两个问题:
- 什么是请求参数?
- 请求参数和请求数据的关系是什么?
1、什么是请求参数?
为了能更好的回答上述两个问题,这里拿用户登录的例子来说明:
1.1 想要登录网址,需要进入登录页面
1.2 在登录页面输入用户名和密码
1.3 将用户名和密码提交到后台
1.4 后台校验用户名和密码是否正确
1.5 如果正确,则正常登录,如果不正确,则提示用户名或密码错误
上述例子中,用户名和密码其实就是所谓的请求参数。
2.什么是请求数据?
请求数据则是包含请求行、请求头和请求体的所有数据
3.请求参数和请求数据的关系是什么?
3.1 请求参数是请求数据中的部分内容
3.2 如果是GET请求,请求参数在请求行中
3.3 如果是POST请求,请求参数一般在请求体中
对于请求参数的获取,常用的有以下两种:
- GET方式->String getQueryString()
- POST方式->BufferedReader getReader();
练习一个案例需求:
(1)发送一个GET请求并携带用户名,后台接收后打印到控制台
(2)发送一个POST请求并携带用户名,后台接收后打印到控制台
此处大家需要注意的是GET请求和POST请求接收参数的方式不一样,具体实现的代码如下:
package com.xzl.Request_Response;/*** @author ︶ㄣ释然* @date 2023/3/10 10:27*/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.BufferedReader;
import java.io.IOException;/*** request 获取请求数据*/
@WebServlet("/req1")
public class req1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String result = req.getQueryString();System.out.println(result);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//在此处获取请求体中的数据//获取post 请求体:请求参数//1. 获取字符输入流BufferedReader br = req.getReader();//2. 读取数据String line = br.readLine();System.out.println(line);}
}
- 对于上述的代码,会存在什么问题呢?
由于请求方式不一样,导致两个方法中存在着大量重复代码
- 如何解决上述重复代码的问题?
需要注意的是,doGet和doPost方法都必须存在,不能删除任意一个。
使用request的getMethod()来获取请求方式,根据请求方式的不同分别获取请求参数值,这样就可以解决上述问题,但是以后每个Servlet都需要这样写代码,实现起来比较麻烦,所以这种方法不采用。
更好的解决方案:
request对象已经将上述获取请求参数的方法进行了封装,并且request提供的方法实现的功能更强大,以后只需要调用request提供的方法即可,在request的方法中都实现了哪些操作?
(1)根据不同的请求方式获取请求参数,获取的内容如下:
(2)把获取到的内容进行分割,内容如下:
(3)把分割后端数据,存入到一个Map集合中
注意:因为参数的值可能是一个,也可能有多个,所以Map的值的类型为String数组。
基于上述理论,request对象提供了如下方法:
- 获取所有参数Map集合->Map<String,String[]> getParameterMap()
- 根据名称获取参数值(数组)->String[] getParameterValues(String name)
- 根据名称获取参数值(单个值)->String getParameter(String name)
接下来,通过案例来把上述的三个方法进行实例演示:
1.修改req.html页面,添加爱好选项,爱好可以同时选多个
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form action="/Servlet/req2" method="get"><input type="text" name="username"><br><input type="password" name="password"><br><input type="checkbox" name="hobby" value="1"> 游泳<input type="checkbox" name="hobby" value="2"> 爬山 <br><input type="submit">
</form>
</body>
</html>
2.在Servlet代码中获取页面传递GET请求的参数值 [完整代码放在本小节2.2的最后]
2.1获取GET方式的所有请求参数
获取的结果为:
2.2获取GET请求参数中的爱好,结果是数组值
获取的结果为:
2.3、获取GET请求参数中的用户名和密码,结果是单个值
获取的结果为:
3.在Servlet代码中获取页面传递POST请求的参数值
3.1将req.html页面form表单的提交方式改成post
3.2将doGet方法中的内容复制到doPost方法中即可
2.5、完整代码
package com.xzl.Request_Response;/*** @author ︶ㄣ释然* @date 2023/3/10 17:39*/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.text.MessageFormat;
import java.util.Map;/*** request 通用方式获取请求参数*/
@WebServlet("/req2")
public class req2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//GET请求逻辑System.out.println("get....");//1. 获取所有参数的Map集合Map<String, String[]> map = req.getParameterMap();for (String key : map.keySet()) {// username:XuZiLinSystem.out.print(key + ":");//获取值String[] values = map.get(key);for (String value : values) {System.out.print(value + " ");}System.out.println();}//2、获取GET请求参数中的爱好,结果是数组值System.out.println("-------------");String[] hobbies = req.getParameterValues("hobby");for (String hobby : hobbies) {System.out.println(hobby);}//3、获取GET请求参数中的用户名和密码,结果是单个值String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(MessageFormat.format("username:{0}\npassword:{1}", username, password));}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("post....");this.doGet(req,resp);}
}
3、IDEA快速创建Servlet
由于一开始创建Servlet的时候,有一些代码是固定要写的,即有固定格式,那么可以通过IDEA来设置创建模板,从而实现快速创建。[可以根据自己的需求修改模板内容]
使用Servlet模板创建模板类:
创建成功:
4、请求参数中文乱码问题
不管是GET还是POST请求,在发送的请求参数中如果有中文,在后台接收的时候,都会出现中文乱码的问题。
4.1、🔺POST请求解决方案
分析出现中文乱码的原因:
- POST的请求参数是通过request的getReader()来获取流中的数据
- TOMCAT在获取流的时候采用的编码是ISO-8859-1
- ISO-8859-1编码是不支持中文的,所以会出现乱码
解决方案:
- 页面设置的编码格式为UTF-8
- 把Tomcat在获取流数据之前的编码设置为UTF-8
- 通过request.setCharacterEncoding("UTF-8")设置编码,UTF-8也可以写成小写
重新发送POST请求,就会在控制台看到正常展示的中文结果。
至此POST请求中文乱码的问题就已经解决,但是这种方案不适用于GET请求
4.2、🔺🔺GET请求解决方案
刚才提到一个问题是POST请求的中文乱码解决方案为什么不适用GET请求?
- GET请求获取请求参数的方式是
request.getQueryString()
- POST请求获取请求参数的方式是
request.getReader()
- request.setCharacterEncoding("utf-8")是设置request处理流的编码
- getQueryString方法并没有通过流的方式获取数据
所以GET请求不能用设置编码的方式来解决中文乱码问题
如何解决GET的编码问题:
首先需要先分析下GET请求出现乱码的原因:
(1)浏览器通过HTTP协议发送请求和数据给后台服务器(Tomcat)
(2)浏览器在发送HTTP的过程中会对中文数据进行URL编码
(3)在进行URL编码的时候会采用页面<meta>标签指定的UTF-8的方式进行编码,张三编码后的结果为%E5%BC%A0%E4%B8%89
(4)后台服务器(Tomcat)接收到%E5%BC%A0%E4%B8%89后会默认按照ISO-8859-1进行URL解码
(5)由于前后编码与解码采用的格式不一样,就会导致后台获取到的数据为乱码。
补充两个知识点:
URL编码
具体编码过程分两步,分别是:
(1)将字符串按照编码方式转为二进制
(2)每个字节转为2个16进制数并在前边加上%
张三按照UTF-8的方式转换成二进制的结果为:
1110 0101 1011 1100 1010 0000 1110 0100 1011 1000 1000 1001
在Java中已经提供了编码和解码的API工具类可以让我们更快速的进行编码和解码:
编码->java.net.URLEncoder.encode("需要被编码的内容","字符集(UTF-8)")
解码->java.net.URLDecoder.decode("需要被解码的内容","字符集(UTF-8)")
接下来对张三来进行编码和解码
public class URLDemo {public static void main(String[] args) throws UnsupportedEncodingException {String username = "张三";//1. URL编码String encode = URLEncoder.encode(username, "utf-8");System.out.println(encode); //打印:%E5%BC%A0%E4%B8%89//2. URL解码//String decode = URLDecoder.decode(encode, "utf-8");//打印:张三String decode = URLDecoder.decode(encode, "ISO-8859-1");//打印:`å¼ ä¸ `System.out.println(decode);}
}
到这,我们就可以分析出GET请求中文参数出现乱码的原因了:
- 浏览器把中文参数按照
UTF-8进行URL编码
- Tomcat对获取到的内容进行了
ISO-8859-1的URL解码
- 在控制台就会出现类上
å¼ ä¸的乱码,最后一位是个空格
清楚了出现乱码的原因,接下来提出解决办法:
从上图可以看出:
- 在进行编码和解码的时候,不管使用的是哪个字符集,他们对应的
%E5%BC%A0%E4%B8%89是一致的
- 那他们对应的二进制值也是一样的,为:
1110 0101 1011 1100 1010 0000 1110 0100 1011 1000 1000 1001
- 所以可以考虑把
å¼ ä¸转换成字节,再把字节转换成张三,在转换的过程中使它们的编码一致,就可以解决中文乱码问题。
具体的实现步骤为:
1.按照ISO-8859-1编码获取乱码å¼ ä¸对应的字节数组
2.按照UTF-8编码获取字节数组对应的字符串
实现代码如下:
public class URLDemo {public static void main(String[] args) throws UnsupportedEncodingException {String username = "张三";//1. URL编码String encode = URLEncoder.encode(username, "utf-8");System.out.println(encode);//2. URL解码String decode = URLDecoder.decode(encode, "ISO-8859-1");System.out.println(decode); //此处打印的是对应的乱码数据//3. 转换为字节数据,编码byte[] bytes = decode.getBytes("ISO-8859-1");for (byte b : bytes) {System.out.print(b + " ");}//此处打印的是:-27 -68 -96 -28 -72 -119//4. 将字节数组转为字符串,解码String s = new String(bytes, "utf-8");System.out.println(s); //此处打印的是张三}
}
至此对于GET请求中文乱码的解决方案,我们就已经分析完了,最后在代码中去实现下:
/*** 中文乱码问题解决方案*/
package com.xzl.Request_Response; /*** @author ︶ㄣ释然* @date 2023/3/10 18:49*/import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;@WebServlet("/GarbledCode")
public class GarbledCode extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);username = new String(bytes,StandardCharsets.UTF_8);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}
注意
- 在doPost没有写
request.setCharacterEncoding("UTF-8")代码的情况下,会发现GET请求参数乱码解决方案同时也可也把POST请求参数乱码的问题也解决了
- 只不过对于POST请求参数一般都会比较多,采用这种方式解决乱码起来比较麻烦,所以对于POST请求还是建议使用设置编码的方式进行。
另外需要说明一点的是Tomcat8.0之后,已将GET请求乱码问题解决,设置默认的解码方式为UTF-8
5、Request请求转发
1、请求转发(forward):一种在服务器内部的资源跳转方式。
(1)浏览器发送请求给服务器,服务器中对应的资源A接收到请求
(2)资源A处理完请求后将请求发给资源B
(3)资源B处理完后将结果响应给浏览器
(4)请求从资源A到资源B的过程就叫请求转发
2、请求转发的实现方式->req.getRequestDispatcher("资源B路径").forward(req,resp);
具体如何使用:
针对上述需求,实现步骤为:
1.创建一个RequestDemo1类,接收/reqDemo1的请求
2.创建一个RequestDemo2类,接收/reqDemo2的请求
3.在RequestDemo1的方法中使用
req.getRequestDispatcher("/reqDemo2").forward(req,resp)进行请求转发
4.启动测试
具体实现:
(1)创建RequestDemo1类
(2)创建RequestDemo2类
(3)在RequestDemo1的doGet方法中进行请求转发
(4)启动测试
可以看到请求已经转发成功了
3、请求转发资源间共享数据:使用request对象
此处主要解决的问题是把请求从/reqDemo1转发到/reqDemo2的时候,如何传递数据给/reqDemo2。
需要使用request对象提供的三个方法:
- 存储数据到request域[范围,数据是存储在request对象]中:
void setAttribute(String name,Object o);
- 根据key获取值
Object getAttribute(String name);
- 根据key删除该键值对
void removeAttribute(String name);
下面是实现样例:
1.在RequestDemo1的doGet方法中转发请求之前,将数据存入request域对象中
2.在RequestDemo2的doGet方法从request域对象中获取数据,并将数据打印到控制台
3.启动访问测试
(1)修改RequestDemo1中的方法
(2)修改RequestDemo2中的方法
(3)启动测试
可以看到执行成功了。
此时就可以实现在转发多个资源之间共享数据。
4、请求转发的特点
- 浏览器地址栏路径不发生变化
虽然后台从/reqDemo1转发到/reqDemo2,但是浏览器的地址一直是/reqDemo1,未发生变化
- 只能转发到当前服务器的内部资源
不能从一个服务器通过转发访问另一台服务器
- 只能执行一次请求,可以在转发资源间使用request共享数据
相关文章:
[Java Web]Request对象 | 超1w字带你熟悉Servlet中的request请求
⭐作者介绍:大二本科网络工程专业在读,持续学习Java,输出优质文章 ⭐所属专栏:Java Web ⭐如果觉得文章写的不错,欢迎点个关注😉有写的不好的地方也欢迎指正,一同进步😁 目录 Reque…...
求一个补码表示数的原始值的三种方式
求一个补码表示数的原始值的三种方式假设 a(10010)2′complement−14a (10010)_{2complement}-14a(10010)2′complement−14 方式1,通过补码求原始值公式求值(see article) x−xM−1∗2M−1∑i0M−2xi∗2ix-x_{M-1}*2^{M-1}\sum_{i0}^{M-2…...
【计算机组成原理】
第2章 运算方法和运算器 2.1 数据与文字的表示方法 2.1.1 数据格式 定点数的表示方法 定点纯小数纯小数表示范围定点纯整数定点表示法特点 浮点数的表示方法: 浮点的规格化表示:阶码、尾数、指数、基数IEEE754标准:单精度、双精度浮点数表…...
论文分享:图像识别与隐私安全
1、基于差分隐私框架的频域下人脸识别隐私保护算法Privacy-Preserving Face Recognition with Learnable Privacy Budget in Frequency Domain2、一种基于视觉密码学和可信计算的无密钥依赖的医学图像安全隐私保护框架A Privacy Protection Framework for Medical Image Securi…...
计算机基础小结
目录 ❤ 计算机基础编程 什么是编程语言? 什么是编程? 为什么要学习编程? ❤ 计算机组成原理 控制器 运算器 储存器 内存(主存) 外存 输入设备 输出设备 适配器 总线 机械硬盘 固态硬盘 ❤ 计算机操作系统 什么是操作系统? 什么是文件? 什么是应…...
Linux服务器还有漏洞?建议使用 OpenVAS 日常检查!
几乎每天都会有新的系统漏洞产生,系统管理员经常忙于管理服务器,有时候会忽略一些很明显的安全问题。扫描 Linux 服务器以查找安全问题并不是很简单的事情,所以有时候需要借助于一些专门的工具。 OpenVAS 就是这样一种开源工具,它…...
【Redis】P1 Redis - NoSQL
Redis - NoSQLSQL 与 NoSQL差别一:结构化 与 非结构化差别二:关联性 与 非关联性差别三:规范化查询语句 与 非规范化差别四:事务 与 无事务差别五:磁盘存储 与 内存存储RedisRedis 的安装当前数据库存储主要分为 关系型…...
Angular学习之ControlValueAccessor接口详解
ControlValueAccessor 是什么?为什么需要使用 ?下面本篇文章就来带大家了解Angular中的ControlValueAccessor组件接口,希望对大家有所帮助! ControlValueAccessor 是什么? 简单来说ControlValueAccessor是一个接口&am…...
【GORM】高级查询方案
【GORM】高级查询方案1.Struct & Map查询为空的情况2.FirstOrInit3.FirstOrCreate4.高级查询1.Struct & Map查询为空的情况 当通过结构体进行查询时,GORM将会只通过非零值字段查询,这意味着如果你的字段值为0,‘’,false…...
MFC 简单使用事件
功能三个按钮,一个静态框,默认值是0,增加减少按钮和退出按钮.增加减少按钮显示在静态框中.退出按钮退出软件.实验事件思路新建三个事件,add事件sub事件quit事件,一个按钮触发一个事件,静态框新建一个线程接受事件做出对应的改变.UI添加的代码就不具体说,具体说下事件的代码,这才…...
华为OD机试题 - 端口合并(JavaScript)| 机考必刷
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:端口合并题目输入输出示例一输入输出说明示例二输入输出说明示例…...
ECharts数据可视化--常用图表类型
目录 一.柱状图 1.基本柱状图 1.1最简单的柱状图 编辑 1.2多系列柱状图 1.3柱状图的样式 (1)柱条样式 (2)柱条的宽度和高度 (3)柱条间距 (4)为柱条添加背景颜色 编辑 2.堆…...
Flutter面试题解析-GridView详解与应用
一、前言Flutter 作为时下最流行的技术之一,凭借其出色的性能以及抹平多端的差异优势,早已引起大批技术爱好者的关注,甚至一些 闲鱼 , 美团 , 腾讯 等大公司均已投入生产使用。虽然目前其生态还没有完全成熟࿰…...
最全的论文写作技巧(建议收藏)
近10年来,笔者有幸多次参与教学论文的评审工作,在此,特将教学论文写作的步骤及相关问题整理汇总如下: 一、选定论题 (一)论题在文中的地位与作用 严格地讲,论文写作是从选定论题开始的。选题…...
面向对象设计模式:设计模式分类(创建型、行为型、结构型)
1. 创建型设计模式 单例模式:https://blog.csdn.net/qq_44992559/article/details/129348686工厂模式:https://blog.csdn.net/qq_44992559/article/details/115222311抽象工厂模式:https://blog.csdn.net/qq_44992559/article/details/12934…...
MySQL数据库迁移
考试系统的数据库一直是在我自己的服务器上面的, 但是最近,自己的服务器马上要过期了,里面的MySQL数据需要迁移出来,放在另外一个服务器上面。百度了几篇教程,也没研究太多,选了一种比较简单的方式进行迁移…...
Docker:关于 Dockerfile 编写优化的一些笔记整理
写在前面 分享一些 Dickerfile 构建镜像优化方式的笔记理解不足小伙伴帮忙指正 对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式&#…...
个性化营销:您需要知道的信息
个性化营销在现代企业中风靡一时。我们将剖析您需要了解的有关个性化营销的信息,一起来了解一下吧。 什么是个性化营销? 个性化营销是一种一对一营销形式,它使用实时用户数据和分析来传递品牌信息并针对特定潜在客户。 它与传统营销不同&…...
栈和队列的相互实现
文章目录一、用栈实现队列入队:出队:Java代码实现:二、用队列实现栈入栈:出栈:Java代码实现:附:C版代码1、用栈实现队列2、用队列实现栈栈(stack):先进后出&a…...
iTab新标签页重磅更新 |这些功能绝对有你想要的新体验!
01 写在前面 csdn的朋友们,你好哦,我是iTab 插件的独立开发者,今天给大家安利一下我做的这款桌面插件。 首先要告诉大家一个好消息: 最近iTab新标签页被Edge 浏览器商店官方热门🔥推荐啦。 在此,特别感谢…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
React核心概念:State是什么?如何用useState管理组件自己的数据?
系列回顾: 在上一篇《React入门第一步》中,我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目,并修改了App.jsx组件,让页面显示出我们想要的文字。但是,那个页面是“死”的,它只是静态…...
使用 uv 工具快速部署并管理 vLLM 推理环境
uv:现代 Python 项目管理的高效助手 uv:Rust 驱动的 Python 包管理新时代 在部署大语言模型(LLM)推理服务时,vLLM 是一个备受关注的方案,具备高吞吐、低延迟和对 OpenAI API 的良好兼容性。为了提高部署效…...
