ServletContext上下文提供对应用程序中所有Servlet所共有的各种资源和功能的访问。Servlet上下文 API用于设置应用程序中所有Servlet共有的信息。Servlet可能需要共享他们之间的共有信息。运行于同 一服务器的Servlet有时会共享资源,如JSP页面、文件和其他Servlet
ServletContext是一个全局的储存信息的空间,服务器开始就存在,服务器关闭才释放。
request一个用户可有多个 session一个用户一个 servletContext所有用户共用一个 为了节省空间,提高效率,ServletContext中可以存放必须的、重要的、所有用户需要共享的数据。注 意需要考虑线程安全问题
ServletContext接口
容器供应商负责提供servlet容器内ServletContext接口的实现。使用ServletContext对象可以记录事件 日志、获取资源的URL地址,并且设置和保存上下文内可以访问的其他servlet的属性 在jsp中是9大默认对象的application对
初始化参数
上下文参数一般都是配置在web.xml中
<context-param> 上下文参数的个数没有限制
<param-name>counter</param-name> 参数名称,不允许重复
<param-value>99999</param-value> 对应配置参数值
</context-param>
......
ServletContext接口的初始化参数允许servlet访问与web应用相关的上下文初始化参数,这些由应用开 发人员在部署描述符中指定:
getInitParameter
String str=this.getServletContext().getInitParameter("counter");//如
果上下文中没有这个初始化参数配置,则获取值null
允许servlet的init-param和上下文参数同名,这里只是通过不同的方式进行获取, 上下文参 数使用application对象获取,servlet参数配置使用ServletConfig获取
getInitParameterNames
final ServletContext application = this.getServletContext();
final Enumeration<String> names =
application.getInitParameterNames();
while(names.hasMoreElements()){
String name=names.nextElement();
String value=application.getInitParameter(name);
System.out.println(name+"---"+value);
}
应用开发人员利用初始化参数传送配置信息。典型的例子是web管理员的e-mail地址或者一个持有关键 数据的系统名称
上下文属性
可以通过名称将对象属性绑定到上下文。任何绑定到上下文的属性可以被同一个web应用的其他servlet 使用。ServletContext接口的方法允许访问
setAttribute
getAttribute
getAttributeNames
removeAttribute
针对基本不发生改变而且需要频繁读取的数据,可以考虑将数据共享在application中
正确的做法是参数ServletContextListener实现application被创建时自动加载,在application销毁 时存储数据
变通做法是由Servlet在init方法中负责加载准备
<servlet>
<servlet-name>loadCatalog</servlet-name>
<servlet-class>com.yan.action.LoadCatalogServlet</servlet-class>
<!--默认情况下,当第一次客户端访问Servlet时,才由服务器负责加载并初始化Servlet
对象 -->
<!--配置参数load-on-startup表示应用启动时自动加载Servlet,值为大于等于零的整
数,值越大优先级越低.默认值-1表示按需加载-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>loadCatalog</servlet-name>
<url-pattern>/load.do</url-pattern>
</servlet-mapping>
在LoadCatalogServlet的init方法中加载类目信息,并存放在application对象的属性中,其它地方直接获 取即可
public class LoadCatalogServlet extends HttpServlet {
@Override
public void init() throws ServletException {
ServletContext application=this.getServletContext();
//模拟从数据库中获取所有的类目信息
List<Catalog> catalogList=new ArrayList<>();
for(int i=0;i<10;i++){
Catalog catalog=new Catalog();
catalog.setId(1L+i);
catalog.setName("name_"+i);
catalogList.add(catalog);
}
System.out.println(catalogList);
application.setAttribute("catalogList",catalogList);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
request.getRequestDispatcher("/product/add.jsp").forward(request,response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
}
}
页面中从application中获取数据
<select name="catalogId">
<option value="">请选择类别</option>
<%
Object obj=application.getAttribute("catalogList");
if(obj!=null && obj instanceof List){
List<Catalog> clist=(List<Catalog>) obj;
for(Catalog c:clist){
%>
<option value="<%=c.getId()%>"><%=c.getName()%></option>
<%}}%>
</select>
资源访问
ServletContext接口提供对web应用组成的静态内容文档层级的直接访问,包括HTML,GIF和JPEG文 件:
getResource
getResourceAsStream
final ServletContext application = this.getServletContext();
try{
String realPath=application.getRealPath(""); //获取应用根路径--绝
对路径,例如windows下c:\dddd\bbb
File file=new File(realPath,"counter.data"); //采用相对路径的方式指代
根路径下的文件counter.data
DataInputStream dos=new DataInputStream(new
FileInputStream(file));
dos.readLong(counter);
dos.close();
} catch (Exception e){
application.log("indexServlet",e);
}
try{
final InputStream inputStream =
application.getResourceAsStream("counter"); //一般不建议在web应用中获取
运行环境相关的配置数据--探针程序
DataInputStream dis=new DataInputStream(inputStream);
counter1=dis.readLong();
dis.close();
} catch (Exception e){
application.log("indexServlet",e);
}
操作日志
两个重载的log方法都是记录日志到servlet日志文件,需要注意的是servlet日志文件的路径由具体的 servlet容器自己去决定。如果是在IDE中跑应用的话,那么日志信息将在控制台Console输出。如果是发 布到Tomcat下的话,日志文件是Tomcat目录下的/logs/localhost.yyyy-MM-dd.log 其它方法 getMajorVersion和getMinorVersion分别返回当前servlet容器支持的Servlet规范最高版本和最低版 本。getEffectiveMajorVersion和getEffectiveMinorVersion分别返回当前应用基于的Servlet规范最高版 本和最低版本,是servlet3.0规范增加的新特性。所以一般情况下: getMajorVersion >= getEffectiveMajorVersion > getEffectiveMinorVersion >= getMinorVersion
Servlet运行特征
HttpServlet 定义了用于支持有条件GET 操作的getLastModified方法。所谓的有条件GET操作是指 客户端通过GET请求获取资源时,当资源自第一次获取那个时间点发生更改后才再次发生数据,否 则将使用客户端缓存的数据。在一些适当的场合,实现此方法可以更有效的利用网络资源,减少不 必要的数据发送
Servlet默认是线程不安全的,需要开发人员处理多线程问题。通常Web容器对于并发请求将使用同 一个servlet处理,并且在不同的线程中并发执行service方法 对于未托管在分布式环境中(默认)的servlet而言,servlet容器对于每一个Servlet声明必须 且只能产生一个实例。如果Servlet实现了SingleThreadModel接口,servlet容器可以选择实 例化多个实例以便处理高负荷请求或者串行化请求到一个特定的实例
public class TestServlet extends HttpServlet implements
SingleThreadModel {
public TestServlet(){
System.out.println("构造器....");
}
@Override
public void init() throws ServletException {
System.out.println("初始化操作....");
}
@Override
public void destroy() {
System.out.println("销毁对象....");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse
resp) throws ServletException, IOException {
System.out.println("get请求...."+Thread.currentThread());
}
}