ServletContext是定义在javax.servlet包中的对象。它定义了用于WEB应用中的服务器端组件关联servlet容器的方法集合。
ServletContext经常被用于存储对象的区域,这些对象在WEB应用中的所有的服务器端组件中使用。你可以把ServletContext当作在WEB应用中共享的存储区域。把一个对象放置到ServletContext中时,它存在于WEB应用的整个生命周期中,除非它被明确的删除或替换。在ServletContext中定义了四个方法来实现存储区的共享功能。
表2.1描述了四个方法:
方法名 |
描述 |
setAttribute(String name,Object obj) |
通过名称绑定一个对象并存储对象到当前ServletContext。如果指定的名称已经被使用过,这个方法会删除旧对象绑定为新对象。 |
getAttribute(String name) |
返回指定名称的对象,如果名称不存在返回null。 |
removeAttribute(String name) |
从ServletContext中删除指定名称的对象
|
getAttributeNames()
|
返回在ServletContext中的指定名称的对象集合 |
Web 应用和ServletContext的关系:
ServletContext 在WEB应用中充当容器的角色。在WEB应用中只有一个ServletContext 实例,Java Servlet规范指定ServletContext作为所有servlet 的容器。The ServletContext acts
为了了解它在WEB组件中的关系,我们将使用一个Servlet和一个JSP来说明。
在这个Servlet中。我们可以看到在ServletContext中存储的一个对象,这个对象在所有的服务端组件中都可使用。
列表2.2显示了servlet的源代码:
Listing 2.2 ContextServlet.java.
----------------------------------------------------------------------------------
package chapter2;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class ContextServlet extends HttpServlet {
private static final String CONTENT_TYPE = "text/html";
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Get a reference to the ServletContext
ServletContext context = getServletContext();
// Get the userName attribute from the ServletContext
String userName = (String)context.getAttribute("USERNAME");
// If there was no attribute USERNAME, then create
// one and add it to the ServletContext
if ( userName == null ) {
userName = new String("Bob Roberts");
context.setAttribute("USERNAME", userName);
}
response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>Context Servlet</title></head>");
out.println("<body>");
// Output the current value of the attribute USERNAME
out.println("<p>The current User is : " + userName +
".</p>");
out.println("</body></html>");
}
public void destroy() {
}
}
如你看到的ContextServlet,你注意到它执行了下面的步骤:
1.首先通过getServletContext()方法得到ServletContext的一个引用。
ServletContext context = getServletContext();
2.一旦你得到了ServletContext的引用,它将通过getAttribute()方法去获取绑定的名称的对象。绑定名称为USERNAME:.
String userName =(String)context.getAttribute("USERNAME");
3.检验返回的对象是否正确,如果getAttribute()方法返回null,说明没有对象绑定到名称USERNAME上。如果对象没有找到,它将创建一个,并添加到ServletContext中。绑定名称USERNAME,使用setAttribute()方法
// If there was no attribute USERNAME, then create
// one and add it to the ServletContext
if ( userName == null ) {
userName = new String("Bob Roberts");
context.setAttribute("USERNAME", userName);
}
4.通过PrintWriter.println(),传送获取的数据到输出流中。
// Output the current value of the attribute USERNAME
out.println("<p>The current User is : " +
userName + ".</p>");
编译你的servlet,并把编译后的class文件放到<CATALINA_HOME>/webapps/wileyapp/WEB-INF/classes/chapter2/目录下,这样servlet被部署到WEB应用中了。
在我们即将写的JSP中会和上面的servlet有很多相似之处,但是有两个不同的地方:ServletContext是在JSP脚本中本访问(这个问题我们将在本章稍后讨论)。
如果JSP中没有发现USERNAME属性,它不能添加一个新的。
代码实现的功能在本质上是一样的,只不过在JSP中。你可以查看源代码:
列表 2.3: Context.jsp.
<HTML>
<HEAD>
<TITLE>
Context
</TITLE>
</HEAD>
<BODY>
<%
// Try to get the USERNAME attribute from the ServletContext
String userName = (String)application.getAttribute("USERNAME");
// If there was no attribute USERNAME, then create
// one and add it to the ServletContext
if ( userName == null ) {
// Don’t try to add it just, say that you can’t find it
out.println("<b>Attribute USERNAME not found");
}
else {
out.println("<b>The current User is : " + userName +
"</b>");
}
%>
</BODY>
</HTML>
注意:Context.jsp中,我们使用了两个固有对象,application(用于引用ServletContext),out(用于输出流到客户端)。在这章的后面我们将讨论这两个对象。现在复制Context.jsp文件到<CATALINA_HOME>/webapps/wileyapp/,重新启动Tomcat;在浏览器中输入地址:
http://localhost:8080/wileyapp/Context.jsp
你会看到输出:Attribute USERNAME not found
Context.jsp没有发现USERNAME属性。如果你输入如下地址:
http://localhost:8080/wileyapp/servlet/chapter2.ContextServlet
会输出:The current User is Bob Roberts
运行servlet后,一个对象被绑定到ServletContext 中的属性USERNAME上,查看WEB应用的变化,打开前面的Context.jsp文件,地址为:http://localhost:8080/wileyapp/Context.jsp
USERNAME已经不为空。
注意:从ServletContext中删除一个对象的方法:重起JSP/Servlet容器或者使用ServletContext.removeAttribute()方法。
Using Servlets to Retrieve HTTP Data
在这一节,我们将实现servlet如何查找从客户端传送过来的信息。
有三个方法被用来查找:getParameter(), getParameterValues(), 和 getParameterNames()。每个方法的定义如下:
public String ServletRequest.getParameter(String name);
public String[] ServletRequest.getParameterValues(String name);
public Enumeration ServletRequest.getParameterNames ();
getParameter()方法返回单个字符串或者null(如果参数不存在),使用这个方法你确保只返回单个值。如果返回多个值,你必须使用getParameterValues()方法,它将返回一个字符串数组或返回null。getParameterNames()返回请求的参数名称的集合或者空集合。
为了了解如何使用这些方法查找数据,让我们来看servlet的Post方法,它是如何查找参数的,并把取得的值返回到客户端。
列表2.4: ParameterServlet.java.
-----------------------------------------------------------------
package chapter2;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class ParameterServlet extends HttpServlet {
public void init(ServletConfig config)
throws ServletException {
// Always pass the ServletConfig object to the super class
super.init(config);
}
// Process the HTTP GET request
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
// Process the HTTP POST request
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Parameter Servlet</title>");
out.println("</head>");
out.println("<body>");
// Get an enumeration of the parameter names
Enumeration parameters = request.getParameterNames();
String param = null;
// Iterate over the paramater names,
// getting the parameters values
while ( parameters.hasMoreElements() ) {
param = (String)parameters.nextElement();
out.println(param + " : " +
request.getParameter(param) +
"<BR>");
}
out.println("</body></html>");
out.close();
}
}
首先要注意的是servlet通过request的getParameterNames()方法取得所有的参数名。一旦取得参数集合后,它执行while循环来取得参数名和通过getParameter()来取得参数名对应的参数值,并打印。
创建一个HTML页面访问来ParameterServlet,如下:
列表 2.5: Form.html.
-------------------------------------------------------------
<HTML>
<HEAD>
<TITLE>
Parameter Servlet Form
</TITLE>
</HEAD>
<BODY>
<form
action="servlet/chapter2.ParameterServlet"
method=POST>
<table width="400" border="0" cellspacing="0">
<tr>
<td>Name: </td>
<td>
<input type="text"
name="name"
size="20"
maxlength="20">
</td>
<td>SSN:</td>
<td>
<input type="text" name="ssn" size="11" maxlength="11">
</td>
</tr>
<tr>
<td>Age:</td>
<td>
<input type="text" name="age" size="3" maxlength="3">
</td>
<td>email:</td>
<td>
<input type="text"
name="email"
size="30"
maxlength="30">
</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td>
<input type="submit" name="Submit" value="Submit">
<input type="reset" name="Reset" value="Reset">
</td>
</tr>
</table>
</FORM>
</BODY>
</HTML>
这个HTML文件包含了一个简单的HTML form,它用来递交到ParameterServlet的请求。
编译servlet,复制class文件到:
<CATALINA_HOME>/webapps/ wileyapp/WEB-INF/classes/chapter2目录下
把HTML文件放到:
<CATALINA_HOME>/webapps/wileyapp/ 目录下。
现在打开浏览器,输入如下地址:http://localhost:8080/wileyapp/Form.html
输入数据,点击提交按钮,输出结果。