Servlet (Server Applet,Java服务器小程序)
一、概述
1.1 概念
指用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容,狭义的Servlet
是指Java语言实现的一个接口,广义的Servlet
是指任何实现了这个Servlet
接口的类
理解:实现Servlet接口
,响应客户端请求,返回消息
1.2 Servlet 容器
- 管理和运行
servlet
(不需要自己实现网络通信,容器自己知道通信协议) - 控制
servlet
的生命周期 - 自己就支持多线程
1.3 Tomcat
tomcat 就是servlet容器
二、Servlet API
servlet 下有四个包
javax.servlet
,包含定义servlet
和servlet容器
之间契约的类和接口。javax.servlet.http
,包含定义HTTP Servlet
和Servlet容器
之间的关系。javax.servlet.annotation
,包含标注servlet
,Filter
,Listener
的标注。它还为被标注元件定义元数据。javax.servlet.descriptor
,包含提供程序化登录Web应用程序的配置信息的类型。
三、Servlet 工作流程
用户发出请求,Servlet容器调用Servlet的service()
方法,并传入一个ServletRequest队形和一个ServletResponse,而ServletRequest和ServletResponse中封装了当前用户的Http请求
要注意的是:每一个应用程序,Servlet容器只会创建一个ServletContext
对象。ServletContext
对象中封装了应用程序的上下文环境信息。每个Servlet对象也都有一个封装Servlet配置的ServletConfig
对象。
四、重点 Servlet生命周期
三个方法:init(),service(),destroy()
-
init(),初始化
Servlet容器加载完Servlet后,Servlet容器会创建一个Servlet实例并调用
init()
方法,init()
方法只会调用一次,客户端第一次请求时,会触发这个方法,只执行一次一般用于创建或打开任何与servlet相的资源和初始化
-
service(),处理客户端请求
每收到一个客户端请求,服务器就会产生一个新的线程去处理,由web容器调用,根据HTTP请求方法(GET、POST等),将请求分发到
doGet()
、doPost()
等方法 -
destroy(),终止销毁
在servlet实例被销毁时调用,Servlet规范确保在
destroy()
方法调用之前所有请求的处理均完成一般用于释放
init()
占用的资源
要注意的是:servlet 是线程不安全的,多线程处理的时候要注意锁问题
五、 ServletRequest 、 ServletResponse
5.1 ServletRequest 中常用的方法
getParameter(String var1);//返回请求参数的值
5.2 ServletResponse 中常用的方法
-
ServletOutputStream getOutputStream() throws IOException;
获得字节流,write(byte[] bytes)可以向response缓冲区中写入字节,通过Tomcat发送给客户端
-
void setCharacterEncoding(String var1);
设置编码方式
-
PrintWriter getWriter() throws IOException;
注意,这个地方的
PrintWriter
对象默认使用ISO-8859-1编码
六、ServletContext
之前提到 ServletContext 对象
在ServletConfig中调用 getServletContext()
方法可以获取到这个应用的 ServletContext 对象
要注意的是:源码如下,删减了一些和servlet,filter相关的方法,没错servlet
、filter
,就是这个接口中的方法维护的,包括熟悉的 Attribute
、Session
、CharacterEncoding
都在这
public interface ServletContext {
//略
Object getAttribute(String var1);
Enumeration<String> getAttributeNames();
void setAttribute(String var1, Object var2);
void removeAttribute(String var1);
SessionCookieConfig getSessionCookieConfig();
int getSessionTimeout();
void setSessionTimeout(int var1);
String getRequestCharacterEncoding();
void setRequestCharacterEncoding(String var1);
String getResponseCharacterEncoding();
void setResponseCharacterEncoding(String var1);
//略
}
七、HttpServlet
HttpServlet抽象类是继承于GenericServlet
抽象类
HttpServletRequest
和 HttpServletResponse
接口分别继承 ServletRequest
和 ServletResponse
接口
6.1 HttpServletRequest
HttpServletRequest 表示Http环境中的Servlet请求
public interface HttpServletRequest extends ServletRequest {
//略
Cookie[] getCookies();//返回一个cookie对象数组
String getHeader(String var1);//返回指定HTTP标题的值
String getMethod();//返回生成这个请求HTTP的方法名称
String getContextPath();//返回请求上下文的请求URI部分
HttpSession getSession();//返回与这个请求相关的会话对象
//略
}
6.2 HttpServletResponse
可以发现各种set,send方法,就是返回给客户端时候输出的信息,不过没有发现 getWriter()
方法,这个方法在他的父类 ServletResponse
里面了
public interface HttpServletResponse extends ServletResponse {
//略
void addCookie(Cookie var1);
boolean containsHeader(String var1);
String encodeURL(String var1);
String encodeRedirectURL(String var1);
void sendError(int var1, String var2) throws IOException;
void sendError(int var1) throws IOException;
void sendRedirect(String var1) throws IOException;
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
void setStatus(int var1);
int getStatus();
String getHeader(String var1);
//略
}
八、编码问题
Service 默认使用 ISO-8859-1编码
注意:使用 filter 过滤所有请求把request进行编码就可以
面试笔试:
-
servlet生命周期
分三部分
- Web容器加载servlet,调用init方法
- 客户端请求时,调用service方法,执行对应请求的方法
- 销毁,当服务停止的时候,web容器调用distroy()方法销毁servlet
-
get和post有什么区别
- get的参数是拼接在url后面,用户在浏览器地址栏可以看到。post是放在http包的包体中
- get方式能提交的数据只能是文本,且大小不超过1024个字节,而post不仅可以提交文本还有二进制文件,文件上传用post
-
会话跟踪
原因,HTTP的请求是响应式的,用户请求,服务器响应,服务器不不知道下一次请求的还是不是同一客户端
四种会话跟踪技术, Cookie、URL重写、隐藏的表单域、session