一、浏览器里输入URL,按回车,之后发生了什么
详细介绍 https://4ark.me/post/b6c7c0a2.html
- URL解析
- DNS解析
- TCP连接
- 处理请求和响应
- 浏览器渲染页面
URL解析–抽取域名字段
什么是URL
URL(Universal Resource Locator),统一资源定位符,也就是我们常说的网址。用来标记在互联网上的万维网文档(web资源),互联网上的每个web资源都有一个唯一的URL,它包含的信息指出资源的位置以及浏览器应该怎么处理它。
URL格式
协议://域名:端口号/资源虚拟路径/资源名?参数1&参数2
http://www.tangbohu.com:9527/qiuxiang.people?age=18&height=166cm
- 协议:http https ftp 等等 。
- 域名(Domain Name):一串用点分隔的名字组成的Internet上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位。
- 域名与ip地址的关系:一对一或者多对一。(ip地址内容看谢希仁的课本)
- DNS(Domain Name System):域名系统,是域名和IP对应的一个数据库,机器之间只认ip,需要域名系统将域名翻译为ip地址。
- 端口号:用来标识服务器上的应用程序。
- 虚拟路径
- 参数
DNS域名解析—域名→ip地址
ip地址不好记,计算机不认域名,需要DNS来进行ip地址和域名的映射
查询过程:
- 查询浏览器缓存
- 查询系统缓存 --检查hosts文件,这个文件保存了以前访问过的网站的域名和IP数据
- 查询本地域名服务器(LDNS),校园网–校园机房、移动电信等–本地运营商服务器,未命中向上迭代查询
- 查询 根域名服务器,这是最上层了。
- 查询到 根域名服务器告诉本地域名服务器应该查询的顶级域名服务器
- 查询到 顶级服务器告诉本地域名服务器应该查询的权限域名服务器
- 查询到 权限域名服务器告诉本地域名服务器想查询的ip
- 查询到 顶级服务器告诉本地域名服务器应该查询的权限域名服务器
- 查询到 根域名服务器告诉本地域名服务器应该查询的顶级域名服务器
域名知识:
图片来源https://blog.csdn.net/baidu_37964071/article/details/80500825
通用顶级域名:
- com 企业域名
- net 网络提供商
- org 非盈利组织
- gov:表示政府机构
- edu:表示教育机构
国家顶级域名:cn 中华人民共和国国家及地区顶级域的域名
TCP连接
只有低层协议(TCP)建立之后才能进行更高层协议(HTTP)的连接
处理请求和响应
https://blog.csdn.net/chen1403876161/article/details/51546653
浏览器页面渲染
略
二、Tomcat服务器
目录结构
bin
bin是binary的缩写 该目录存放windows和linux命令文件、tomcat可执行文件
- .bat 是dos下的批处理文件,包含一条或多条命令。它的文件扩展名为 .bat 或 .cmd。在命令提示下输入批处理文件的名称,或者双击该批处理文件,系统就会调用cmd.exe按照该文件中各个命令出现的顺序来逐个运行它们。
- .sh 是UNIX/LINUX 操作系统的脚本文件
- .exe 可执行文件
conf 存放配置文件
context.xml (context背景、环境、来龙去脉)
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<!--被监视的资源,没有/是相对路径------->
server.xml
server.xml详解https://www.cnblogs.com/kismetv/p/7228274.html
每一个元素都对应了Tomcat中的一个组件;通过对xml文件中元素的配置,可以实现对Tomcat中各个组件的控制。
文件结构
<Server>
<Service>
<Connector />
<Connector />
<Engine>
<Host>
<Context /><!-- 现在常常使用自动部署,不推荐配置Context元素,Context小节有详细说明 -->
</Host>
</Engine>
</Service>
</Server>
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000" redirectPort="8443" />
<Engine name="Catalina" defaultHost="www.neweasymall.com">
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
</Host>
</Engine>
</Service>
</Server>
标签 | 作用 | 属性含义 |
---|---|---|
Server | 代表整个Tomcat容器,提供一个接口让客户端能够访问到这个Service集合,同时维护它所包含的所有的Service的生命周期,一个Server可以有多个Service。 | shutdown:关闭Server的指令;port属性:Server接收shutdown指令的端口号,设为-1可以禁掉该端口。 |
Service | 把Connector和Engine组装在一起,对外提供服务。一个Service可以包含多个Connector,但是只能包含一个Engine。 | name:名字 |
Connection | 从客户端接收请求 | port:监听HTTP请求的端口号;protocol:请求使用的协议;connectionTimeout:超时时间 redirectPort:略 |
Engine | 请求处理组件,处理Connection接收进来的请求,并将完成的响应返回给Connector | defaultHost:发往本机的请求指定的host名称不存在时,一律使用defaultHost指定的host进行处理;因此,defaultHost的值,必须与Engine中的一个Host组件的name属性值匹配。 |
Host | Engine、Host和Context都是容器,Host是Engine的子容器。Host代表虚拟主机,对应了服务器中一个网络名实体,运行多个Web应用,缺省主机不需要在DNS注册。 | appBase:appBase属性指定Web应用所在的目录,默认值是webapps,这是一个相对路径,代表Tomcat根目录下webapps文件夹。创建web工程发布web应用时可以自定义发布路径。 |
web.xml
全局的web应用程序部署描述文件,具体太多了现在理解不了。
tomcat-user.xml
配置Tomcat的用户名、密码,管理身份验证以及访问控制权限。
lib
Tomcat的类库,里面是一大堆jar文件
logs
运行中产生的日志文件
temp
临时文件目录,清空不会影响Tomcat运行
webapps
webapps目录用来存放web应用,,其中每个文件夹都是一个项目,当tomcat启动时会去加载webapps目录下的应用程序。ROOT是一个特殊的文件夹,在地址栏中没有给出web应用路径时,默认使用ROOT。
work
运行时生成的文件,最终运行的文件都在这里。
三、Servlet
servlet本质是一个java编写的服务端应用程序,它运行在应用服务器中。
Servlet接口
public interface Servlet {
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
- servlet 的生命周期
Servlet第一次被请求时,Servlet容器调用init方法初始化Servlet对象,这个方法只调用一次;后续的每次请求,Servlet对象都会调用service方法;当Servlet对象被移出容器或者关闭Tomcat服务器时,Servlet对象调用destory方法,进行销毁,Servlet对象至此驾鹤起去了。
Tomcat工作机制
浏览器向Tomcat服务器发送请求→服务器从磁盘加载Servlet到容器→服务器解析HTTP请求为Request对象→转发Request对象到相应的Servlet→Servlet处理后返回Reponse→Tomcat服务器将Response对象转换为HTTP响应→响应返回到客户端
HTTPServletRequest对象详解
HTTP复习
请求/响应报文结构
请求 | 响应 |
---|---|
请求行 request line | 状态行 |
请求头 request header | 响应头 |
空行 | 空行 |
请求数据 | 响应正文 |
HTTPServletRequest对象封装着请求头的信息。
public class RequestDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
- 方法
request.getRequestURL();//返回客户端发出的请求中的URL
request.getRequestURI();//返回请求行中资源名称,统一资源标识符,URI范围比URL大
request.getQueryString();//返回请求行参数部分 ?
request.getRemoteAddr();//返回请求的客户机的IP地址
request.getMethod();//返回客户机请求方式
request.getContextPath();//拿到的是你的web项目的根路径(域名后边的路径)
request.getHeader("");//获取单个请求头value值
request.getHeaders("");//获取多个同名请求头对应的value值
request.getParameter("");//获取请求参数
示例:URL URI ContextPath(web应用根目录)
乱码处理
Request 乱码处理
- post乱码处理
浏览器发送数据,是编码数据的位置;浏览器使用何种字符集打开页面,就会使用何种字符集发送数据,utf-8。 服务器接收数据,是解码数据的位置;tomcat8.5 及其以上 utf-8,7.0是iso8859-1,这个字符集没中文。所以,可以通知服务器接收数据时用utf-8解码。
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
System.out.println("username: "+username);
- get乱码处理
字符C(浏览器:输入)→二进制数据B(浏览器:用utf-8编码)→乱码D(服务器:用iso解码)→二进制数据B(服务器:用iso编码)→字符C(服务器:用utf-8解码)
String username = request.getParameter("username");
byte[] bytes = username.getBytes("iso8859-1");//编码
username = new String(bytes, "utf-8");//解码
//------
username = new String(username.getBytes("iso8859-1"),"utf-8");
System.out.println("username"+username);
Response 乱码处理
//最好的解决方法,不论字符流,字节流
response.setContentType("text/html;charset=UTF-8");
//字符流——response.getWriter()——解决方法B
response.setCharacterEncoding("UTF-8");//规定输出到客户端时,使用utf-8进行编码
response.setHeader("content-type","text/html;charset=UTF-8");//规定浏览器,
//字节流—— response.getOutputStream()
response.setHeader("content-type","text/html;charset=UTF-8");//指定浏览器
response.getOutputStream().write("中文".getBytes("UTF-8")); //指定输出
页面跳转的两种方式
请求转发
作用:多个资源之间共享数据
特点:
- 在服务器端完成跳转,浏览器感知不到,所以地址栏不发生变化;
- 从当前servlet跳转到目的servlet,前后共用一个request,即一次请求,一次响应。
- "/"表示当前web应用的根目录。
demo4
@WebServlet("/RequestDemo4")
//创建调度器
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/RequestDemo5");
//请求转发
requestDispatcher.forward(request,response);
- 请求转发可以实现多重转发
demo4
@WebServlet("/RequestDemo4")
//创建调度器
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/RequestDemo5");
//请求转发
requestDispatcher.forward(request,response);
demo5
@WebServlet("/RequestDemo5")
request.getRequestDispatcher("/RequestDemo6").forward(request,response);
demo6
@WebServlet("/RequestDemo6")
response.getWriter().write("this is demo6");
请求重定向
- 客户端跳转,浏览器地址栏会发生变化;
- 两次请求,两次响应,可以转型其他web应用;
- 不使用上一次的request对象
response.sendRedirect("目的页面");
路径问题
域对象
四、cookie session
这个东西怎么找出来—ctrl+R all
cookie 数据保存在浏览器端–时间长
- 会话作用:在多次请求和响应之间共享数据,直到浏览器关闭之前,发送到所有请求和响应都属于会话。
ctrl shift delete - 浏览器第一次发送请求:携带请求参数,参数到达服务器,服务器将参数以set-cookie响应头的形式传回浏览器,这个参数保存在浏览器中;
浏览器第二次发送请求:请求自动带一个cookie请求头,请求头中的数据就是刚刚保留在浏览器中的cookie信息。
//请求参数放入 set-cookie响应头
response.setHeader("set-cookie","time "+time);
//通过请求对象获取 cookie请求头,读取数据
String cookie = request.getHeader("cookie");
//通过respone对象输出到浏览器中
if(cookie == null){
response.getWriter().write("初次访问");
}else {
response.getWriter().write("上次访问时间"+cookie);
}
- 设置生命时长
setMaxAge()
- 设置有效路径 cookie影响的范围
setPath(getContextPath()+"/")
如果不设置有效路径,那么cookie只在当前资源的路径级别下有效。 - 发送cookie
- 删除cookie
cookie类没有删除方法,而是发送一个与要删除cookie一致(name path domain)且生命时长为0的cookie到浏览器,将原有覆盖。
Cookie cookie = new Cookie("time","");
cookie.setPath(request.getContextPath()+"/");
cookie.setMaxAge(0);
response.addCookie(cookie);
- 获取cookie的name和value值
package cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
@WebServlet("/CookieDemo2")
public class CookieDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//乱码处理
response.setContentType("text/html;charset=utf-8");
Date date = new Date();
String time = date.toLocaleString();
//创建cookie
Cookie cookie = new Cookie("time",time);
//发送cookie 响应→发送cookie到浏览器
response.addCookie(cookie);
//获取cookie
Cookie[] cookies = request.getCookies();//除此访问没有cookie 所以会赋值为null
//下面会出现空指针,所以加一个判断
//遍历cookie
Cookie co = null;
if (cookies!=null){
for (Cookie c:cookies){
if ("time".equals(c.getName())){
co = c;
}
}}
//获取cookie的值
//响应到浏览器
if (co!=null){
String value = co.getValue();
response.getWriter().write(value);
}else {
response.getWriter().write("初次访问");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
session 数据保存在服务端–时间短
- 浏览器访问服务器中,会在服务器中创建一个session对象,这个对象可保存当前浏览器的数据,多个浏览器会各自在服务器中保留各自的session对象,这些对象是通过SESSIONID区分的。
- session本质是一个cookie,在浏览器中会保留一个名为JSESSIONID的cookie用于存储当前session对象的id。
- request.getsession()
- true 没有session对象会创建对象,有取出直接用
- false 没有session对象会返回null,有取出直接用
- 可以作为域对象使用 生命周期:
//将JESSIONID在浏览器端保存
HttpSession session = new request.getSession();
Cookie cookie = new Cookie("JESSIONID",session.getID());
cookie.setPath(request.getContextPath()+"/");
cookie.setMaxAge(3600*24*30);
response.addCookie(cookie);
验证码
- 控制浏览器不使用缓存
response.setDateHeader("Expires",-1);
response.setHeader("Cache-Control","no-cache");
response.setHeader("pragma","no-cache");
- 验证码图片
<img id=" " src="" width="" height=""/>
- 添加单击事件,更换图片
//再访问路径就可以
$("#img").click(function(){
//jQuery修改属性
$(this).attr("src","<%=request.getContentPath()%>/ValidateServlet")
//http协议中,如果两次请求的地址没有发生变化,认为是同一个请求,不发送。拼一个参数,不一定使用
var date = new Date();
var time = date.toLocaleString();
//获取毫秒
var time = date.getTime();
$(this).attr("src","<%=request.getContentPath()%>/ValidateServlet?time"+time);
})