Servlet 入门教程
总结 《Servlet、JSP 和 Spring MVC 初学指南》 一书。
Servlet 是开发Web 项目的底层技术,封装了http请求,使用Servlet 可以只关注收发请求,而不用关注底层的建立连接的情况。在测试中经常会使用Servlet 开发挡板之类的小程序。
1. HTTP 协议
HTTP 第一个版本是0.9,之后是HTTP1.0,现在是HTTP1.1,Web 服务器7x24 不间断运行,并等待HTTP客户端(浏览器)来连接并请求资源。由客户端发起请求,服务器不会主动连接客户端。
1.1 URL 和 URI 的区别
URL = host 地址 + URI,如 http://example.com/test/index.html,host 地址是http://example.com,URI 则是 /test/index.html。可以理解为URL是在互联中请求的地址,URI 则是资源路径。
1.2 HTTP 请求
一个HTTP请求包含三部分内容:
①. 方法-URI-协议/版本
②. 请求头信息
③. 请求正文
如下为一个具体的示例:
POST example/default.jsp HTTP/1.1
Accept: text/plain; text/html
Accept-Language: en-us
Connection: Keep-Alive
…
lastName=Blanks&firstName=Mike
请求的第一行即是方法-URI-协议/版本,请求方法为post,URI 为 /example/default.jsp,协议是HTTP,版本是1.1 。HTTP 1.1 协议规定了7种方法,一般常用的是get和post,URI 定义了一个互联网资源,通常解析为服务器根目录的相对路径(例如 在tomcat 的 webapps 会部署项目),因此通常用/符号开头,另外URL 是 URI的一个具体类型(后续的servlet的request中,有两种方法分别可以获取请求的uri 和 url)。
HTTP请求头所包含的信息包含关于客户端环境和实体内容等非常有用的信息。例如,浏览器所设置的语言实体,内容长度,内容类型等,每个header 用回车/换行(CRLF)分隔。
HTTP请求头和请求正文用个空行分隔,HTTP 服务器根据此判断请求正文的起始位置。
1.3 HTTP 响应
同HTTP请求一样,HTTP响应包含三部分
①. 协议-状态码-描述
②. 响应头信息
③. 响应正文
响应头信息和请求头信息一样,响应正文和响应头之间也是用一个空行分隔。
附:请求头中的MIME 类型,MIME 类型即是指文件类型,在请求头和响应头的 Content-Type 中。
MIME 百度百科解释:MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。它是一个互联网标准,扩展了电子邮件标准,常见的MIME类型:
超文本标记语言文本 .html,.html text/html
普通文本 .txt text/plain
RTF文本 .rtf application/rtf
GIF图形 .gif image/gif
JPEG图形 .ipeg,.jpg image/jpeg
au声音文件 .au audio/basic
MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
MPEG文件 .mpg,.mpeg video/mpeg
AVI文件 .avi video/x-msvideo
GZIP文件 .gz application/x-gzip
TAR文件 .tar application/x-tar
用jmeter 或者 postman 工具发送http 请求有时需要设置Content-Type,才能请求成功。
2 Servlet
2.1 Servlet 接口中的方法
Servlet 技术的核心是Servlet,它是所有Servlet 必须直接或间接实现的一个接口,它有5个方法,其中三个是生命周期方法,另外两个是获取Servlet 信息。
2.1.1 生命周期相关方法
- init 方法:当Servlet 第一次被请求时,调用该方法,做一些初始化工作,调用这个方法时,Servlet 容器会传入一个 ServletConfig,一般来说会将ServletConfig 赋给一个累计变量,这个变量可以直接通过Servlet 类来访问。
- service 方法:每当请求Servlet 时,Servlet 容器就会调用这个方法。
- destroy 方法:销毁Servlet 时会调用该方法。
2.1.2 非生命周期相关方法
- getServletInfo 方法:返回Servlet 的描述,可以返回有意义的信息。 getServletConfig 方法:这个方法会返回由Servlet
- 容器传给init方法的ServletConfig,但是为了让该方法返回一个非null值,必须将init方法的ServletConfig赋给一个类变量。
2.2 ServletRequest
对于一个Servlet 请求,Servlet 容器都会创建一个ServletRequest 实例,并将它传给Servlet的service 方法,ServletRequest的一些方法:
- getContentLength(): 返回请求主题的字节数,int类型;
- getContentType(): 返回请求主题的MIME类型;
- getParameter(id): 返回请求的参数,是比较常用的方法,通过参数名来获取参数,还有类似的getParameters、getParameterMap、getParameterValues 获取表单域名、值以及查询字符串。
2.3 ServletResponse
在调用 service 方法前,servlet 容器会先创建一个 ServletResponse 对象,并作为第二个参数传给service方法。ServletResponse 比较常用的2个方法是 getWriter 方法,向客户端发送文本,getOutputStream 用于发送二进制数据。在发送文本前要先设置内容类型,为防止出现中文乱码,还要设置字符编码,如:
response.setContentType("text/html; charset = utf-8");
2.4 ServletConfig
对于每一个应用程序,Servlet 容器还会创建一个ServletContext实例,这个对象封装了上下文的应用详情,每个上下文只有一个ServletContext,每一个 Servlet实例也都有一个封装Servlet配置的ServletConfig。
当 Servlet 容器初始化Servlet 时,容器会给init方法传入一个ServletConfig ,ServletConfig 的封装可以通过@WebServlet 或者部署描述符传给Servlet 的配置信息,这样传入的每一条信息都叫一个初始参数,由key-value 组成,可以在ServleConfig通过调用getInitParameter 获得,例如:
@WebServlet(name = "ServletConfigDemoServlet",
urlPatterns = { "/servletconfigdemo" },
initParams = {
@WebInitParam(name="admin", value = "xcc"),
@WebInitParam(name="email", value = "xcc@123.com")
})
public class ServletConfigDemoServlet implements Servlet {
private static final long serialVersionUID = 1L;
private transient ServletConfig servletConfig;
初始参数 name 的值可以定义为任意需要的值。
2.5 ServletContext
ServletContext 表示Servlet应用程序上下文,每个Servlet只有一个ServletContext,在一个应用程序部署到分布式环境中,每个java 虚拟机上的web应用都会有一个ServletContext 对象,通过在ServletConfig中调用getServletContext方法可以获得ServletContext对象,有了ServletContext,就可以共享从应用程序的所有资料处访问到的信息,并且可以动态注册web对象。
2.6 HttpServlet
HttpServlet 继承至GenericServlet 类,GenericServlet 是实现了Servlet的一个抽象类,复写了Servlet的所有方法,并且新增了有关http method 的几个方法,如常用的doGet 和 doPost 方法,平常开发中经常使用的是HttpServlet,相应的请求中传递的参数为HttpServletRequest 和 HttpServletResponse。