学习方向
-
快速学习数据库软件navicat、Sqlyog的安装,掌握数据库基本的增删改查语法
-
数据库管理软件:
navicat
- 官方下载地址:https://www.navicat.com.cn/products
- https://www.bilibili.com/video/BV1JK411V7bQ
Sqlyog
- 官方下载地址:https://sqlyog.en.softonic.com/
-
-
IDEA散记:
调用方法之后,在末尾写.var可以自动添加返回值类型和返回值变量,方便快捷编码
-
javaEE7帮助文档:https://gitee.com/Kevin_Hunter/picgo/tree/master/
-
快速学习服务器软件tomcat的安装和项目部署,连接IDEA
-
软件架构
B/S 浏览器/服务器
C/S 客户端/服务器 -
服务器软件:
tomcat
:- 官方下载地址:https://tomcat.apache.org/ 下载压缩包解压到目录即可完成安装
-
Servlet快速入门
-
浏览器访问服务器:
- 常规浏览器搜索框直接访问服务器是Get请求,url会携带参数
<form>
表单形式指定method="post"
可以发送post请求,参数会存放在请求体(正文)
中
-
MarkDown编辑软件:
Typora
的下载地址:https://www.typora.io/
-
图片管理软件:
-
PicGo
下载地址:https://github.com/Molunerfinn/PicGo/releases/tag/v2.3.0 -
搭配
Gitee
配置云图库教程:https://blog.csdn.net/qq_40683225/article/details/105124810 -
配置步骤:
-
-
设置Typora:
-
-
-
下载gitee图片上传插件(搜索gitee):
-
-
-
在PicGo中设置gitee:
-
-
-
Servlet
一、概念:
全称 sever applet
, 运行在服务器端的小程序
Servlet就是一个接口,定义了java类被浏览器访问到(tomcat识别)的规则
将来自定义一个类,实现Servlet接口,复写方法实现功能
二、Servlet快速入门
:
1.创建JavaEE项目
2.定义一个类,实现Servlet接口
3.实现接口中的抽象方法
4.配置Servlet
三、Servlet执行原理
:
- 当服务器接受客户端浏览器的请求之后,会解析请求URL路径,获取访问的
Servlet
的资源路径- 查找web.xml文件,看是否有对应的
<url-patton>
的标签体内容- 如果有,则再查找到对应的
<servlet - class>
全类名- tomcat会将字节码文件加载进内存,并且创建其对象
- 再调用类中的方法
四、Servlet的生命周期
:
常用:
1. 被创建:
执行init()
方法,只执行一次,一般用于加载资源
要点:Servlet方法什么时候被创建?
默认情况下,第一次被访问时,Servlet被创建
但是可以通过配置,来控制Servlet被创建的时机
-
配置方法
:
在web.xml文件下的<servlet></servlet>
标签中配置
(1).当<load-on-startup></load-on-startup>
标签中的值为负数时(默认),第一次被访问时,Servlet对象被创建
(2).当<load-on-startup></load-on-startup>
标签中的值为0或者正整数时,服务器启动时i,Servlet对象被创建 -
注意事项
:
Servlet的init方法只被调用一次,说明只有一个Servlet在内存中只存在一个对象,Servlet是单例的
多个用户同时访问时,可能存在线程安全问题 -
解决方法
:
尽量不要在Servlet中定义成员变量,即是定义了,也不要修改成员变量,可以定义方法中的临时局部变量,以此避免并发数据安全问题
2. 提供服务:
执行server方法,每次调用都执行一次
每次访问Servlet时,server方法都会被执行一次
3. 被销毁:
执行destroy方法,只执行一次
Servlet被销毁时执行。服务器关闭时,Servlet会被销毁
只有服务器正常关闭时,才会执行destroy()
方法
destroy()
方法在Servlet销毁前被执行,一般用户释放资源
不常用:
1.getServletConfig()
方法:
用于获取ServletConfig
对象
方法返回值为:ServletConfig
(Servlet的配置对象)
2.getServletInfo()
方法:
用于获取Servlet的一些版本、作者等信息
方法返回值为:String
(Servlet的版本信息)
五、Servlet的体系结构
:
一、父子接口关系
Servlet
— 接口
| 继承
GenericSeverlet
– -抽象类,继承了Servlet类
| 继承
HttpServlet
—抽象类,继承了GenericServlet类
-
GenericServlet : 将Servlet接口中其他的方法做了默认空实现,只将常用的
server()
方法作为抽象将来定义Servlet类时,可以继承GeneriServlet类,直接实现
service()
方法即可 -
HttpServlet : 对浏览器访问服务器的请求方式进行了判断的封装,如果是
GET
请求,则调用doGet()
方法;如果是POST
请求,则调用doPost()
方法将来定义Servlet类时,可以继承HttpServlet类,只需要复写
doGet()
或者doPost()
方法即可
二、Servlet3.0注解配置
:
urlpartten: Servlet访问路径
一个Servlet可以有多个访问路径:@WebServlet({"/虚拟路径1", “虚拟路径2”,“虚拟路径3”}),可以由多个路径进行访问
三、路径定义规则:
/xxx: 路径匹配(常规)
/xxx/xxx/xxx: 多层路径,虚拟路径,目录结构
*号代表任意,前面不加/号,否则报错
例如:
①. @WebServlet("/demo/*")
服务器访问url: `localhost/demo/任意路径
②. WebServlet(/*)
服务器访问url;localhost/任意路径
访问的优先级别最低,如果能访问到其他资源,则不会访问此路径的资源
③. @WebServlet("*.do")
服务器访问url:localhost/任意路径.do
do为拓展名,可自定义
HTTP
一、概念:
Hyper Text Tranfer Protocol 超文本传输协议
HTTP请求总共有7
种方式,常用的有GET
请求和POST
请求
-
GET请求:
- 请求参数在请求的请求行中 在url后
- 请求的url长度有限制(文件传输较大,长度超过限制)
- 相对不安全
-
POST请求:
- 请求参数在请求体中
- 请求的url长度没有限制(可用于文件传输)
- 相对安全
二、传输协议 :
定义了客户端和服务端通信时,发送数据的格式
三、特点 :
-
基于TCP/IP 的高级协议
-
默认端口号为 :
80
-
基于请求/响应模型的:一次请求,一次响应
-
无状态的:请求与请求之间是相互独立的,不能交互数据
四、历史版本:
版本1.0(每一次请求,响应都会建立一次连接)
版本1.1 (可以复用连接,多次请求响应,同用一次连接)
五、请求消息格式
1、请求行
-
请求方式 请求url 请求协议/版本
GET /localhost/login.html HTTP/1.1
2、请求头
-
请求头名称 :请求头值(值如果有多个,可以用逗号隔开)
-
常见的请求头
User-Agent
: 携带浏览器的版本信息,服务器可以通过获取浏览器的版本信息,解决浏览器数据兼容性问题Accept
: 浏览器可以响应的文件格式Accept-Language
:浏览器支持的语言Accept-Encoding
:浏览器支持的压缩格式- `Reffer(重要)``
- ``Connection`:标识连接是否还在
Upgrade-Insecure-Requests
:升级信息
-
请求头中的
Reffer
:http:/localhost/login.html-
作用:告诉服务器,当前请求从哪里来
-
防止盗链
-
统计工作
-
-
3、请求空行
- 空行(用于分隔请求头和请求体)
4、请求体
只有当请求方式为POST时才有请求体
,GET方式没有请求体
- 参数名1=参数值1&参数名2=参数值2&…
5、请求数据示例:
POST /login.html HTTP/1.1 //1.请求行
/*2.请求头开始*/
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://localhost/login.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1
/*请求头结束*/
//3.请求空行
username=zhangsan //4.请求体
六、响应消息格式
1. 概念:
- 请求响应流程:
1.浏览器发送请求之后,tomcat服务器会根据请求url中的资源路径,创建对应的Servlet类的对象
2.tomcat服务器还会将请求数据封装成对象,创造request对象和response对象,
request对象
封装了请求中的消息数据3.tomcat将request对象和response对象传给
service()方法
,并且调用service()方法4.程序员则可以在service()方法中通过request对象获取请求的消息数据,再通过response对象设置响应消息数据
5.服务器在给浏览器做出响应之前,会从response对象中解析程序员写的response对象中的响应消息数据
2.知识点:
1、request对象和response对象的原理
- resquest对象和resopnse对象是由服务器创建的,我们只是使用它们
- resquest对象是用来获取请求消息,response对象是用来设置响应消息
2、request对象的继承体系结构:
ServletRequest --接口
| 继承
HttpServletRequest —接口
| 继承
org.apache.catalina.connector.RequestFacade@17d6087b 类(tomcat的开源的类)
- Servlet类中的service()方法中有
ServletRequest对象
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
-
HttpServlet类中的doGet()方法和doPost()方法中有
HttpServletRequest对象
打印出HttpServletRequest对象的值:
org.apache.catalina.connector.RequestFacade@17d6087b
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
}
}
3、request的功能:
获取请求消息数据:
①、获取请求行数据:
-
GET /localhost/login.html?userName=zhangsan HTTP/1.1
- 请求方式 主机地址/虚拟路径/Servlet类的路径?参数
-
方法:
-
1. 获取请求的方式:
GET
String getMethod()
-
*2. (重要)获取虚拟目录:/
String getContextPath()
-
3. 获取Servlet路径:/login.html
String getServletPath()
-
4. 获取请求参数:userName=zhangsan
String getQueryString()
-
*5. (重要)获取请求
URI
:/login.htmlString getRequestURI()
- 统一资源标识符(范围相对较大,限制相对较少)
-
6. 获取请求
URL
: http:localhost/login.htmlStringBuffer getRequestURL()
- 统一资源定位符
-
7. 获取协议及版本:HTTP/1.1
String getProtocol()
-
8. 获取客户机的IP地址:
String getRemodeAttr()
代码示例:
-
浏览器中访问的地址:http://localhost/demo4
@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.获取请求的方式
String method = req.getMethod();
// 2.获取请求的虚拟路径
String contextPath = req.getContextPath();
// 3.获取请求的Servlet路径
String servletPath = req.getServletPath();
// 4.获取请求的参数
String queryString = req.getQueryString();
// 5.获取请求的URI
String uri = req.getRequestURI();
// 6.获取请求的URL
StringBuffer url = req.getRequestURL();
// 7.获取请求的协议和版本
String tip = req.getProtocol();
// 8.获取主机地址
String addr = req.getRemoteAddr();
// 打印
System.out.println("请求方式-->" + method);
System.out.println("虚拟路径-->" + contextPath);
System.out.println("请求参数-->" + queryString);
System.out.println("URI-->" + uri);
System.out.println("URL-->" + url);
System.out.println("版本协议-->" + tip);
System.out.println("主机地址-->" + addr);
}
}
输出:
请求方式-->GET
虚拟路径-->
请求参数-->null
URI-->/demo4
URL-->http://localhost/demo4
版本协议-->HTTP/1.1
主机地址-->0:0:0:0:0:0:0:1
②、获取请求头数据:
-
方法:
-
(*常用*)String getHeader(String name)
:通过请求头的名称获取请求头的值 -
Enumeration<String> req.getHeaderNames()
:获取请求头信息的类(接口)类中定义了两个方法:
hasMoreElements()
:检测此枚举对象是否有更多元素nextElement()
:如果此枚举对象至少有一个要提供的元素,则返回此枚举的下一个元素
代码示例:
@WebServlet("/demo3") public class ServletDemo3 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取所有请求头的名称 Enumeration<String> headerNames = req.getHeaderNames(); System.out.println("请求头中所有请求头的名称-->" + headerNames); // 遍历所有请求头 while (headerNames.hasMoreElements()) { // 获取一个请求头的名称 String headerName = headerNames.nextElement(); // 根据请求头的名称获取请求头的值 String headerValue = req.getHeader(headerName); // 打印请求头的名称和请求头的值 System.out.println("请求头 " + headerName + " 的值为 " + headerValue); } } }
输出: 请求头中所有请求头的名称-->org.apache.tomcat.util.http.NamesEnumerator@676a55e8 请求头 host 的值为 localhost 请求头 connection 的值为 keep-alive 请求头 sec-ch-ua 的值为 "Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99" 请求头 sec-ch-ua-mobile 的值为 ?0 请求头 sec-ch-ua-platform 的值为 "Windows" 请求头 upgrade-insecure-requests 的值为 1 请求头 user-agent 的值为 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36 请求头 accept 的值为 text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 请求头 sec-fetch-site 的值为 none 请求头 sec-fetch-mode 的值为 navigate 请求头 sec-fetch-user 的值为 ?1 请求头 sec-fetch-dest 的值为 document 请求头 accept-encoding 的值为 gzip, deflate, br 请求头 accept-language 的值为 zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6 请求头 cookie 的值为 JSESSIONID=4605D1FB1B7640954F8E9C9585201EF9
-
-
较常用法:
- 根据版本信息在代码中判断再进行逻辑编写,以此解决浏览器兼容性问题
- 获取请求头中的
reffer
数据,标识当前请求从哪个链接发出,如果从浏览器中直接输入发送的请求,则返回值为null
@WebServlet("/demo5") public class ServletDemo5 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String reffer = req.getHeader("reffer"); System.out.println("请求从哪里发出-->"+reffer); } }
浏览器输入:http://localhost/demo5 发送请求
以下代码输出:请求从哪里发出–>null
reffer作用(
防盗链
):https://segmentfault.com/a/1190000024540592
③、获取请求体(正文)数据:
-
请求体
:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数 -
步骤
:-
-
获取流对象
-
获取字符输入流:
BufferedReader getReader()
方法 获取字符输入流,只能操作字符 -
获取字节输入流:
ServletInputStream()方法
获取字节输入流,可以操作所有类型数据(主要用于文件上传
)
-
-
再从流对象中拿数据
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("post"); // 获取请求消息体 // 1.获取字符流 BufferedReader reqReader = req.getReader(); // 2.读取数据 String line = null; while((line = reqReader.readLine()) != null){ System.out.println(line); } }
点击注册后服务器端输出: post username=Kevin&password=123
-
-
其他功能:
①、获取请求参数的通用方式:
由于
GET
请求的参数在url中,并且其请求体中没有参数,所有只能通过req.getQueryString()
方法获取参数字符串,而POST
请求的参数在请求体中,一般是通过req.getReader()
方法获取参数字符串的,所有存在不统一的问题,以下几个方法在GET和POST请求中通用,都可以获取到参数的值,更为常用
String getParameter(String name)
: 根据参数名称获取参数值 username=Kevin&password=123Enumeration<String> getParameterNames(String name)
:获取所有参数的名称String[] getParameterValues(String name)
:根据参数名称获取参数值的数组 hobby=xx&hobby=yyMap<String, String[]> getParameterMap()
:获取所有参数的map集合
@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置流的编码
req.setCharacterEncoding("utf-8");
// System.out.println("post");
获取单个参数的值(字符串)
// String username = req.getParameter("username");
// System.out.println("用户名-->"+username);
// 根据参数名称获取参数值的数组
// String[] values = req.getParameterValues("hobby");
// for(String item:values){//遍历数组
// System.out.println(item);//输出每一项的值
// }
// 获取所有参数的名称
// Enumeration<String> parameterNames = req.getParameterNames();
// while(parameterNames.hasMoreElements()){
// String item = parameterNames.nextElement();
// System.out.println(item);
// String value = req.getParameter(item);
// System.out.println(value);
// System.out.println("-----------------");
// }
// 获取所有参数的map集合(泛型)
Map<String, String[]> parameterMap = req.getParameterMap();
Set<String> keyset = parameterMap.keySet();
for (String name : keyset) {
// 根据键来获取值
String[] values = parameterMap.get(name);
System.out.println(name);
for (String value : values) {
System.out.println(value);
}
System.out.println("----------------");
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// System.out.println("get");
// String username = req.getParameter("username");
// System.out.println("用户名-->" + username);
this.doPost(req, resp);//逻辑通用,简化代码
}
}
- 请求参数的中文乱码问题:
GET
请求方式中,tomcat已经将get方式的中文乱码问题解决了
POST
请求方式中,参数中如果有中文,则会出现乱码问题
//解决:在获取参数前,设置request的编码格式
// 设置流的编码
req.setCharacterEncoding("utf-8");
②、请求转发:
1. 概念:
- 一种在服务器内部资源跳转的方式
2.步骤:
- 通过request对象获取请求转发器对象,
RequestDispatcher getRequestDispatcher(String path)
- 使用RequestDispatcher对象进行转发:
forward(HttpServletRequest req, HttpServletResponse resp)
常用写法:
req.getRequestDispatcher("/demo9").forward(req, resp);
3.特点:
- 转发时,浏览器地址栏路径不发生变化
- 只能转发到当前服务器内部的资源中
- 转发虽然有资源跳转,但只是一次请求
③、共享数据:
-
域对象:一个有作用范围的对象,可以在范围内共享数据
-
request域,代表一次请求的范围,一般用于请求转发的多个资源中数据共享
-
方法:(在转发之前将数据存储到request域中,转发之后在新的类中获取数据)
-
void setAttribute(String name, Object obj)
:存储数据 -
Object getAttribute(String name, Object obj)
:获取数据 -
void removeAttribute(String name)
:通过键移除键值对
-