静态资源vs动态资源:
静态资源:提前写好的内容,tomcat读取文件即可
动态资源:通过代码片段写好的内容,tomcat调用代码片段,运行生成内容
Ajax是让js具有发送响应HTTP请求能力
首先有一个json的文件
其次有一个js文件,
js通过创建XMLHttpRequst对象xhr来进行发送HTTP请求
再调用对象发送要求资源的方法 xhr.open("请求方法","要请求资源的路径")
再通过事件驱动的方式接收响应内容,改变DOM树xhr.οnlοad=fuction{}:
其中xhr/this是事件源,xhr.responseTest是响应体 有一个js的原生方法把String json字符串转为js对象JSON(字符串),这时的情况是转为数组,添加DOM树,把name加上去
再调用xhr.send()发送请求
再有一个html文件为Ajax,有js
解析以上浏览器和tomcat的通信,图如下:
用哪些方法可以让浏览器发出HTTP请求:
GET:①地址栏回车②a标签③form表单(<form action="">)④<img src=""> ⑤<link href="">⑥<scrip src=""> ⑦Ajax
POST:form表单 Ajax 重定向
这时就可以解释状态码404出现的原因:8080端口被其他进程绑定 路径(Context Path+Servlet Psth)写错了 代码中写了404
使用Servlet(服务器的小物件)技术开发动态资源:
开发流程要遵守标准(没有遵守tomcat不认)
1、通过继承HttpServlet抽象类,完成我们自己的类(每一个都是一个独立的web资源)
2、重写其中的方法(get,post,delete,put),输出资源内容
3、把动态资源和路径建立绑定关系:①通过web.html ②使用java中注解语法完成@WebServlet
不需要我们实例化对象(tomcat会实例化(饿汉模式)) 不需要我们调用写好的方法(tomcat会在合适的时候调用)
如图所示:重写了get方法 req是请求 resp是响应 ,读取请求信息,根据我们当下情况,准备响应数据,通过填写resp对象进行响应
resp.setStatus(响应状态) resp.setContentType(响应文件内容,字符集编码)
@WebServlet("/second")把动态资源与路径进行绑定
Tomcat内部的大概过程:
1、tomcat收到了HTTP请求
2、tomcat根据HTTP协议进行解析,得到了:请求方式,资源路径,请求头们,请求体
3、tomcat根据路径(Path=Context Path+Servlet Psth)
Context Path是告知这个资源交给了哪个webapp(tomcat可以支持多个webapp)
Servlet Psth让tomcat在对应的webapp中找到资源进行处理:
(一)动态资源
如果是动态资源tomcat会根据Servlet Psth 路径得到一个类
如果这个类没有实例化对象,tomcat会实例化其对象,否则直接获取这个对象(单例模式)
拿到对象之后,根据请求方法,调用这个对象的doGet/doPost方法或者其他方法
doGet方法执行后,resp对象被填充信息,tomcat根据resp对象构造HTTP响应,发送给webapp(浏览器)
(二)静态资源
如果是静态资源,就根据路径找到对应文件,并响应文件内容
(三)如果静态/动态资源都没有找到,就404
重要的面试题:浏览器中输入url回车之后,知道看见网页,期间发生了什么
首选在应用层角度上:
1、浏览器解析URL(如果是域名通过DNS服务器,将域名换成IP的过程)构建HTTP请求(GET请求)
2、Tomcat接收到HTTP请求,根据路径Context Path确定是哪个webapp,再根据Servlet Psth找到对象,再调用对象的get方法,填充响应对象,
3、根据响应对象构建HTTP响应,发送给浏览器
4、浏览器读取响应,如果是html/或者要直接js代码,可能还会触发产生新的HTTP请求
5、最后浏览器得到显示页面的所以资源,构建DOM树(js处理过程)+CSS渲染产生最终页面
6、用户看见页面
还可以结合网络知识:发送HTTP请求,收到HTTP请求,首先要建立TCP连接
TCP的三次握手+TCP连接+TCP四次挥手
站在发送端(浏览器):应用层-传输层-网络层-数据链路层-物理层(网卡)各种协议的封装
站在接收端(tomcat):物理层-数据链路层-网络层-传输层-应用层 各种协议的解包分用
只针对网络层的路由(路由器的作用(长期目标-短期目标)) ARP表(局域网的IP转换成MAC地址)
NAT服务器怎么做到IP转为PORT替换映射的
DNS的请求过程(域名转IP):
1、浏览器可能有本地DNS
2、如果缓存中没有,去调用OS系统调用,去要DNS换IP
3、O读取本地hosts文件
4、OS会发送DNS请求,给本地DNS服务器
3、如果本地DNS有记录,直接返回,如果没有,再去它的上一级要记录结果,最终走到权威DNS(geng)
HttpServlet 类中有req包含了请求行+请求头+请求体(可能)
GET方法不包含请求体,POST方法包含请求体
POST请求方式:form表单发送HTTP请求 准备servlet动态资源只支持POST方法,答应读取请求头,代码图如下:
req对象以getxxx()方法为主:
resp对象以setxxx()方法为主:
响应填充:resp.setStatus(响应状态)
设置响应头: resp.setHeader("content-type","text/plain;charset=utf-8");响应头是key-value形式,name不区分大小写,非标准响应头name:X-(以x开头)
设置响应体:面向字符 :resp.setCharacterEncoding("字符集编码") resp.setContentype("文件格式") resp.getWriter():
PrintWriter writer = resp.getWriter(); //这只是拿到了一个管道对象(字节流对象) writer.print("你好");(对流操作,操作结果会反应到resp的对应位置)
响应体的内容是字节流
resp.getOutputStream():
OutputStream outputStream = resp.getOutputStream();//这只是获得了一个字节流对象 outputStream.write('H');//在对流进行操作,操作结果会反应到resp对应位置
Servlet生命周期:
servlet请求-响应服务器模型(不仅仅争对HTTP协议)
interface Servlet-abc class HttpServlet -MyServlet
三个方法(三个阶段):
1、初始化阶段 init() 有且只有一次
2、处理请求响应阶段 service(req,resp)每一次请求响应都会执行一次 HttpServlet 变成doGet/doPost
3、销毁阶段 destory() 有且只有一次
Servlet日常开发格式要求:
@WebServlet(路径):①填写路径必须以/开头 ②路径不能重复 ③特殊情况1:路径为"*.do"只要路径后缀名是.do的URL都这个代码管 ④特殊情况2:"/"所有的URL都归这个代码管 ⑤""代表根目录URL
什么情况Tomcat启动失败:1、端口被占用 2、动态资源绑定的路径有错
响应体是文本内容&&字符集编码为utf-8
1、设置响应体字符集编码:resp.setCharacterEncoding("utf-8");先设置字符集,再resp.getWriter
2、设置Content-Type的响应头(代表响应体文本格式):resp.setContentType("text/plain");
3、写响应体:
PrintWriter writer = resp.getWriter();获得通道对象,
writer.print("1"); 对通道对象进行操作
读取请求参数(网页中收集用户填写的信息)
GET方法请求参数放在URL中的搜索字符串中(quer string)
POST方法请求的参数放在URL中的搜索字符串(quer string)中和响应体中(requst body)(必须是form表单请求的)
GET和POST方法读取参数都是req.getParameter()
图如下:get请求:
post请求:
正确请求格式:
当GET请求时:
1、请求参数放在query string 格式为name-value&name-value
2、当value无论中文时还是英文均可以正确读取
3、如果只有name读到一个空字符串
4、如果name都没有了,读到为null
当POST请求时:
1、请求参数放在query string 也可以放在 requst body中(必须form表单) 格式为name-value&name-value
2、当value英文可以正确读取,中文要在读取之前设置字符集编码(req.setCharacterEncoding())
3、如果只有name读到一个空字符串
4、如果name都没有了,读到为null
面试常见问题:GET和POST有什么区别:
1、根本区别:语义不同get是获得,post是提交
2、具体区别:
1、get不应该带有请求体/响应体 post可以带有请求体/响应体
2、有参数get请求放在查询字符串中,post请求放在查询字符串或者请求体中(form表单)
由于浏览器的实现URL长度有限 短于请求头(无限制)
URL一般delete总会记录在日志中,请求头不会记录日志,所以有种说法post比get稍微安全一点(真正安全使用HTTPS协议)
3、HTTP方法类比于sql动作
get(select) post(insert)put(update)delete(delete)
幂等的(今天,明天,永远可以执行下去):get,put ,delete
无副作用的:执行不会影响数据
现象一:
get请求:直接刷新浏览器,浏览器就自动重新发送请求
post请求:直接刷新浏览器,有些浏览器会提示用户,你确定重新发送一次post请求吗
现象二:
HTTP响应支持缓存,为了提升访问速度,get支持,post不支持
资源重定向(请求一个资源时,要求浏览器请求另一个资源):
3xx+响应头(定位到新的地址上面)
重定向:有永久重定向 和临时重定向
301永久重定向 (不能请求老地址了,要请求新地址)
重定向时是否保留原方法:
303无论是post还是get重定向之后还是get请求(不保留,退化成get)
307根据之前的请求方法,重定向的请求方法也是之前的(保留跟之前的一样)