在 web.xml 中,一个 Servlet 可以被映射为两个 url ,例如:
<servlet>
<description>TestServlet444</description>
<display-name>TestServlet123</display-name>
<servlet-name>TestServlet1</servlet-name>
<servlet-class>org.stephencat.test.TestServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value></param-value>
</init-param>
</servlet>
<servlet>
<description>TestServlet444</description>
<display-name>TestServlet123</display-name>
<servlet-name>TestServlet2</servlet-name>
<servlet-class>org.stephencat.test.TestServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>abc</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet1</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TestServlet2</servlet-name>
<url-pattern>/test2</url-pattern>
</servlet-mapping>
<description>TestServlet444</description>
<display-name>TestServlet123</display-name>
<servlet-name>TestServlet1</servlet-name>
<servlet-class>org.stephencat.test.TestServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value></param-value>
</init-param>
</servlet>
<servlet>
<description>TestServlet444</description>
<display-name>TestServlet123</display-name>
<servlet-name>TestServlet2</servlet-name>
<servlet-class>org.stephencat.test.TestServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>abc</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet1</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TestServlet2</servlet-name>
<url-pattern>/test2</url-pattern>
</servlet-mapping>
以上配置把 TestServlet 通过使用不同的两个名称 TestServlet1 和 TestServlet2 配置为两个不同的 url :/test 和 /test2
在 TestServlet 中定义了如下的类属性:
public String servletID = String.valueOf(Calendar.getInstance().getTimeInMillis());
这是在属性定义时就已经赋值的。
另外还定义了如下类属性:
private String username = null;
该类属性在声明时没有赋值,而是通过 init() 初始化方法从 web.xml 中读取初始化参数 username 给它赋值:
/**
* Initialization of the servlet. <br>
*
* @throws ServletException if an error occure
*/
public void init(ServletConfig config) throws ServletException {
// Put your code here
this.username = config.getInitParameter("username");
}
* Initialization of the servlet. <br>
*
* @throws ServletException if an error occure
*/
public void init(ServletConfig config) throws ServletException {
// Put your code here
this.username = config.getInitParameter("username");
}
在 servlet 的 doGet() 方法中,包含如下输出语句:
if(this.username==null){
out.println("null");
}else if(this.username.equals("")){
out.println("blank");
}else{
out.println(username);
}
out.println(request.getSession().getId());
out.println(servletID);
out.println("null");
}else if(this.username.equals("")){
out.println("blank");
}else{
out.println(username);
}
out.println(request.getSession().getId());
out.println(servletID);
分别打开两个 IE 窗口,访问:
http://localhost:8080/.../test
和
http://localhost:8080/.../test2
分别得到如下结果:
/test 的结果:
blank CD0C16C3CFFBE533BD8497522546EF75 1165071414984
/test2 的结果:
abc EE35E9B6588607D54E282DA865CEB8AD 1165071408234
再打开两个 IE 窗口分别访问以上网址,两个窗口的 username 和 servletID 值没有改变,只有 sessionID 值改变了。
小结:
1. 在一个 Servlet 映射内部,Servlet 的类属性是线程不安全的,因为一个映射产生唯一一个实例,多个线程访问这个唯一的实例
2. 在两个 Servlet 映射之间,类属性的值(包括在获取初始化参数时赋值和声明时直接赋值)互不干扰、相对独立