目录
HTTP协议
1、HTTP协议简介
2、HTTP协议特点
3、HTTP协议通信流程(工作原理)
4、HTTP报文格式
4.1、HTTP请求报文
4.2、HTTP响应报文
4.3、HTTP状态消息
Servlet详解
1、Servlet核心接口和类
1.1、Servlet接口
1.2、GenericServlet抽象类
1.3、HttpServlet类
2、Servlet两种创建方式
2.1、实现Servlet接口
3、Servlet两种配置方式
3.1、使用web.xml配置
3.2、资源配置属性
3.3使用注释配置
3.4、@WebServlet注解常用属性
Servlet应用
1、Request对象
1.1、got和post区别
1.2、request主要方法
1.3request应用
1.4、get请求收参问题
1.5、get中文乱码
1.6、post中文乱码
2、response对象
2.1、response主要方法
2.2、response应用
2.3、解决输出中文乱码
HTTP协议
1、HTTP协议简介
HTTP(HyperText Transfer Protocol),超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个基于请求与响应模式的、无状态的、应用层的协议,运行于TCP协议基础之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。
2、HTTP协议特点
(1)支持客户端(浏览器)/服务器模式。
(2)简单快速:客户端只向服务器发送请求方法和路径,服务器即可响应数据,因而通信速度很快。请求方法常用的有get和post等。
(3)灵活:HTTP允许传输任意类型的数据,传输的数据类型由Content-Type标识。
(4)无连接:无连接指的是每次TC连接只处理一个或多个请求,服务器处理完客户的请求后,即断开连接。采用这种方式可以节省传输时间。
HTTP1.0版本一个请求响应之后,直接就断开了。称为短连接。
HTTP1.1版本不是响应之后直接就断开了,而是等几秒钟,这几秒钟之内有新的请求,那么还是通过之前的连接通道来收发消息,如果过了这几秒钟用户没有发送新的请求,就会断开连接。称为长连接。
(5)无状态:HTTP协议是无状态协议。
无状态是指协议对于事务处理没有记忆能力。
3、HTTP协议通信流程(工作原理)
HTTP是基于客户/服务器模式,且面向连接的。典型的HTTP事务处理有如下的过程:
(1)客户端与服务器建立连接(三次握手)。
(2)客户向服务器发送请求。
(3)服务器接受请求,并根据请求返回响应的文件作为应答。
(4)客户与服务器关闭连接(四次挥手)。
客户与服务器之间的HTTP连接是一种一次性连接,它限制每次连接只处理一个请求,当服务器返回本次请求的应答后便立即关闭连接,下次请求再重新建立连接。这种一次性连接主要考虑到WWW服务器面向的是Internet中成千上万个用户,且只能提供有限个连接,故服务器不会让一个连接处于等待状态,及时地释放连接可以大大提高服务器的执行效率。
HTTP是一种无状态协议,即服务器不保留与客户交易时的任何状态。这就大大减轻了服务器记忆负担,从而保持较快的响应速度。HTTP是一种面向对象的协议。允许传送任意类型的数据对象。它通过数据类型和长度来标识所传送的数据内容和大小,并允许对数据进行压缩传送。当用户在一个HTML文档中定义了一个超文本链后,浏览器将通过TCP/IP协议与指定的服务器建立连接。
HTTP支持持久连接,在HTTP / 0.9和1.0中,连接在单个请求/响应对之后关闭。在HTTP / 1.1中,引入了保持活动机制,其中连接可以重用于多个请求。这样的持久性连接可以明显减少请求延迟,因为在发送第一个请求之后,客户端不需要重新协商TCP 3-Way-Handshake连接。另一个积极的副作用是,通常,由于TCP的缓慢启动机制,连接随着时间的推移而变得更快。
该协议的1.1版还对HTTP / 1.0进行了带宽优化改进。例如,HTTP / 1.1引入了分块传输编码,以允许流传输而不是缓冲持久连接上的内容。HTTP流水线进一步减少了延迟时间,允许客户端在等待每个响应之前发送多个请求。协议的另一项附加功能是字节服务,即服务器仅传输客户端明确请求的资源部分。
从技术上讲是客户在一个特定的TCP端口(端口号一般为80)上打开一个套接字。如果服务器一直在这个周知的端口上倾听连接,则该连接便会建立起来。然后客户通过该连接发送一个包含请求方法的请求块。
HTTP规范定义了9种请求方法,每种请求方法规定了客户和服务器之间不同的信息交换方式,常用的请求方法是GET和POST。服务器将根据客户请求完成相应操作,并以应答块形式返回给客户,最后关闭连接。
4、HTTP报文格式
HTTP报文由从客户机到服务器的请求和从服务器到客户机的响应构成。
4.1、HTTP请求报文
当浏览器向Web服务器发出请求时,它向服务器传送了一个数据块,也就是所谓的请求信息(请求报文),HTTP请求信息由4个部分组成,分别是:1、请求行 请求方法/地址/ URI协议/版本 2、请求头(Request Header) 3、空行 4、请求正文
4.2、HTTP响应报文
HTTP响应报文与HTTP请求报文相似,HTTP响应报文也由4个部分组成:1、状态行 2、响应头(Response Header) 3、空行 4、响应正文
4.3、HTTP状态消息
HTTP的状态消息有很多,在这里主要列举最常见的一些状态消息。
状态代码 | 状态描述 | 说明 |
---|---|---|
200 | OK | 客户端请求成功 |
302 | Found | 临时重定向 |
403 | Forbidden | 服务器收到请求,但是拒绝提供服务。 服务器通常会在响应正文中给出不提供服务的原因 |
404 | Not Found | 请求的资源不存在,最常见的就是输入了错误的路径 |
500 | Internal Server Error | 服务器发生不可预期的错误,导致无法完成客户端的请求 |
Servlet详解
1、Servlet核心接口和类
在Servlet体系结构中,除了第三节中讲的实现Servlet接口,还可以通过继承GenericServlet或HttpServlet类,完成自定义Servlet的编写。
1.1、Servlet接口
在Servlet API中最重要的是Servlet接口,所有Servlet都会直接或间接的与该接口发生联系,或是直接实现该接口,或间接继承自实现了该接口的类。该接口中包括以下5个方法:
destroy()
ServletConfig getServletConfig()
String getServletInfo()
void init(ServletConfig arg0)
void service(ServletRequest arg0, ServletResponse arg1)
1.2、GenericServlet抽象类
GenericServlet使编写Servlet变得更容易。它提生命周期方法init和destroy的简单实现,要编写一般的Servlet,只需要重写service方法即可。
1.3、HttpServlet类
1)HttpServlet是在继承GenericServlet的基础上进一步的扩展。提供将要被子类化以创建适用于Web站点的HTTP servlet的抽象类。
2)HTTPServlet的子类至少必须重写一个方法,该方法通常是:
-
doGet():用于HTTP GET请求
-
doPost():用于HTTP POST请求
-
doPut():用于HTTP PUT请求
-
doDelete():用于HTTP DELETE请求
2、Servlet两种创建方式
2.1、实现Servlet接口
使用这种方式创建Servlet类比较麻烦,需要重写Servlet接口中的所有方法
package com.cxyzxc.www.servlet01;
import javax.servlet.*;
import java.io.IOException;
/**
* 使用实现Servlet接口创建的Servlet类
*/
public class MyServlet01 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("使用实现Servlet接口创建的MyServlet类");
servletResponse.getWriter().println("Servlet is very interesting ");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
2.2、继承HttpServlet(推荐使用)
package com.cxyzxc.www.servlet01;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 使用继承HttpServlet类创建的MyServlet类,开发中推荐使用这种方式
*/
public class MyServlet02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("使用继承HttpServlet类创建的MyServlet类");
resp.getWriter().println("Servlet is very funny ");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3、Servlet两种配置方式
3.1、使用web.xml配置
这种配置是Servlet2.5之前使用的
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<!-- Servlet名称 -->
<servlet-name>myServlet01</servlet-name>
<!-- Servlet的全称类名 -->
<servlet-class>com.cxyzxc.www.servlet01.MyServlet01</servlet-class>
<!-- 启动的优先级,数字越小越先起作用 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Servlet映射配置 -->
<servlet-mapping>
<!-- Servlet名称 -->
<servlet-name>myServlet01</servlet-name>
<!-- 资源的匹配原则:精确匹配 -->
<url-pattern>/servlet01</url-pattern>
</servlet-mapping>
</web-app>
3.2、资源配置属性
url-pattern定义匹配规则,取值说明:
精确匹配 /具体的名称 只有url路径是具体的名称的时候才会触发Servlet
后缀匹配 *.xxx 只要是以xxx结尾的就匹配触发Servlet
通配符匹配 /* 匹配所有请求,包含服务器的所有资源
通配符匹配 / 匹配所有请求,包含服务器的所有资源,不包括.jspload-on-startup
1)元素标记容器是否应该在web应用程序启动的时候就加载这个servlet。
2)它的值必须是一个整数,表示servlet被加载的先后顺序。
3)如果该元素的值为负数或者没有设置,则容器会当servlet被请求时再加载。
4)如果值为整数或0时,表示容器在应用启动时就加载并初始化这个servlet,值越小,servlet的优先级越高,就越先被加载。值相同时,容器就会自己选择顺序来加载。
3.3使用注释配置
这种配置是Servlet3.0之后使用的,推荐使用这种方式
@WebServlet("/servlet02")
public class MyServlet02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("使用继承HttpServlet类创建的MyServlet类");
resp.getWriter().println("Servlet is very funny ");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3.4、@WebServlet注解常用属性
-
name:Servlet名字(可选)
-
value:配置url路径,可以配置多个
-
urlPatterns:配置url路径,和value作用一样,不能同时使用
-
loadOnStartup:配置Servlet的创建的时机,如果是0或者正数,启动程序时创建,如果是负数,则访问时创建。数字越小优先级越高。
Servlet应用
1、Request对象
在Servlet中用来处理客户端请求需要用doGet或doPost方法中的request对象。
1.1、got和post区别
get请求
-
get提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连
-
get方式明文传递,数据量小,不安全
-
效率高,浏览器默认请求方式为get请求
-
对应的Servlet的方法是doGet()
post请求
-
post方法是把提交的数据放在HTTP包的body中
-
密文传递数据,数据量大,安全
-
效率没有get高
-
对应的Servlet的方法是doPost()
1.2、request主要方法
方法名 | 方法说明 |
---|---|
String getParameter(String name) | 根据表单组件名称获取提交的数据 |
void setCharacterEncoding(String charset) | 指定每个请求的编码 |
1.3request应用
c
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎页面</title>
</head>
<body>
<h1>欢迎你</h1>
<form action="welcomeServlet" method="post">
<label>姓名:</label><input type="text" name="username" /><br />
<label>年龄:</label><input type="text" name="userage" /><br />
<input type="submit" value="提交" />
</form>
</body>
</html>
1.3.2、编写Servlet页面
package com.cxyzxc.www.demo01;
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;
@WebServlet("/welcomeServlet")
public class WelcomeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取表单提交的姓名
String username = req.getParameter("username");
//获取表单提交的年龄
String userage = req.getParameter("userage");
//服务器端输出获取到的数据
System.out.println("客户端发来的信息:姓名:"+username+",年龄:"+userage);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
1.3.3、浏览器提交
1.3.4、后台获取数据
1.4、get请求收参问题
get请求发送后,在服务器端获取数据产生乱码,是因为服务器和客户端沟通的编码不一致造成的,所以解决办法是在客户端和服务器之间设置一个统一的编码,之后就按照设置的编码进行数据的传输和接收。
1.5、get中文乱码
在Tomcat7及以下版本,客户端以UTF-8的编码传输数据到服务器端,而服务器端的request对象使用的是ISO8859-1这个字符编码来接收数据,服务器和客户端沟通的编码不一致,因此会产生中文乱码。
1)解决办法:在接收到数据后,先获取request对象以ISO8859-1字符编码接收到的原始数据的字节数组,然后通过字节数组以指定的编码构建字符串,解决乱码问题。
2)Tomcat8的版本中get不会出现乱码了,因为服务器对url的编码格式可以自动转换。
1.6、post中文乱码
由于客户端是以UTF-8字符编码将表单数据传输到服务器端的,因此服务器端也需要设置以UTF-8字符编码进行接收。
解决方法:使用从ServletRequest接口继承而来的setCharacterEncoding(charset)方法进行统一的编码设置。
2、response对象
response对象用于响应客户请求并向客户端输出信息
2.1、response主要方法
方法名称 | 方法作用 |
---|---|
setHeader(name,value) | 设置响应信息头 |
setContenType(String) | 设置响应文件类型、响应式的编码格式 |
setCharacterEncoding(String) | 设置服务端响应内容编码格式 |
getWriter() | 获取字符输出流 |
2.2、response应用
如果输出内容包含中文,则出现乱码,因为服务器默认采用ISO8859-1编码响应内容
2.3、解决输出中文乱码
方式一:设置服务器端响应的编码格式和设置客户端响应内容的头内容的文件类型及编码格式,这种方式不推荐
方式二:同时设置服务端的编码格式和客户端响应的文件类型及响应时的编码格式,推荐此方式