1.关于系统架构
1.1系统架构包括
C/S架构:
Client/Server(客户端/服务器)
例如电脑上安装的各种软件,qq等,需要安装特定的软件
优点:
- 速度快(软件中数据大部分在客户端中,少量的数据在服务端获取)
- 体验好(界面炫酷)
- 服务器压力小
- 安全(大量的数据集中在客户端中,就算服务器因为某种原因受损,客户端也存在大量的数据)
缺点:
- 升级维护困难,每一个客户端都需要升级,特别是有些软件不好安装。
B/S 架构
浏览器/服务器
实际上B/S就是一个特殊的C/S,这个客户端是一个固定不变的浏览器,通过浏览器访问。4
优点:
- 升级维护方便,成本比较低(只需要升级服务器就可以了)
- 不需要安装特定的客户端,直接通过网址访问就行
缺点:
- 速度慢(不是因为带宽的问题,所有的数据都在服务器上。)
- 体验差(界面不会很炫酷,因为网页只支持html,JAVASCRIPT,css)
- 不安全(如果服务器炸了,数据全部丢失)
两种架构哪个好
一般的娱乐软件,适用于C/S架构,比较炫酷
公司内部的业务或者各种管理系统等适用于B/S架构
公司内部的系统需要维护成本比较低
1.2 javaEE是什么
javaSE:java标准版,是一套别人写好的类库,是另外两个的基础
javaEE:java企业版,是一套可以帮助我们完成企业级项目开发,专门为企业内部提供解决方案的一套或多套类库
javaME:java微型版,一套用于机顶盒,吸尘器等等的内核程序
1.3.B/S架构的通信原理
web访问过程
关于域名:
https://www.baidu.com/(网址)
www.baidu.com 是一个域名
。在浏览器地址栏上输入域名,回车之后,域名解析器会将域名解析出来一个具体的iP地址和端口号等。
。解析结果也许是:http://110.242.68.3:80/index.htmll
ip地址是啥?
。计算机在网络当中的一个身份证号。在同一个网络当中,P地址是唯一的。
。A计算机要想和B计算机通信,首先你需要知道B计算机的IP地址,有了IP地址才能建立连接。
端口号是啥?
。一个端口代表一个软件(一个端口代表一个应用,一个端口仅代表一个服务)
。一个计算机当中有很多软件,每一个软件启动之后都有一个端口号。
。在同一个计算机上,端口号具有唯一性。
一个WEB系统的通信原理?通信步骤:
。第一步:用户输入网址(URL)
。第二步:域名解析器进行域名解析:
什么是URL?
。统一资源定位符(http://www.baidu.com)
简单来说:输入网址,域名解析成ip,然后找到服务器返回一个html,然后试图解析器直接解析。
1.4关于web服务器软件
• WEB服务器软件都有哪些呢?
Tomcat(WEB服务器)
jetty(WEB服务器)
BOSS(应用服务器)
WebLogic(应用服务器)。
Websphere(应用服务器)应用服务器
WEB服务器的关系?
。应用服务器实现了lavaEE的所有规范。(lavaEE有13个不同的规范。)
。WEB服务器只实现了lavaEE中的Servlet +JSP两个核心的规范。
。通过这个讲解说明了:应用服务器是包含WEB服务器的。
。用过IBOSS服务器的同学应该很清楚,JBOSS中内嵌了一个Tomcat服务器。
tomcat下载
tomcat开源免费的轻量级WEB服务器.
tomcat还有另外一个名字:gatalina(catalina是美国的一个岛屿,风景秀丽,据说作者是在这个风景秀丽的小岛上开发了一个轻量级的WEB服务器,体积小,运行速度快,因此tomcat又被称为gatalina)
tomcat的logo是一只公猫(寓意表示Tomcat服务器是轻巧的,小巧的,果然,体积小,运行速度快,只实现了Servlet+lSP规范)
tomcat是java语言写的。
tomcat服务器要想运行,必须先有jre(Java的运行时环境)
启动tomcat
xxx.bat文件是windows操作系统使用的,这种文件中存放的是大量的dos命令。
xxx.sh文件是linux操作系统使用的,存放大量的shell命令
tomcat的bin目录下存放两者,说明tomcat的兼容性
tomcat服务器执行通过startup.bat,分析源码发现,main方法最后执行的是CATALINA.bat文件
所以启动tomcat需要环境变量
JAVA_HOME=IDK的根
还有一个tomcat服务器的bin
CATALINA_HOME=Tomcat服务器的根
关于Tomcat服务器的目录
- bin:这个目录是Tomcat服务器的命令文件存放的目录,比如:启动Tomcat,关闭Tomcat等
- conf:这个目录是Tomcat服务器的配置文件存放目录。(server.xml文件中可以配置端口号,默认Tomcat端口是8080)o
- lib :这个目录是Tomcat服务器的核心程序目录,因为Tomcat服务器是Java 语言编写的,这里的jar包里面都是class文件。
- logs:Tomcat服务器的日志目录,Tomcat服务器启动等信息都会在这个目录下生成日志文件。
- temp:Tomcat服务器的临时目录。存储临时文件。
- webapps:这个目录当中就是用来存放大量的webapp(web application:web应用,我们使用idea打包到tomcat的项目就在这个目录下)
- work:这个目录是用来存放ISP文件翻译之后的java文件以及编译之后的class文件。
2.Servlet
2.1模拟servlet和tomcat
需要,三个集成servlet的类,一个servlet(就写了一个方法),一个tomcat,一个配置文件
public class Tomcat {
public static void main(String[] args) throws Exception{
System.out.println("请输入url地址");
Scanner url=new Scanner(System.in);
String key=url.nextLine();
FileReader r=new FileReader("src\\test\\java\\Tomcat_servlet\\data.properties");
Properties p=new Properties();
p.load(r);
String classpath=p.getProperty(key);
Class c=Class.forName(classpath);
Servlet s= (Servlet) c.newInstance();
s.move();
//tomcat作用就是获取web端传递过来的url地址,然后通过寻找配置文件指定执行的方法,所以tomcat连接浏览器和webapp
}
}
public class method2 implements Servlet {
@Override
public void move() {
System.out.println("method2");
}
}
/aaa=Tomcat_servlet.method1
/bbb=Tomcat_servlet.method2
/ccc=Tomcat_servlet.method3
通过我们的分析:
- 对于我们javaweb程序员来说,我们只需要做两件事:
- 编写一个类实现Servlet接口。
将编写的类配置到配置文件中,在配置文件中:指定 请求路径=类名的关系。
注意:
- 这个配置文件的文件名不能乱来。固定的。
- 这个配置文件的存放路径不能乱来。固定的。
- 文件名、文件路径都是SUN公司制定的Servlet规范中的明细。
严格意义上来说Servlet其实并不是简单的一个接口:
Servlet规范中规定了:
- 一个合格的webapp应该是一个怎样的目录结构。
- 一个合格的webapp应该有一个怎样的配置文件。
- 一个合格的webapp配置文件路径放在哪里。
- 一个合格的webapp中java程序放在哪里。
这些都是Servlet规范中规定的。
Tomcat服务器要遵循Servlet规范。JavaWEB程序员也要遵循这个Servlet规范。这样Tomcat服务器和webapp才能解耦合。
2.2开发一个带有servlet的webapp
第一步:在webapps目录下新建一个目录,起名crm(这个crm就是webapp的名字)。
第二步:在webapp的根下新建一个目录:WEB-INP 注意:这个目录的名字是Servlet规范中规定的,必须全部大写,必须一模一样。必须的必须。
第三步:在WEB-INF目录下新建一个目录:classes 注意:这个目录的名字必须是全部小写的classes。这也是Servlet规范中规定的。另外这个目录下一定存放的是Java程序编译之后的class文件(这里存放的是字节码文件)。
第四步:在WEB-INF目录下新建一个目录:lib
注意:这个目录不是必须的。用于存放第三方的jar包,比如数据库驱动
第五步:在WEB-INF目录下新建一个文件:web.xml
注意:这个文件是必须的,这个文件名必须叫做web.xml。在这个配置文件中描述了请求路径和Servlet类之间的对照关系。
第六步:编写一个Java程序,这个小ava程序也不能随意开发,这个小java程序必须实现Servlet接口。·
这个Servilet接口不在JDK当中。(在javaEE中,所以需要引入环境变量使用其他的库)
Servlet接口(Servlet.class文件)是Oracle提供的。(最原始的是sun公司提供的。)
Servlet接口是JavaEE的规范中的一员。
Tomcat服务器实现了Servlet规范,所以Tomcat服务器也需要使用Servlet接口。Tomcat服务器中应该有这个接口,Tomcat服务器的CATALINA_HOME\lib目录下有一个servlet-api.jar,解压这个servlet-api.jar之后,你会看到里面有一个Servlet.class文件。
public class HelloServlet implements Servlet{
//5个方法
public void init(ServletConfig config) throws ServletException{
}
public void service(ServletRequest request,ServletResponse response)
throws ServletException , IOException{
}
public void destroy(){
}
public String getServletInfo(){
return"";
}
public ServletConfig getServletConfig(){
return null;
}
第七步:编译我们编写的HelloServlet(因为servlet的包不在jdk,不能直接使用)
重点:你怎么能让你的HelloServlet编译通过呢?配置环境变量CLASSPATH
CLASSPATH=.;C:\dev\apache-tomcat-10.0.12\lib\servlet-api.jar
第八步:将以上编译之后的HelloServlet.class文件拷贝到WEB-INF\classes目录下。
第九步:在web.xml文件中编写配置信息,让“请求路径“和"Servlet类名“关联在一起。
这一步用专业术语描述:在web.xm!文件中注册Servlet类。(然后就可以在网页使用该路径访问了url-pattern)
实例
<form action="servlet_test1" method="post">
<table>
<tr><td>姓名<input name="username" type="text"></td></tr>
<tr><td>密码<input name="password" type="password"></td></tr>
<tr><td><button type="submit">aaaa</button></td></tr>
</table>
</form>
//前端
<servlet>
<servlet-name>Test1</servlet-name>
<servlet-class>com.Servlet.Test1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Test1</servlet-name>
<url-pattern>/servlet_test1</url-pattern>
</servlet-mapping>
//servlet注册
class AdapteServlet implements Servlet
//直接使用类来实现servlet就行,然后有五个方法,在service里写方法就行
数据库代码
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
servletResponse.setContentType("text/html");
Connection conn=null;
PreparedStatement p=null;
ResultSet rs=null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url="jdbc:mysql://localhost3306/database";
String username="root";
String password="root";
conn= DriverManager.getConnection(url,username,password);
String sql="select * from user";
p=conn.prepareStatement(sql);
rs=p.executeQuery();
while (rs.next()){
String user= rs.getString("ziduan");
String psw=rs.getString("psw");
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
2.3servlet的生命周期
servlet有五个方法
tomcat在创建setvlet对象之前会通过反射机制创建对象,这个对象是调用的无参数构造方法
,这里不要自己单独写一个有参数的构造方法,不然会报错
public class test implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}//初始化方法,首先tomcat会创建servlet对象(调用无参数的构造方法),然后就会调用这个初始化方法
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}//servlet被访问的时候执行的方法
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}//在销毁之前执行的方法,关闭tomcat之前
}
<load-on-startup>1</load-on-startup>决定了servlet的优先级,数字越小优先级越大
适配器设计模式
这样的话每次实现servlet都需要重写五个方法,只需要一个service方法,这样就会很麻烦。
所以可以编写一个抽象类来当做适配器。简化代码,将需要的方法变成抽象方法
public abstract class AdapteServlet implements Servlet {
private ServletConfig config;
//在tomcat中会自己创建一个这样的对象,然后当做
//初始化方法的参数,我想要将这个对象取出来。就可以这样
public ServletConfig getConfig(){
return this.config;
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
this.config=servletConfig;
}//将对象赋值给定义的值,然后使用一个get获取,这样子类就可以直接获取这个值。
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException ;
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
这种获取对象的方式会使用到init方法,如果子类重写init方法就导致获取不到这个值。
所以需要在该方法上加上final关键字,但是这个时候我又需要重写该方法,所以就可以在该方法中在调用另一个init用来重写
@Override
public final void init(ServletConfig servletConfig) throws ServletException {
this.config=servletConfig;
this.init();
}
public void init(){
}
这个适配器别人已经写好了叫GenericServlet(用于简化Servlet接口)
一般使用servlet的时候我们使用HttpServlet,这个是GenericServlet的子类,使用更加方便。
ServletConfig对象
什么是ServletConfig?
- Servlet对象的配置信息对象。
- ServletConfig对象中封装了<servlet></servlet>标签中的配置信息。(web.xml文件中servlet的配置信息)
一个Servlet对应—个ServletConfig对象。
Servlet对象是Tomcat服务器创建,并且ServletConfig对象也是Tomcat服务器创建。并且默认情况下,他们都是在用户发送第一次请求的时候创建。
Tomcat服务器调用Servlet对象的init方法的时候需要传一个ServletConfig对象的参数给init方法。
ServletConfig接口的实现类是Tomcat服务器给实现的。(Tomcat服务器说的就是WEB服务器。)
ServletConfig接口有哪些常用的方法?
- public string getInitparameter(string name);// 通过初始化参数的name获取
- value public Enumeration<string> getInitparameterNames();// 获取所有的初始化参数的
- name public ServletContext getservletContext();// 获取ServletContext对象
- public String getServletName(); // 获取Servlet的name
以上方法在Servlet类当中,都可以使用this去调用。因为GenericServlet实现了ServletConfig接口。
Servlet的配置信息对象
在直接继承GenericServlet类的时候,可以获取到改对象
然后通过里面存在的方法获取servlet的配置信息
<servlet>
<servlet-name>Test2</servlet-name>
<servlet-class>com.Servlet.ConfigMethod1</servlet-class>
<!-- 初始化信息-->
<init-param>
<param-name>key1</param-name>
<param-value>value1</param-value>
</init-param>
<init-param>
<param-name>key2</param-name>
<param-value>value2</param-value>
</init-param>
<init-param>
<param-name>key3</param-name>
<param-value>value3</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Test2</servlet-name>
<url-pattern>/servlet_test2</url-pattern>
</servlet-mapping>
使用获取的config对象来获取servlet的配置信息
@Override
public void service(ServletRequest servletRequest, ServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
//先指定返回值的格式
PrintWriter out=response.getWriter();
//创建打印到网页的流
ServletConfig config=this.getServletConfig();
//获取config对象
out.println(config.getServletName()+"</br>");
//获取配置servlet注册的id
Enumeration<String> list=config.getInitParameterNames();
//使用getInitParameterNames获取所有初始化信息的key
while (list.hasMoreElements()){
String key=list.nextElement();
//遍历取出key
String value=config.getInitParameter(key);
//通过key取出value
System.out.println(key+" "+value);
//输出到控制台
out.println(key+" "+value);
//输出到网页
out.println("</br>");
}
// String initname=config.getServletName();单个初始化信息的时候使用
// String initvalue=config.getInitParameter(initname);
}
直接使用父类的方法来获取信息
public void service(ServletRequest servletRequest, ServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
//先指定返回值的格式
PrintWriter out=response.getWriter();
//创建打印到网页的流
Enumeration<String> list=this.getInitParameterNames();
while (list.hasMoreElements()){
String key=list.nextElement();
System.out.println(key+" "+this.getInitParameter(key));
out.println(key+" "+this.getInitParameter(key));
}
}
ServletContext
ServletContext是一个接口,Tomcat服务器对ServletContext接口进行了实现。
SerletContext对象的创建也是Tomcat服务器来完成的。启动webapp的时候创建的。
ServletContext接口中有哪些常用的方法?
- public string getInitparameter (String name);// 通过初始化参数的name获取value
- public Enumeration<String>getInitparameterNames ();// 获取所有的初始化参数的name
<!--以上两个方法是servletContext对象的方法,这个方法获取的是什么信息?是以下的配置信息-->
<context-param>
<param-name>pagesize</par am-name><param-value>10</param-value></context-par am>
<context-param>
<param-name>startIndex</param-name>
<param-value>0</param-value>
</context-param>
<!--注意:以上的配置信息属于应用级的配置信息,一般一个项目中共享的配置信息会放到以上的标签当中。-->
<!--如果你的配置信息只是想给某一个servlet作为参考,那么你配置到servlet标签当中即可,使用servletConfig对象来获取。-->
// 获取应用的根路径(非常重要),因为在java源代码当中有一些地方可能会需要应用的根路径,这个方法可以动态获取应用的根路径
// 在java源码当中,不要将应用的根路径写死,因为你永远都不知道这个应用在最终部署的时候,起一个什么名字。
String contextPath = servletcontext.getContextPath();
// 获取文件的绝对路径(真实路径)
public String getRealPath(String path);
// 通过servletContext对象也是可以记录日志的
public void log(String message);
public void log(String message, Throwable t);
// 这些日志信息记录到哪里了?
// localhost.2021-11-05.1og
// Tomcat服务器的logs目录下都有哪些日志文件?
//catalina.2021-11-05.1og 服务器端的java程序运行的控制台信息。
//localhost.2021-11-05.1og ServletContext对象的1og方法记录的日志信息存储到这个文件中。
//localhost_access_1og.2021-11-05.txt 访问日志
ServletContext对象还有另一个名字:应用域(后面还有其他域,例如:请求域、会话域)
// 如果所有的用户共享一份数据,并且这个数据很少的被修改,并且这个数据量很少,可以将这些数据放到ServletContext这个应用域中
// 为什么是所有用户共享的数据? 不是共享的没有意义。因为ServletContext这个对象只有一个。只有共享的数据放进去才有意义。
// 为什么数据量要小? 因为数据量比较大的话,太占用堆内存,并且这个对象的生命周期比较长,服务器关闭的时候,这个对象才会被销
毁。大数据量会影响服务器的性能。占用内存较小的数据量可以考虑放进去。
// 为什么这些共享数据很少的修改,或者说几乎不修改?
// 所有用户共享的数据,如果涉及到修改操作,必然会存在线程并发所带来的安全问题。所以放在ServletContext对象中的数据一般都是
只读的。
// 数据量小、所有用户共享、又不修改,这样的数据放到ServletContext这个应用域当中,会大大提升效率。因为应用域相当于一个缓
存,放到缓存中的数据,下次在用的时候,不需要从数据库中再次获取,大大提升执行效率。
// 存(怎么向ServletContext应用域中存数据)
public void setAttribute(String name, Object value); // map.put(k, v)
//取(怎么从ServletContext应用域中取数据)
public Object getAttribute(String name);//删(怎么删除ServletContext应用域中的数据)public void removeAttribute(String name);
map.put(k)
map.get(k)
map.remove(k)
Http协议
缓存机制(一部分)
- 堆内存中的字符串常量池 (jdk1.7之后将运行时的方法区常量池移动到了堆中)
- 堆内存中的整数常量池
- 连接池(connection Cache):jvm和数据库是两个进程,进程和进程之间打开通道是非常困难的。所以可以提前创建多个连接对象,需要连接的时候不需要重新创建,直接获取对选哪个。这样就能提高效率,而这个存放connection对象的数组就是连接池。
- 线程池:tomcat服务器在启动的时候就创建好n多个线程放到一个集合中。用户发起请求之后,直接从线程池中取对象。
- redis:Nosql数据库,非关系型数据库。缓存数据库
- servletcontext应用域
-
什么是协议?
-
协议实际上是某些人,或者某些组织提前制定好的一套规范,大家都按照这个规范来,这样可以做到沟通无障碍。
-
协议就是一套规范,就是一套标准。由其他人或其他组织来负责制定的。
-
我说的话你能听懂,你说的话,我也能听懂,这说明我们之间是有一套规范的,一套协议的,这套协议就是:中国普通话协议。我们都遵守这套协议,我们之间就可以沟通无障碍。
-
-
什么是HTTP协议?
-
HTTP协议:是W3C制定的一种超文本传输协议。(通信协议:发送消息的模板提前被制定好。)
-
W3C:
-
万维网联盟组织
-
负责制定标准的:HTTP HTML4.0 HTML5 XML DOM等规范都是W3C制定的。
-
万维网之父:蒂姆·伯纳斯·李
-
-
什么是超文本?
-
超文本说的就是:不是普通文本,比如流媒体:声音、视频、图片等。
-
HTTP协议支持:不但可以传送普通字符串,同样支持传递声音、视频、图片等流媒体信息。
-
-
这种协议游走在B和S之间。B向S发数据要遵循HTTP协议。S向B发数据同样需要遵循HTTP协议。这样B和S才能解耦合。
-
什么是解耦合?
-
B不依赖S。
-
S也不依赖B。
-
-
B/S表示:B/S结构的系统(浏览器访问WEB服务器的系统)
-
浏览器 向 WEB服务器发送数据,叫做:请求(request)
-
WEB服务器 向 浏览器发送数据,叫做:响应(response)
-
HTTP协议包括:
-
请求协议
-
浏览器 向 WEB服务器发送数据的时候,这个发送的数据需要遵循一套标准,这套标准中规定了发送的数据具体格式。
-
响应协议
-
WEB服务器 向 浏览器发送数据的时候,这个发送的数据需要遵循一套标准,这套标准中规定了发送的数据具体格式。
-
HTTP的请求协议包括:4部分
-
请求行GET /servlet05/getServlet?username=lucy&userpwd=1111 HTTP/1.1
-
请求头
Host: localhost:8080 请求头 Connection: keep-alive sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";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/95.0.4638.54 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: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Referer: http://localhost:8080/servlet05/index.html Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9
-
空白行:用于分割请求体和请求头的
-
请求体:数据直接记录在请求行上,这个请求空白
HTTP请求协议的具体报文:POST请求
-
请求行POST /servlet05/postServlet HTTP/1.1
-
请求头:略
-
空白行
-
请求体:username=lisi&userpwd=123
请求行:三个部分
第一部分 ,请求方式:get,post,delete,put,head,options,trace
第二部分, URI:统一资源标识符,代表网络中的每个资源名字 /servlet05/postServlet
URL:统一资源定位符,代表网络中某个资源,同时,通过URL是可以定位到该资源的。
URL包括URI
第三部分, HTTP协议版本号
请求头:请求的主机,主机的端口号,浏览器信息,平台信息,cookie等
-
空白行
-
空白行是用来区分“请求头”和“请求体”
-
-
请求体
-
向服务器发送的具体数据。
-
HTTP的响应协议包括:4部分
-
状态行:HTTP/1.1 200 ok
-
响应头:
Content-Type: text/html;charset=UTF-8 响应头
Content-Length: 160
Date: Mon, 08 Nov 2021 13:19:32 GMT
Keep-Alive: timeout=20
Connection: keep-alive
-
空白行
-
响应体(就是服务器返回给浏览器的东西,这里是用代码打印出来的前端网页)
-
<!doctype html> 响应体 <html> <head> <title>from get servlet</title> </head> <body> <h1>from get servlet</h1> </body> </html>
-
状态行
-
三部分组成
-
第一部分:协议版本号(HTTP/1.1)
-
第二部分:状态码(HTTP协议中规定的响应状态号。不同的响应结果对应不同的号码。)
-
200 表示请求响应成功,正常结束。
-
404表示访问的资源不存在,通常是因为要么是你路径写错了,要么是路径写对了,但是服务器中对应的资源并没有启动成功。总之404错误是前端错误。
-
405表示前端发送的请求方式与后端请求的处理方式不一致时发生:
-
比如:前端是POST请求,后端的处理方式按照get方式进行处理时,发生405
-
比如:前端是GET请求,后端的处理方式按照post方式进行处理时,发生405
-
-
500表示服务器端的程序出现了异常。一般会认为是服务器端的错误导致的。
-
以4开始的,一般是浏览器端的错误导致的。
-
以5开始的,一般是服务器端的错误导致的。
-
-
第三部分:状态的描述信息
-
ok 表示正常成功结束。
-
not found 表示资源找不到。
-
-
-
-
响应头:
-
响应的内容类型
-
响应的内容长度
-
响应的时间
-
....
-
-
空白行:
-
用来分隔“响应头”和“响应体”的。
-
-
响应体:
-
响应体就是响应的正文,这些内容是一个长的字符串,这个字符串被浏览器渲染,解释并执行,最终展示出效果。
-
怎么向服务器发送GET请求,怎么向服务器发送POST请求?
-
到目前为止,只有一种情况可以发送POST请求:使用form表单,并且form标签中的method属性值为:method="post"。
-
其他所有情况一律都是get请求:
-
在浏览器地址栏上直接输入URL,敲回车,属于get请求。
-
在浏览器上直接点击超链接,属于get请求。
-
使用form表单提交数据时,form标签中没有写method属性,默认就是get
-
或者使用form的时候,form标签中method属性值为:method="get"
-
GET请求和POST请求有什么区别?
-
-
get请求发送数据的时候,数据会挂在URI的后面,并且在URI后面添加一个“?”,"?"后面是数据。这样会导致发送的数据回显在浏览器的地址栏上。(get请求在“请求行”上发送数据)
-
post请求发送数据的时候,在请求体当中发送。不会回显到浏览器的地址栏上。也就是说post发送的数据,在浏览器地址栏上看不到。(post在“请求体”当中发送数据)
-
get请求只能发送普通的字符串。并且发送的字符串长度有限制,不同的浏览器限制不同。这个没有明确的规范。
-
get请求无法发送大数据量。
-
post请求可以发送任何类型的数据,包括普通字符串,流媒体等信息:视频、声音、图片。
-
post请求可以发送大数据量,理论上没有长度限制。
-
get请求在W3C中是这样说的:get请求比较适合从服务器端获取数据。
-
post请求在W3C中是这样说的:post请求比较适合向服务器端传送数据。
-
get请求是安全的。get请求是绝对安全的。为什么?因为get请求只是为了从服务器上获取数据。不会对服务器造成威胁。(get本身是安全的,你不要用错了。用错了之后又冤枉人家get不安全,你这样不好(太坏了),那是你自己的问题,不是get请求的问题。)
-
post请求是危险的。为什么?因为post请求是向服务器提交数据,如果这些数据通过后门的方式进入到服务器当中,服务器是很危险的。另外post是为了提交数据,所以一般情况下拦截请求的时候,大部分会选择拦截(监听)post请求。
-
get请求支持缓存。
-
https://n.sinaimg.cn/finance/590/w240h350/20211101/b40c-b425eb67cabc342ff5b9dc018b4b00cc.jpg
-
任何一个get请求最终的“响应结果”都会被浏览器缓存起来。在浏览器缓存当中:
-
一个get请求的路径a 对应 一个资源。
-
一个get请求的路径b 对应 一个资源。
-
一个get请求的路径c 对应 一个资源。
-
......
-
-
实际上,你只要发送get请求,浏览器做的第一件事都是先从本地浏览器缓存中找,找不到的时候才会去服务器上获取。这种缓存机制目的是为了提高用户的体验。
-
有没有这样一个需求:我们不希望get请求走缓存,怎么办?怎么避免走缓存?我希望每一次这个get请求都去服务器上找资源,我不想从本地浏览器的缓存中取。
-
只要每一次get请求的请求路径不同即可。
-
https://n.sinaimg.cn/finance/590/w240h350/20211101/7cabc342ff5b9dc018b4b00cc.jpg?t=789789787897898
-
https://n.sinaimg.cn/finance/590/w240h350/20211101/7cabc342ff5b9dc018b4b00cc.jpg?t=789789787897899
-
https://n.sinaimg.cn/finance/590/w240h350/20211101/7cabc342ff5b9dc018b4b00cc.jpg?t=系统毫秒数
-
怎么解决?可以在路径的后面添加一个每时每刻都在变化的“时间戳”,这样,每一次的请求路径都不一样,浏览器就不走缓存了。
-
-
-
post请求不支持缓存。(POST是用来修改服务器端的资源的。)
-
post请求之后,服务器“响应的结果”不会被浏览器缓存起来。因为这个缓存没有意义。
-
-
-
GET请求和POST请求如何选择,什么时候使用GET请求,什么时候使用POST请求?
-
怎么选择GET请求和POST请求呢?衡量标准是什么呢?你这个请求是想获取服务器端的数据,还是想向服务器发送数据。如果你是想从服务器上获取资源,建议使用GET请求,如果你这个请求是为了向服务器提交数据,建议使用POST请求。
-
大部分的form表单提交,都是post方式,因为form表单中要填写大量的数据,这些数据是收集用户的信息,一般是需要传给服务器,服务器将这些数据保存/修改等。
-
如果表单中有敏感信息,还是建议适用post请求,因为get请求会回显敏感信息到浏览器地址栏上。(例如:密码信息)
-
做文件上传,一定是post请求。要传的数据不是普通文本。
-
其他情况都可以使用get请求。
-
-
不管你是get请求还是post请求,发送的请求数据格式是完全相同的,只不过位置不同,格式都是统一的:
-
name=value&name=value&name=value&name=value
-
name是什么?
-
以form表单为例:form表单中input标签的name。
-
-
value是什么?
-
以form表单为例:form表单中input标签的value。
-
-
模板方法设计模式
-
什么是设计模式?
-
某个问题的固定的解决方案。(可以被重复使用。)
-
-
你知道哪些设计模式?
-
GoF设计模式:
-
通常我们所说的23种设计模式。(Gang of Four:4人组提出的设计模式)
-
单例模式
-
工厂模式
-
代理模式
-
门面模式
-
责任链设计模式
-
观察者模式
-
模板方法设计模式
-
.....
-
-
JavaEE设计模式:
-
DAO
-
DTO
-
VO
-
PO
-
pojo
-
....
-
-
....
-
-
什么是模板方法设计模式?
-
在模板类的模板方法当中定义核心算法骨架,具体的实现步骤可以延迟到子类当中完成。
-
-
模板类通常是一个抽象类,模板类当中的模板方法定义核心算法,这个方法通常是final的(但也可以不是final的)
-
模板类当中的抽象方法就是不确定实现的方法,这个不确定怎么实现的事儿交给子类去做。