首页 > 代码库 > Head-First Servelts&JSP reading note 3
Head-First Servelts&JSP reading note 3
<servlet> <servlet-name>BeerParamTests</servlet-name> <servlet-class>TestInitParams</servlet-class> <init-param> <param-name>adminEmail</param-name> <param-value>likewecare@wickedlysmart.com</param-value> </init-param></servlet>
web.xml中的片段。
这个片段针对的是TestInitParams这个servlet。
getServletConfig()能够获得这个servlet相关的信息。
getServletConfig().getInitParameter("adminEmail");
能够获得对应的paramValue——likewecare@wickedlysmart.com
当容器初始化一个Servlet的时候,会创建一个唯一对应的ServletConfig。
Container会从DD中读取相应的信息,绑定到这个ServletConfig对象上。
然后,调用Servlet类的init方法,把servletConfig对象的引用给Servlet对象。
ServletConfig对象的方法:
1 String getInitParameter(String);
2 Enumeration getInitParameterNames(); // Enumeration的一个实现类是StringTokenizer。。。
3 ServletContext getServletContext();
4 String getServletName(); // nearly with no use
<servlet> <servlet-name>BeerParamTests</servlet-name> <servlet-class>TestInitParams</servlet-class></servlet><context-param> <param-name>adminEmail</param-name> <param-value>clientheaderror@wickedlysmart.com</param-value></context-param>
web.xml中的片段。
ServletContext,属于整个web-app,而不是某一个servlet。
this.getServletContext().getInitParameter("adminEmail");
this.getServletConfig().getServletContext().getInitParameter("adminEmail");
BOTH RIGHT!!! If the servlet extends HttpServlet or GenericServlet.
ServletContext对象的方法:
1 String getInitParameter(String)
2 Enumeration getInitParameterNames();
3 Object getAttribute(String);
4 getAttributeNames();
5 setAttribute(String, Object);
6 removeAttribute(String);
7 getRequestDispatcher(String);
Listener
有的时候需要在某一个或某些事件执行之前去完成一些工作,或之后完成一些工作。
这个工作可以让每一个servlet去实现,但是显得累赘,这个时候可以把这些工作提取出来,交给一个Java类去完成,这个java类就是一个Listener。
ServletContextListener
监听ServletContext的动作的监听器
public class SomeServletContextListener implements ServletContextListener { public void contextInitialized(ServletContextEvent event){ ServletContext sc = event.getServletContext;
String some = sc.getInitParameter("some");
Dog dog = new Dog(some);
sc.setAttribute("dog", dog); } public void contextDestoryed(ServletContextEvent event){ // NOTHING TO DO HERE~ }}
设置监听器,在web.xml中,追加
<listener> <listener-class>xx.xx.SomeServletContextListener</listener-class></listener>
这样,Container就会去指定的位置寻找监听器类了,然后
Servlet类中,通过
Dog dog = (Dog) getServletContext().getAttribute(“dog”);
就可以获得这个dog对象了,注意强制类型转换。
其他类型的监听器:
ServletContextAttributeListener:用于监听ServletContext中的Attribute变动的。
- attributeAdded
- attributeRemoved
- attributeReplaced
HttpSessionListener:用于监听Session创建和销毁的,也就是说多少个用户在使用该程序。
- sessionCreated
- sessionDestroyed
ServletRequestListener:用于监听对该程序进行请求,以便对请求进行封装或者log情报打印等。
- requestInitialized
- requestDestroyed
等等。。。
ServletRequestAttributeListener
HttpSessionBindingListener
HttpSessionAttributeListener
HttpSessionActivationListener
所谓监听器,就是对某些东西进行监听,如追加,删除,变化,初始化和销毁。
Attribute的种类:ServletContext,HttpSession,HttpServletRequest
Parameter的种类:ServletContext init Parameter,Request Parameter,ServletConfig init Parameter
可以对Attribute进行设定,如this.getServletContext().setAttribute("Some", new Some());
但是不能对parameter进行修改。
可以获取Attribute和Parameter,但是Attribute的返回类型是Object,而Parameter返回类型是String,如:
Object o = request.getAttribute("Some");
String str = request.getParameter("Some");
String str = this.getServletConfig().getInitParameter("Some");
Attribute的存在的三个区域:
Context:ServletContext,对所有的用户可见;
Session:HttpSession,只对当前Session可见;
Request:ServletRequest,只对当前请求可见。
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
Enumeration getAttributeNames()
Context Scope is not thread-safe
因为application的任何一个用户都可以新建一个servletcontext的一个attribute,当然也有修正和删除它的权利。
所以放到servletContext中的attribute不能保证其安全性。
syncronized(this.getServletContext) 能够保障其线程安全性。
HttpSession Scope is not thread-safe
synchronized(request.getSession());
HttpServletRequest Scope is thread-safe.
RequestDispatcher有两种获得方式,一种是通过request,一种是通过ServletContext
RequestDispatcher view = request.getRequestDispatcher(“result.jsp”);
RequestDispatcher view = getServletContext().getRequestDispatcher(“/result.jsp”);
注意:他俩是相当不同的!!!
request的方式的话,如果参数是以"/"开头的话,它回去该项目的root目录下去寻找该页面,否则他会去request的相对路径下去寻找页面。
servletContext,只能以用“/”开头的字符串作为参数!
之后就可以用这个view.forward(request, response);了。
You can’t forward the request if you’ve already committed a response!
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType(“application/jar”); ServletContext ctx = getServletContext(); InputStream is = ctx.getResourceAsStream(“bookCode.jar”); int read = 0; byte[] bytes = new byte[1024]; OutputStream os = response.getOutputStream(); while ((read = is.read(bytes)) != -1) { os.write(bytes, 0, read); } os.flush(); // cause an illegalStateException RequestDispatcher view = request.getRequestDispatcher(“result.jsp”); view.forward(request, response); os.close();}