@[TOC](Servlet学习笔记三)
一、自启动 Servlet
1、自启动 Servlet 的特点
自动启动 Servlet 表示在 Tomcat 启动时就会实例化这个 Servlet,他的实例化过程不依赖于请求,而是依赖容器的启动。
可以通过在 web.xml 中的标签中通过1配置自启动 Servlet。
//自启动Servlet特点
public class AutoStartServlet extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("Servlet Init........");
}
}
web.xml:
<servlet>
<servlet-name>autoStartServlet</servlet-name>
<servlet-class>servlet.AutoStartServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>autoStartServlet</servlet-name>
<url-pattern>/auto.do</url-pattern>
</servlet-mapping>
2、通过自启动Servlet实现配置信息的读取
需求:修改文件下载案例,通过自启动 Servlet 读取配置信息。
//自启动Servlet特点
public class AutoStartServlet extends HttpServlet {
@Override
public void init() throws ServletException {
ServletConfig servletConfig = this.getServletConfig();
String value = servletConfig.getInitParameter("path");
ServletContext servletContext = this.getServletContext();
servletContext.setAttribute("path",value);
}
}
之前下载文件时的路径:
String realPath = servletContext.getRealPath("image/aa.png");
使用自启动Servlet后:
//获取ServletContext对象
ServletContext servletContext = this.getServletContext();
String path = (String)servletContext.getAttribute("path");
System.out.println(path);
//路径转换
String realPath = servletContext.getRealPath(path+"/aa.png");
web.xml:
<servlet>
<servlet-name>autoStartServlet</servlet-name>
<servlet-class>servlet.AutoStartServlet</servlet-class>
<init-param>
<param-name>path</param-name>
<param-value>image</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>autoStartServlet</servlet-name>
<url-pattern>/auto.do</url-pattern>
</servlet-mapping>
二、Servlet 线程安全问题
在 Servlet 中使用的是多线程方式来执行 service()方法处理请求,所以我们在使用 Servlet时需要考虑到线程安全问题,在多线程中对于对象中的成员变量是最不安全的,所以不要在Servlet 中通过成员变量的方式来存放数据,如果一定要使用成员变量存储数据,在对数据进行操作时需要使用线程同步的方式来解决线程安全问题,避免出现数据张冠李戴现象。
//Servlet 线程安全问题
public class ThreadSafeServlet extends HttpServlet {
private PrintWriter pw;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
synchronized (this){
pw = resp.getWriter();
try{
Thread.sleep(5000);
pw.println(name);
pw.flush();
pw.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
web.xml:
<servlet>
<servlet-name>threadSafeServlet</servlet-name>
<servlet-class>servlet.ThreadSafeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>threadSafeServlet</servlet-name>
<url-pattern>/safe.do</url-pattern>
</servlet-mapping>
运行结果:
三、Servlet 的 url-pattern 配置
1、URL 的匹配规则
1.1、精确匹配
精确匹配是指中配置的值必须与 url 完全精确匹配。
1.2、扩展名匹配
在允许使用统配符“”作为匹配规则,“”表示匹配任意字符。在扩展名匹配中只要扩展名相同都会被匹配和路径无关。注意,在使用扩展名匹配时在中不能使用“/”,否则容器启动就会抛出异常。
1.3、路径匹配
根据请求路径进行匹配,在请求中只要包含该路径都匹配。“*”表示任意路径以及子路径。
1.4、任意匹配
匹配“/”。匹配所有但不包含 JSP 页面。
匹配所有
2、优先顺序
当一个 url 与多个 Servlet 的匹配规则可以匹配时,则按照 “ 精确路径 > 最长路径 > 扩展名”这样的优先级匹配到对应的 Servlet。
3、URL 映射方式
在 web.xml 文件中支持将多个 URL 映射到一个 Servlet 中,但是相同的 URL 不能同时映射到两个 Servlet 中。
3.1、方式一
3.2、方式二
四、基于注解式开发 Servlet
在 Servlet3.0 以及之后的版本中支持注解式开发 Servlet。对于 Servlet 的配置不在依赖于web.xml 配置文件,而是使用@WebServlet 注解完成 Servlet 的配置。
1、@WebServlet 注解中属性
@WebServlet(urlPatterns = “/ann.do”)
//基于注解开发Servlet
@WebServlet(urlPatterns = "/ann.do")
public class AnnotationServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.