目录
# Tomcat 版本
# Servlet
# ServletRequest
# 异步处理
# Servlet Context
# ServletResponse
# 过滤器
# Session
# Annotation
# Web fragment
# RequestDispatcher
# Web App
# 错误处理
# 欢迎页面
# Tomcat 版本
Tomcat 7.x:JDK 7/Servlet 3.0/JSP 2.2/EL 2.2
Tomcat 6.x:JDK 6/Servlet 2.5/JSP 2.1
# Servlet
Servlet接口2个类:GenericServlet,HttpServlet
一般,容器只创建一个Servlet实例,并发的请求使用同一个实例进行处理,因此,Servlet 不是线程安全的
Servlet 若实现 SingleThreadModel,则容器会创建多个实例,确保每个实例同时只在一个线程内运行。但是,规范不推荐使用 SingleThreadModel
两个生命周期回调方法:init() 和 destroy()
o 路径映射
路径格式:
– 以 / 开头,以/* 结尾的,用最长匹配
– 以 * 开头的,用扩展名匹配
– 空串(””),匹配Context Path
– 仅/字符,匹配默认Servlet
– 所有其他的,严格匹配
如果某URL出现多个匹配,优先顺序:
– 严格匹配
– 最长匹配
– 扩展名匹配
# ServletRequest
接口 ServletRequest,HttpServletRequest
类 HttpServletRequestWrapper
o 生命周期:请求对象失效后,被容器回收后可能被重用,应用程序不应该依赖于超出有效范围的请求对象
o 请求参数
客户端提交的请求参数,通过 HttpServletRequest.getParameterXxx() 方法读取
表单数据如果是POST方法提交,则编码类型必须是 application/x-www-form-urlencoded ,表单数据才作为参数,否则,美国空间,表单数据在 HTTP 请求 body 内,只能通过 InputStream 读取
文件上传(File upload)须使用 multipart/form-data 表单类型,且Servlet 添加 @MultipartConfig 标记
文件上传数据的读取:getPart(),getParts()
o 属性
属性(Attribute)是容器设置,香港虚拟主机,或应用程序设置,方法:setAttribute(),getAttributeXxx()
以 java,javax,网站空间,sun开头的属性名称保留
SSL有关的属性,容器以属性的形式提供
判断是否SSL:isSecure()
o HTTP 头:getHeaderXxx(),getXxxHeader()
o 请求路径
请求路径包含3部分
– Context Path:Web 应用的根路径,如果Web应用为默认应用,则为””,getContextPath()
– Servlet Path:Context Path 后面,Servlet 映射路径
– Path Info:如果Servlet映射路径使用了通配符,Servlet Path 后面的部分为 Path Info
如,主机为,Web应用为 some.war,某一Servlet 映射路径为 /oneServlet/*,客户端请求 ,则
– Context Path = /some
– Servlet Path = /oneServlet
– Path Info = /any/file
忽略URL编码,requestURI = contextPath + servletPath + pathInfo
o 获取本地路径
可将请求路径转换为服务器本地文件系统路径
– ServletContext.getRealPath():将相对于 Context Path 的路径转换为本地物理路径
– HttpServletRequest.getPathTranslated() :将该请求的 Path Info 转换为本地物理路径
o getCookies() 获取 Cookie
o I18N
HTTP请求中 Accept-Language 头,可通过以下方法读取:getLocale(),getLocales()
o 请求的字符编码
getCharacterEncoding(),如果客户端未指定(Content-Type头),则返回 null,容器默认使用 ISO-8859-1
setCharacterEncoding() 覆盖客户端提交的字符编码
# 异步处理
如果 Servlet.service() 方法内需要等待另一资源可用,如数据库连接,会导致线程等待,降低了容器的线程利用率
异步处理的基本思路是,应用程序起一个子线程,在子线程内执行导致线程等待的工作,让 service() 尽快返回
ServletRequest.startAsync() 使请求进入异步模式,在异步模式下,退出service() 不会提交Response 到客户端,而是要等到
– 异步处理完成。通过调用 AsyncContext.complete() 通知容器,AsyncContext 由 startAsync() 返回
– 异步处理超时
(对于在Web容器内起应用程序线程,个人持保留态度)
# Servlet Context
ServletContext 是Web app的访问接口
Web app 在服务器上的路径为 :port/contentRoot
每个 Web app 只有一个 ServletContext 实例
o 初始化参数
设置:通过 web.xml
读取:getInitParameterXxx()
o 编程增加Servlet,Filter和Listener
ServletContext 提供方法,可在Web app 初始化时创建、配置 Servlet、Filter 和 Listener,如同在 web.xml 中声明一样
– addServlet/Filter/Listener()
– createServlet/Filter/Listener()
– getServlet/Filter/ListenerRegistration()
– getServlet/Filter/ListenerRegistrations()
o 属性
ServletContext 的属性对象可以被Web app 内任意组件访问
– setAttribute()
– getAttribute()
– getAttributeNames()
– removeAttribute()
o 读取资源
可读取 Web app 内的静态资源文件,如:HTML
– getResource()
– getResourceAsStream()
o 临时文件夹
容器要为每个Webapp 提供一个临时文件夹
File dir = (File) servletContext.getAttribute(“javax.servlet.context.tempdir”);
# ServletResponse
HttpServletResponse 表示给客户端的HTTP响应
ServletResponse 对象应该只在其有效范围(Servlet.service())内使用
o 缓冲
返回客户端的数据,可以通过 OutputStream 或 PrintWriter 写出去,也可以先写入缓冲区,再提交到客户端
ServletResponse 提供以下方法
– getBufferSize()
– setBufferSize()
– reset()
– resetBuffer()
– flushBuffer()
– isCommitted()
o HTTP 头
setHeader()
addHeader()
setXxxHeader()
addXxxHeader()
o 便利方法
– sendRedirect() 重定向
– sendError() 返回HTTP错误页面
o I18N
– setLocale()
– setContentType()
– setCharacterEncoding()
# 过滤器
接口 Filter
过滤器可在请求到达Servlet前对 Request 和 Response 对象进行修改
也可在Servlet 处理之后、发送给客户端之前,对 Response 进行修改
过滤器可通过包装(Wrap)的方式修改 Request或Response 头
生命周期:init(),doFilter(),destroy()
init() 时,容器提供 FilterConfig 参数,通过FilterConfig,Filter 可
– 获取初始化参数:getInitParameterXxx()
– 获取 ServletContext:getServletContext()
doFilter() 接收 FilterChain 参数,须显式调用其 doFilter() 方法以调用下一个过滤器
下一个 Filter.doFilter() 执行之后,可修改 Response 对象
FilterChain 中的 Filter.doFilter() 形成一个函数调用栈,因此,程序流程是沿着FilterChain的一次往复过程,先从头至尾经过每一个Filter,再按相反顺序回到第一个Filter
o Filter 的配置
首先在 web.xml 中配置 Filter
……… 却不去主动改变,而是放任它的生活态度。