ServletContext与Web应用范围
2016-04-20 18:13
423 查看
在Servlet容器启动一个Web应用的时候,会为它创建唯一的ServletContext对象,终止应用的时候,就会销毁这个对象。同生共死,他俩的生命周期的同步的。
定义一系列servlet可以使用来和它的容器进行通信的方法,例如,获得文件的MEME类型,传递请求,或者往日志的文件写入。
There is one context per “web application” per Java Virtual Machine. (A “web application” is a collection of servlets and content installed under a specific subset of the server’s URL namespace such as “/catalog”and possibly installed via a“ .war” file.)
每一个Web应用对应一个虚拟机,对应一个context对象。Web应用是多个servlet的集合,这些servlet由服务器具体的URL 甚至文件 子集配置。(个人理解就是映射吧)
In the case of a web application marked “distributed” in its deployment descriptor, there will be one context instance for each virtual machine. In this situation, the context cannot be used as a location to share global information (because the information won’t be truly global). Use an external resource like a database instead.
当Web应用在部署的时候被标记为分布式时,每个虚拟机只有一个context实例,此时context不能共享全局的信息。可以用数据库来替换。
The ServletContext object is contained within the ServletConfig object, which the Web server provides the servlet when the servlet is initialized.
ServletContext对象中包含有ServletConfig对象,这个对象包含了容器提供的初始化的一些数据和信息
要想在Web应用生命周期内在组件之间进行数据共享,直接将共享的对象绑定到ServletContext对象,其实就是关联。为此要提供一对属性名和属性值,使用这几个方法增加获取和移除共享数据。
来个共享数据的小例子,统计网站的访问次数。在Web应用的生命周期里,这个Count对象将会一直存在。
计数器:
计数的servlet
计数信息将会以图片的形式发送到客户端,表示Servlet还能生成动态图像,用了java的图形绘制的相关类。
将共享的信息转发到jsp进行显示,最最简单的将业务逻辑和界面分开。当然啦,最好是界面里不要有java代码,用标签或者是EL表达式来替换。这里可以直接用jsp的9个隐式对象。
访问多次,每次增加1。
打开多个窗口,显示结果在之前的结果上加1。
将tomcat关闭或者在控制台将Web应用关闭,再启动,将看到从1开始计数。
参考书籍:孙卫琴老师的《Tomcat与Java Web开发技术详解》这本书很好
以下内容为源码的注释内容,自己翻译理解下。
Defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file.定义一系列servlet可以使用来和它的容器进行通信的方法,例如,获得文件的MEME类型,传递请求,或者往日志的文件写入。
There is one context per “web application” per Java Virtual Machine. (A “web application” is a collection of servlets and content installed under a specific subset of the server’s URL namespace such as “/catalog”and possibly installed via a“ .war” file.)
每一个Web应用对应一个虚拟机,对应一个context对象。Web应用是多个servlet的集合,这些servlet由服务器具体的URL 甚至文件 子集配置。(个人理解就是映射吧)
In the case of a web application marked “distributed” in its deployment descriptor, there will be one context instance for each virtual machine. In this situation, the context cannot be used as a location to share global information (because the information won’t be truly global). Use an external resource like a database instead.
当Web应用在部署的时候被标记为分布式时,每个虚拟机只有一个context实例,此时context不能共享全局的信息。可以用数据库来替换。
The ServletContext object is contained within the ServletConfig object, which the Web server provides the servlet when the servlet is initialized.
ServletContext对象中包含有ServletConfig对象,这个对象包含了容器提供的初始化的一些数据和信息
要想在Web应用生命周期内在组件之间进行数据共享,直接将共享的对象绑定到ServletContext对象,其实就是关联。为此要提供一对属性名和属性值,使用这几个方法增加获取和移除共享数据。
removeAttribute(String name)
getAttribute(String name)
setAttribute(String name,Object object)
注意:别和setParameter()搞混淆。从名字看,一个是属性值,后者是参数,也就是浏览器请求资源时附加的参数,get和post方式中参数位置不同,数据量的大小限制不同。来个共享数据的小例子,统计网站的访问次数。在Web应用的生命周期里,这个Count对象将会一直存在。
计数器:
package com.neo.domain; /** * @author neo */ public class Counter { private int count; public Counter(){ this(0); } public Counter(int count){ this.count = count; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public void add(int step){ count += step; } }
计数的servlet
package com.neo.controller; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.neo.domain.Counter; @WebServlet(urlPatterns = { "/count" }) public class CounterServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); ServletContext context = getServletContext(); Counter counter = (Counter) context.getAttribute("counter"); if(null == counter){ counter = new Counter(0); context.setAttribute("counter", counter); } counter.add(1); context.getRequestDispatcher("/count.jsp").forward(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
计数信息将会以图片的形式发送到客户端,表示Servlet还能生成动态图像,用了java的图形绘制的相关类。
package com.neo.controller; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; @WebServlet("/image") public class ImageServlet extends HttpServlet { private static final long serialVersionUID = 1L; //字体 private Font font = new Font("Courier", Font.BOLD, 12); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); //得到待显示的数字 String count = request.getParameter("count"); //数字的长度 int len = count.length(); //设置响应正文的类型 response.setContentType("image/jpeg"); ServletOutputStream out = response.getOutputStream(); //创建一个位于缓存中的图像,长为11*len,高为16 BufferedImage image = new BufferedImage(11 * len, 16, BufferedImage.TYPE_INT_RGB); //得到画笔 Graphics g = image.getGraphics(); g.setColor(Color.black); //画一个黑色的矩形,长度为11*len,高度为16 g.fillRect(0, 0, 11*len, 16); g.setColor(Color.white); g.setFont(font); char c; for(int i=0; i < len; i++){ c = count.charAt(i); //写白色的数字 g.drawString(c + "", i*11+1, 12); //画一条白色的竖线 g.drawLine( ( i + 1) * 11, 0, (i+1)*11-1, 16); } //输出JPEG格式的图片 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); //对图像进行JPEG格式编码,并且利用out输出图像数据 encoder.encode(image); out.close(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
将共享的信息转发到jsp进行显示,最最简单的将业务逻辑和界面分开。当然啦,最好是界面里不要有java代码,用标签或者是EL表达式来替换。这里可以直接用jsp的9个隐式对象。
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ page import="com.neo.domain.Counter" %> <% ServletContext context = getServletContext(); Counter counter = (Counter) context.getAttribute("counter"); %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Counter's jsp</title> </head> <body> 欢迎光临本站,您是第<img src='image?count=${counter.count}' />位访问者。 </body> </html>
访问多次,每次增加1。
打开多个窗口,显示结果在之前的结果上加1。
将tomcat关闭或者在控制台将Web应用关闭,再启动,将看到从1开始计数。
参考书籍:孙卫琴老师的《Tomcat与Java Web开发技术详解》这本书很好
相关文章推荐
- DX9入门笔记1-D3D初始化
- 为什么我们总是使用android:configChanges=“keyboardHidden|orientation”?
- RCurl爬虫抓取验证码例子
- iOS cocoapods 使用以及版本更新
- .Net分布式架构(二):基于Redis的Session共享
- math.h,stdarg.h与assert.h
- Android保持屏幕常亮的三种方法
- 2016年最新810多套源码2.46GB免费一次性打包下载
- JS-事件及监听知识点
- 第七周项目1
- 关于@Override
- 个人工作总结2
- PHP 防范xss攻击
- android 百度地图定位开发2
- 背景色渐变与Button点击效果与Button圆角
- Android ScrollView的使用
- google 推出android的MVP架构
- 单例模式(Singleton)——Java
- Select模型原理
- Java中方法重写与方法重载