一、Servlet概述

一个类型的Servlet只有一个实例对象,就会现时出一个Servlet同时处理多个请求。多个线程公用一个Servlet对象,所以Servlet是线程不安全的。但Servlet的工作效率很高
所以不应该在Servlet中创建成员变量,因为可能会存在一个线程对这个成员变量进行写操作,另一个线程对这个成员变量进行读操作。
特性:
单例(第一次访问时,被服务器创建),一个类只有一个对象;当然可能存在多个Servlet类,线程不安全的,效率是高的!
Servlet实现类由用户实现,但对象由服务器来创建,并且由服务器来调用相应的方法。

Servlet介绍

Servlet是JavaWeb的三大组件之一,它属于动态资源。Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:
接收请求数据;处理请求;完成响应。
例如客户端发出登录请求,这些请求都由Servlet来完成处理。Servlet需要用户自己来编写,每个Servlet必须实现javax.servlet.Servlet接口

Servlet实现方式

实现Servlet有三种方式:

  1. 实现javax.servlet.Servlet接口;
  2. 继承javax.servlet.GenericServlet类;
  3. 继承javax.servlet.http.HttpServlet类;

通常我们继承HttpServlet类来实现Servlet

  1. package javax.servlet;
  2. import java.io.IOException;
  3. public interface Servlet {
  4. public void init(ServletConfig config) throws ServletException;
  5. public ServletConfig getServletConfig();
  6. public void service(ServletRequest req, ServletResponse res)
  7. throws ServletException, IOException;
  8. public String getServletInfo();
  9. public void destroy();
  10. }

1.实现Servlet接口

  1. public class DemoServlet implements Servlet {
  2. public void init(ServletConfig config) throws ServletException {}
  3. public ServletConfig getServletConfig() {return null;}
  4. public void destroy() {}
  5. public String getServletInfo() {return null;}
  6. //用来处理请求的方法
  7. public void service(ServletRequest req, ServletResponse res)
  8. throws ServletException, IOException {
  9. System.out.println("hello servlet!");
  10. }
  11. }

配置web.xml
将访问路径与Servlet绑定到一起。即将访问路径:/demoworld与com.masterlu.servlet.DemoServlet绑定

  1. <servlet>
  2. <servlet-name>helloServlet</servlet-name>
  3. <servlet-class>com.masterlu.servlet.DemoServlet</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6. <servlet-name>demo</servlet-name>
  7. <!-- 指定Servlet的访问路径(必须以/开头),
  8. 可以配置多个,多个路径指向同一个Servlet。
  9. 也可以使用通配符配置路径(通配符不能出现在中间,只能作为前缀或后缀)。
  10. -->
  11. <url-pattern>/demoworld</url-pattern>
  12. <url-pattern>/demoworld2</url-pattern>
  13. <url-pattern>/servlet/*<url-patter>
  14. <url-pattern>*.do</url-pattern>
  15. </servlet-mapping>

2.继承GenericServlet

GenericServlet是Servlet接口的实现类,也可以通过继承GenericServlet来编写自己的Servlet。

  1. package javax.servlet;
  2. import java.io.IOException;
  3. import java.util.Enumeration;
  4. import java.util.ResourceBundle;
  5. public abstract class GenericServlet
  6. implements Servlet, ServletConfig, java.io.Serializable
  7. {
  8. private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
  9. private static ResourceBundle lStrings =
  10. ResourceBundle.getBundle(LSTRING_FILE);
  11. private transient ServletConfig config;
  12. public GenericServlet() { }
  13. @Override
  14. public void destroy() {
  15. }
  16. @Override
  17. public String getInitParameter(String name) {
  18. ServletConfig sc = getServletConfig();
  19. if (sc == null) {
  20. throw new IllegalStateException(
  21. lStrings.getString("err.servlet_config_not_initialized"));
  22. }
  23. return sc.getInitParameter(name);
  24. }
  25. @Override
  26. public Enumeration<String> getInitParameterNames() {
  27. ServletConfig sc = getServletConfig();
  28. if (sc == null) {
  29. throw new IllegalStateException(
  30. lStrings.getString("err.servlet_config_not_initialized"));
  31. }
  32. return sc.getInitParameterNames();
  33. }
  34. @Override
  35. public ServletConfig getServletConfig() {
  36. return config;
  37. }
  38. @Override
  39. public ServletContext getServletContext() {
  40. ServletConfig sc = getServletConfig();
  41. if (sc == null) {
  42. throw new IllegalStateException(
  43. lStrings.getString("err.servlet_config_not_initialized"));
  44. }
  45. return sc.getServletContext();
  46. }
  47. @Override
  48. public String getServletInfo() {
  49. return "";
  50. }
  51. @Override
  52. public void init(ServletConfig config) throws ServletException {
  53. this.config = config;
  54. this.init();
  55. }
  56. public void init() throws ServletException {
  57. }
  58. public void log(String msg) {
  59. getServletContext().log(getServletName() + ": "+ msg);
  60. }
  61. public void log(String message, Throwable t) {
  62. getServletContext().log(getServletName() + ": " + message, t);
  63. }
  64. @Override
  65. public abstract void service(ServletRequest req, ServletResponse res)
  66. throws ServletException, IOException;
  67. @Override
  68. public String getServletName() {
  69. ServletConfig sc = getServletConfig();
  70. if (sc == null) {
  71. throw new IllegalStateException(
  72. lStrings.getString("err.servlet_config_not_initialized"));
  73. }
  74. return sc.getServletName();
  75. }
  76. }

GenericServlet的init()方法

在GenericServlet中,定义ServletConfig config实例变量,并在init(ServletConfig)方法中把参数ServletConfig赋给了实例变量。然后该类的很多方法使用实例变量config。则子类需要完成一些初始化操作,只能覆盖GenericServlet提供的init()方法。它是没有参数的init()方法,它会在init(ServletConfig)方法中被调用。
如果子类覆盖GenericServlet的init(StringConfig)方法,那么this.config=config这一条语句就会被覆盖了,则config的值为null,那么所有依赖config的方法都不能使用。

实现了ServletConfig接口

GenericServlet还实现了ServletConfig接口,所以可以直接调用getInitParameter()、getServletContext()等ServletConfig的方法。

3.继承HttpServlet(常用方式)

HttpServlet类是GenericServlet的子类,提供了对HTTP请求的特殊支持,通常都会通过继承HttpServlet来完成自定义的Servlet。(SpringMVC的Servlet也是继承HttpServlet)

  1. package javax.servlet.http;
  2. import javax.servlet.*;
  3. public abstract class HttpServlet extends GenericServlet
  4. {
  5. private static final String METHOD_DELETE = "DELETE";
  6. private static final String METHOD_HEAD = "HEAD";
  7. private static final String METHOD_GET = "GET";
  8. private static final String METHOD_OPTIONS = "OPTIONS";
  9. private static final String METHOD_POST = "POST";
  10. private static final String METHOD_PUT = "PUT";
  11. private static final String METHOD_TRACE = "TRACE";
  12. private static final String HEADER_IFMODSINCE = "If-Modified-Since";
  13. private static final String HEADER_LASTMOD = "Last-Modified";
  14. private static final String LSTRING_FILE =
  15. "javax.servlet.http.LocalStrings";
  16. private static ResourceBundle lStrings =
  17. ResourceBundle.getBundle(LSTRING_FILE);
  18. public HttpServlet() { }
  19. protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  20. throws ServletException, IOException
  21. {
  22. String protocol = req.getProtocol();
  23. String msg = lStrings.getString("http.method_get_not_supported");
  24. if (protocol.endsWith("1.1")) {
  25. resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
  26. } else {
  27. resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
  28. }
  29. }
  30. protected long getLastModified(HttpServletRequest req) {
  31. return -1;
  32. }
  33. protected void doHead(HttpServletRequest req, HttpServletResponse resp)
  34. throws ServletException, IOException
  35. {
  36. NoBodyResponse response = new NoBodyResponse(resp);
  37. doGet(req, response);
  38. response.setContentLength();
  39. }
  40. protected void doPost(HttpServletRequest req, HttpServletResponse resp)
  41. throws ServletException, IOException
  42. {
  43. String protocol = req.getProtocol();
  44. String msg = lStrings.getString("http.method_post_not_supported");
  45. if (protocol.endsWith("1.1")) {
  46. resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
  47. } else {
  48. resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
  49. }
  50. }
  51. protected void doPut(HttpServletRequest req, HttpServletResponse resp)
  52. throws ServletException, IOException
  53. {
  54. String protocol = req.getProtocol();
  55. String msg = lStrings.getString("http.method_put_not_supported");
  56. if (protocol.endsWith("1.1")) {
  57. resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
  58. } else {
  59. resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
  60. }
  61. }
  62. protected void doDelete(HttpServletRequest req,
  63. HttpServletResponse resp)
  64. throws ServletException, IOException
  65. {
  66. String protocol = req.getProtocol();
  67. String msg = lStrings.getString("http.method_delete_not_supported");
  68. if (protocol.endsWith("1.1")) {
  69. resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
  70. } else {
  71. resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
  72. }
  73. }
  74. private Method[] getAllDeclaredMethods(Class<? extends HttpServlet> c) {
  75. Class<?> clazz = c;
  76. Method[] allMethods = null;
  77. while (!clazz.equals(HttpServlet.class)) {
  78. Method[] thisMethods = clazz.getDeclaredMethods();
  79. if (allMethods != null && allMethods.length > 0) {
  80. Method[] subClassMethods = allMethods;
  81. allMethods =
  82. new Method[thisMethods.length + subClassMethods.length];
  83. System.arraycopy(thisMethods, 0, allMethods, 0,
  84. thisMethods.length);
  85. System.arraycopy(subClassMethods, 0, allMethods, thisMethods.length,
  86. subClassMethods.length);
  87. } else {
  88. allMethods = thisMethods;
  89. }
  90. clazz = clazz.getSuperclass();
  91. }
  92. return ((allMethods != null) ? allMethods : new Method[0]);
  93. }
  94. protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
  95. throws ServletException, IOException
  96. {
  97. Method[] methods = getAllDeclaredMethods(this.getClass());
  98. boolean ALLOW_GET = false;
  99. boolean ALLOW_HEAD = false;
  100. boolean ALLOW_POST = false;
  101. boolean ALLOW_PUT = false;
  102. boolean ALLOW_DELETE = false;
  103. boolean ALLOW_TRACE = true;
  104. boolean ALLOW_OPTIONS = true;
  105. for (int i=0; i<methods.length; i++) {
  106. String methodName = methods[i].getName();
  107. if (methodName.equals("doGet")) {
  108. ALLOW_GET = true;
  109. ALLOW_HEAD = true;
  110. } else if (methodName.equals("doPost")) {
  111. ALLOW_POST = true;
  112. } else if (methodName.equals("doPut")) {
  113. ALLOW_PUT = true;
  114. } else if (methodName.equals("doDelete")) {
  115. ALLOW_DELETE = true;
  116. }
  117. }
  118. // we know "allow" is not null as ALLOW_OPTIONS = true
  119. // when this method is invoked
  120. StringBuilder allow = new StringBuilder();
  121. if (ALLOW_GET) {
  122. allow.append(METHOD_GET);
  123. }
  124. if (ALLOW_HEAD) {
  125. if (allow.length() > 0) {
  126. allow.append(", ");
  127. }
  128. allow.append(METHOD_HEAD);
  129. }
  130. if (ALLOW_POST) {
  131. if (allow.length() > 0) {
  132. allow.append(", ");
  133. }
  134. allow.append(METHOD_POST);
  135. }
  136. if (ALLOW_PUT) {
  137. if (allow.length() > 0) {
  138. allow.append(", ");
  139. }
  140. allow.append(METHOD_PUT);
  141. }
  142. if (ALLOW_DELETE) {
  143. if (allow.length() > 0) {
  144. allow.append(", ");
  145. }
  146. allow.append(METHOD_DELETE);
  147. }
  148. if (ALLOW_TRACE) {
  149. if (allow.length() > 0) {
  150. allow.append(", ");
  151. }
  152. allow.append(METHOD_TRACE);
  153. }
  154. if (ALLOW_OPTIONS) {
  155. if (allow.length() > 0) {
  156. allow.append(", ");
  157. }
  158. allow.append(METHOD_OPTIONS);
  159. }
  160. resp.setHeader("Allow", allow.toString());
  161. }
  162. protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
  163. throws ServletException, IOException
  164. {
  165. int responseLength;
  166. String CRLF = "\r\n";
  167. StringBuilder buffer = new StringBuilder("TRACE ").append(req.getRequestURI())
  168. .append(" ").append(req.getProtocol());
  169. Enumeration<String> reqHeaderEnum = req.getHeaderNames();
  170. while( reqHeaderEnum.hasMoreElements() ) {
  171. String headerName = reqHeaderEnum.nextElement();
  172. buffer.append(CRLF).append(headerName).append(": ")
  173. .append(req.getHeader(headerName));
  174. }
  175. buffer.append(CRLF);
  176. responseLength = buffer.length();
  177. resp.setContentType("message/http");
  178. resp.setContentLength(responseLength);
  179. ServletOutputStream out = resp.getOutputStream();
  180. out.print(buffer.toString());
  181. }
  182. protected void service(HttpServletRequest req, HttpServletResponse resp)
  183. throws ServletException, IOException
  184. {
  185. String method = req.getMethod();
  186. if (method.equals(METHOD_GET)) {
  187. long lastModified = getLastModified(req);
  188. if (lastModified == -1) {
  189. // servlet doesn't support if-modified-since, no reason
  190. // to go through further expensive logic
  191. doGet(req, resp);
  192. } else {
  193. long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
  194. if (ifModifiedSince < lastModified) {
  195. // If the servlet mod time is later, call doGet()
  196. // Round down to the nearest second for a proper compare
  197. // A ifModifiedSince of -1 will always be less
  198. maybeSetLastModified(resp, lastModified);
  199. doGet(req, resp);
  200. } else {
  201. resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
  202. }
  203. }
  204. } else if (method.equals(METHOD_HEAD)) {
  205. long lastModified = getLastModified(req);
  206. maybeSetLastModified(resp, lastModified);
  207. doHead(req, resp);
  208. } else if (method.equals(METHOD_POST)) {
  209. doPost(req, resp);
  210. } else if (method.equals(METHOD_PUT)) {
  211. doPut(req, resp);
  212. } else if (method.equals(METHOD_DELETE)) {
  213. doDelete(req, resp);
  214. } else if (method.equals(METHOD_OPTIONS)) {
  215. doOptions(req,resp);
  216. } else if (method.equals(METHOD_TRACE)) {
  217. doTrace(req,resp);
  218. } else {
  219. //
  220. // Note that this means NO servlet supports whatever
  221. // method was requested, anywhere on this server.
  222. //
  223. String errMsg = lStrings.getString("http.method_not_implemented");
  224. Object[] errArgs = new Object[1];
  225. errArgs[0] = method;
  226. errMsg = MessageFormat.format(errMsg, errArgs);
  227. resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
  228. }
  229. }
  230. /**
  231. * Dispatches client requests to the protected
  232. * <code>service</code> method. There's no need to
  233. * override this method.
  234. *
  235. * @param req the {@link HttpServletRequest} object that
  236. * contains the request the client made of
  237. * the servlet
  238. *
  239. * @param res the {@link HttpServletResponse} object that
  240. * contains the response the servlet returns
  241. * to the client
  242. *
  243. * @throws IOException if an input or output error occurs
  244. * while the servlet is handling the
  245. * HTTP request
  246. *
  247. * @throws ServletException if the HTTP request cannot
  248. * be handled or if either parameter is not
  249. * an instance of its respective {@link HttpServletRequest}
  250. * or {@link HttpServletResponse} counterparts.
  251. *
  252. * @see javax.servlet.Servlet#service
  253. */
  254. @Override
  255. public void service(ServletRequest req, ServletResponse res)
  256. throws ServletException, IOException
  257. {
  258. HttpServletRequest request;
  259. HttpServletResponse response;
  260. if (!(req instanceof HttpServletRequest &&
  261. res instanceof HttpServletResponse)) {
  262. throw new ServletException("non-HTTP request or response");
  263. }
  264. request = (HttpServletRequest) req;
  265. response = (HttpServletResponse) res;
  266. service(request, response);
  267. }
  268. }

HttpServlet#service(HttpServletRequest,HttpServletResponse)方法,判断当前请求是GET还是POST,如果是GET请求,那么会去调用本类的doGet()方法,如果是POST请求会去调用doPost()方法。用户在子类中去覆盖doGet()或doPost()方法即可
image.png

二、Servlet生命周期

生命周期相关方法
void init(ServletConfig);
void service(ServletRequest,ServletResponse);
void destroy();

1.Servlet初始化方法

默认情况下,Servlet实例,在Servlet第一次被访问时,由服务器创建(或者在web.xml文件中配置,使得在服务器启动时创建Servlet实例)。
一个Servlet类型,服务器只创建一个实例对象,例如在首次访问http://localhost:8080/appName/demoworld时,服务器通过“/helloworld”找到绑定的Servlet名称为com.masterlu.servlet.DemoServlet,然后服务器查看这个类型的Servlet是否已经创建过,如果没有创建过,那么服务器会通过反射来创建DemoServlet的实例。再次访问http://localhost:8080/helloservlet/helloworld时,服务器就不会再次创建DemoServlet实例了,而是直接使用上次创建的实例。
在Servlet被创建后,服务器会立刻调用Servlet的void init(ServletConfig)方法。init方法只会被调用一次。
利用这个特性,可以把Servlet的初始化工作放到init方法中。

  1. <servlet>
  2. <servlet-name>helloServlet</servlet-name>
  3. <servlet-class>com.masterlu.servlet.DemoServlet</servlet-class>
  4. <!-- 服务器在启动时就创建该Servlet,其中<load-on-startup>元素的值必须是大于等于0的整数,
  5. 数字越小优先级越高-->
  6. <load-on-startup>0</load-on-startup>
  7. </servlet>

2.Servlet服务方法

用户每次请求服务器时,服务器都会调用Servlet#service()方法来处理请求。因为service()方法可以被多次调用,所以我们才需要把处理请求的代码写到service()方法中。

3.Servlet销毁方法

在服务器被关闭时,服务器会去销毁Servlet,在销毁Servlet之前服务器会先去调用Servlet的destroy()方法,我们可以把Servlet的销毁逻辑放到destroy()方法中,例如对某些资源的释放等代码放到destroy()方法中。

三、Servlet接口用到的对象

ServletConfig
init()方法的参数,表示Servlet配置对象,它对应Servlet的配置信息,即:对应web.xml的元素。
ServletRequest
由服务器创建的请求对象,它封装了所有与请求相关的数据;
ServletResponse
由服务器创建的响应对象,在service()方法中完成对客户端的响应,需要使用这个对象;
ServletRequest和ServletResponse的实例由服务器创建,然后传递给Servlet#service() 。一个是请求对象,一个是响应对象,可以从ServletRequest对象中获取请求数据,可以使用ServletResponse对象完成响应。
如果在service() 方法中使用HTTP相关的功能,可以把ServletRequest和ServletResponse强转成HttpServletRequest和HttpServletResponse。

HttpServletRequest方法

String getParameter(String paramName)
获取指定请求参数的值;
String getMethod()
获取请求方法,例如GET或POST;
String getHeader(String name)
获取指定请求头的值;
void setCharacterEncoding(String encoding)
设置请求体的编码!因为GET请求没有请求体,所以这个方法仅对POST请求有效。当调用request.setCharacterEncoding(“utf-8”)之后,再调用getParameter()方法获取参数值时,则参数值都已经转换成UTF-8编码。所以这个方法必须在调用getParameter()方法之前调用

HttpServletResponse方法

PrintWriter getWriter()
获取字符响应流,使用该流向客户端输出响应信息。例如response.getWriter().print(“

Hello JavaWeb!

”);
ServletOutputStream getOutputStream()
获取字节响应流,使用该流向客户端响应字节数据,例如要向客户端响应图片;
void setCharacterEncoding(String encoding)
用来设置字符响应流的编码,例如在调用setCharacterEncoding(“utf-8”);之后,再response.getWriter()获取字符响应流对象,响应流的编码为utf-8,使用response.getWriter()输出的中文都会转换成utf-8编码后发送给客户端;
void setHeader(String name, String value)
向客户端添加响应头信息,例如setHeader(“Refresh”, “3;url=http://www.baidu.com”),表示3秒后自动刷新到http://www.baidu.com;
void setContentType(String contentType)
是setHeader(“content-type”, “xxx”)的简便方法,即用来添加名为content-type响应头的方法。content-type响应头用来设置响应数据的MIME类型
例如要向客户端响应jpg的图片,那么可以setContentType(“image/jepg”),
如果响应数据为文本类型,且同时设置编码,例如setContentType(“text/html;chartset=utf-8”)表示响应数据类型为文本类型中的html类型,并且该方法会调用setCharacterEncoding(“utf-8”)方法;
void sendError(int code, String errorMsg)
向客户端发送状态码,以及错误消息。例如给客户端发送404:response(404, “您要查找的资源不存在!”)。

ServletConfig

对应web.xml文件中的元素。ServletConfig对象是由服务器创建的,然后传递给Servlet的init()方法,你可以在init()方法中使用它!
String getServletName()
获取Servlet在web.xml文件中的配置名称,即指定的名称;servletConfig.getInitParameter(“paramName1”);//获取到paramValue1
ServletContext getServletContext()
用来获取ServletContext对象。
String getInitParameter(String name)
用来获取在web.xml中配置的初始化参数,通过参数名来获取参数值;
Enumeration getInitParameterNames()
用来获取在web.xml中配置的所有初始化参数名称;

  1. <servlet>
  2. <servlet-name>helloServlet</servlet-name>
  3. <servlet-class>com.masterlu.servlet.DemoServlet</servlet-class>
  4. </servlet>
  5. <init-param>
  6. <param-name>paramName1</param-name>
  7. <param-value>paramValue1</param-value>
  8. </init-param>
  9. <init-param>
  10. <param-name>paramName2</param-name>
  11. <param-value>paramValue2</param-value>
  12. </init-param>
  13. </servlet>

四、web.xml文件继承

每一个javaWeb应用中都需要有web.xml文件,应用中的web.xml都有一个共同的父文件(tomca的conf/web.xml)。
tomca中conf/web.xml相当于写到项目中web.xml中

  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <web-app xmlns="http://java.sun.com/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  5. http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  6. version="3.0">
  7. <!-- 它的优先级最低的Servlet
  8. 1.当访问路径不存在时,会执行该Servlet,
  9. 2.在访问index.html时也是在执行这个Servlet。
  10. -->
  11. <servlet>
  12. <servlet-name>default</servlet-name>
  13. <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
  14. <init-param>
  15. <param-name>debug</param-name>
  16. <param-value>0</param-value>
  17. </init-param>
  18. <init-param>
  19. <param-name>listings</param-name>
  20. <param-value>false</param-value>
  21. </init-param>
  22. <load-on-startup>1</load-on-startup>
  23. </servlet>
  24. <servlet>
  25. <servlet-name>jsp</servlet-name>
  26. <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
  27. <init-param>
  28. <param-name>fork</param-name>
  29. <param-value>false</param-value>
  30. </init-param>
  31. <init-param>
  32. <param-name>xpoweredBy</param-name>
  33. <param-value>false</param-value>
  34. </init-param>
  35. <load-on-startup>3</load-on-startup>
  36. </servlet>
  37. <!-- 匹配所有URL,即用户访问的URL路径没有匹配的页面时,那么执行的就是名为default的Servlet,
  38. 即org.apache.catalina.servlets.DefaultServlet -->
  39. <servlet-mapping>
  40. <servlet-name>default</servlet-name>
  41. <url-pattern>/</url-pattern>
  42. </servlet-mapping>
  43. <!-- 任何URL后缀为jsp的访问,都会执行名为jsp的Servlet,
  44. 即org.apache.jasper.servlet.JspServlet
  45. -->
  46. <servlet-mapping>
  47. <servlet-name>jsp</servlet-name>
  48. <url-pattern>*.jsp</url-pattern>
  49. <url-pattern>*.jspx</url-pattern>
  50. </servlet-mapping>
  51. <!-- session的默认超时时间为30分钟 -->
  52. <session-config>
  53. <session-timeout>30</session-timeout>
  54. </session-config>
  55. <!-- 省略了大多数tomcat配置的MIME类型的定义,这里只给出两种MIME类型的定义 -->
  56. <mime-mapping>
  57. <extension>bmp</extension>
  58. <mime-type>image/bmp</mime-type>
  59. </mime-mapping>
  60. <mime-mapping>
  61. <extension>htm</extension>
  62. <mime-type>text/html</mime-type>
  63. </mime-mapping>
  64. <!-- 设置默认主页为index.html、index.html、index.jsp -->
  65. <welcome-file-list>
  66. <welcome-file>index.html</welcome-file>
  67. <welcome-file>index.htm</welcome-file>
  68. <welcome-file>index.jsp</welcome-file>
  69. </welcome-file-list>
  70. </web-app>

五、ServletContext

一个项目只有一个ServletContext对象,在整个Web应用的动态资源之间实现共享数据。可以在所有Servlet中来获取这个唯一的对象,使用它可以给多个Servlet传递数据!对象在Tomcat启动时就创建,在Tomcat关闭时销毁!

获取ServletContext

ServletConfig#getServletContext();
GenericServlet#getServletContext();
HttpSession#getServletContext()
ServletContextEvent#getServletContext()

域对象的功能

JavaWeb四大域对象
PageContext、ServletRequest、HttpSession、ServletContext;
所有域对象都有存取数据的功能,因为域对象内部有一个Map,用来存储数据。
ServletContext对象用来操作数据的方法:
void setAttribute(String name, Object value)
存储一个域属性。如果多次调用该方法,并且使用相同的name,那么会覆盖上一次的值;
Object getAttribute(String name)
获取ServletContext中的数据
void removeAttribute(String name)
用来移除ServletContext中的域属性,如果参数name指定的域属性不存在,那么本方法什么都不做;
Enumeration getAttributeNames()
获取所有域属性的名称;

获取应用初始化参数

配置公共的初始化参数,为所有Servlet而用!需要使用ServletContext才能使用

<web-app ...>
  <context-param>
    <param-name>paramName1</param-name>
    <param-value>paramValue1</param-value>      
  </context-param>
  <context-param>
    <param-name>paramName2</param-name>
    <param-value>paramValue2</param-value>      
  </context-param>
</web-app>
        ServletContext context = this.getServletContext();
        String value1 = context.getInitParameter("paramName1");
        String value2 = context.getInitParameter("paramName2");
        System.out.println(value1 + ", " + value2);

        Enumeration names = context.getInitParameterNames();
        while(names.hasMoreElements()) {
            System.out.println(names.nextElement());
        }