在现实工作中很少用servlet的,至少对于码农是这样!
其实只要是个系统,只要上个项目;都会涉及到servlet。当然jsp就是一个servlet等等
其实我们知道得最多的还是在搭建一个框架系统时,会常用到servlet做过滤。比如.do、.action、.jsf、.faces等等
也一直知道一个事情,就是应用程序启动的时候,可以调用一些远程的数据来初始化系统。很多庞大的框架就有这样的需求。下面写出自己的代码,
以前也只知道servlet可以extends httpServlet来实现一个servlet。
今天才知道一般情况下,我们有两种途径实现;还有一种就是extends GenericServlet。只不过httpServlet更为方法的识别http协议所提供的多种请求类型,而httpServlet本身就是从GenericServlet extends而来。
当然我们知道只要继承了servlet接口的类,自己封装好了方法都是可以用的。
<servlet> <servlet-class>com.xiva.servlet.HelloWorldServlet</servlet-class> <servlet-name>hello</servlet-name> <load-on-startup>#</load-on-startup> <init-param> <param-name>name</param-name> <param-value>xiva</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
package com.xiva.servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import javax.servlet.GenericServlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class HelloWorldServlet extends GenericServlet{ /** * */ private static final long serialVersionUID = 1L; @SuppressWarnings("unchecked") @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { // ServletContext context = this.getServletContext(); Enumeration<String> enume = this.getInitParameterNames(); while(enume.hasMoreElements()){ System.out.println(enume.nextElement()); } String name = this.getInitParameter("name"); PrintWriter out; response.setContentType("text/html"); out = response.getWriter(); out.println("<html><head><title>Hello</title></head>"); out.println("<body><h>Hello World</h>"); out.println(name+"<br/>"); out.println(request.getRemoteAddr()+"<br/>"); out.println(request.getRemoteHost()+"<br/>"); out.println(request.getServerName()+"<br/>"); out.println(request.getServerName()+"<br/>"); out.println("</body></html>"); } public void init(){ System.out.println("Xiva Start"); } }
需要注意的是servlet的单线程模式,现在已经 deprecated。
还有一点就是GenericServlet是implements ServletConfig接口的,但是我们在使用下面两个方法
getInitParameterNames() getInitParameter(String name)
时,需要使用GenericServlet中的方法,而不是先获取ServletConfig,再从ServletConfig中获取初始化的参数名和参数值了。
二 配置自己的监视器Listener
首先是web.xml的配置
<listener> <listener-class>com.xiva.servlet.listener.HttpListenerDemo</listener-class> </listener>
其次是代码:
package com.xiva.servlet.listener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import com.xiva.OnlineCount; public class HttpListenerDemo implements HttpSessionListener{ @Override public void sessionCreated(HttpSessionEvent event) { System.out.println("welcome"); OnlineCount.raise(); } @Override public void sessionDestroyed(HttpSessionEvent event) { System.out.println("bye"); OnlineCount.reduce(); } }
监听器是从servlet上下文中接收通知事件的对象,在servlet2.3的规范中有四种监听器:
ServletContextListener ServletContextAttributesListener HttpSessionListener HttpSessionAttributesListener
熟悉Spring的朋友,可能就清楚其监听器ContextLoaderListener就是继承了ServletContextListener接口。
在网上得知还有一个监听器:
HttpSessionBindingListener
HttpSessionBindingListener这个接口有两个方法:
@Override public void valueBound(HttpSessionBindingEvent arg0) { // TODO Auto-generated method stub } @Override public void valueUnbound(HttpSessionBindingEvent arg0) { // TODO Auto-generated method stub }
这两个方法什么时候调用呢?
在session做removeAttribute或者销毁时,调用valueUnbound
在session做setAttribute时,调用valueBound
了解jsf各组件中也有一个binging的属性,不知和这个binging监听器是否有关系,记得以后再研究!
三 配置自己的过滤器filter
package com.xiva.servlet.filter; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.Properties; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import com.xiva.exception.InitException; public class CharacterFilter implements Filter { private String coding; @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub System.out.println(filterConfig.getFilterName()); Enumeration<?> names = filterConfig.getInitParameterNames(); String name = null; while(names.hasMoreElements()){ name = (String) names.nextElement(); //从filter的参数中设置coding if("encoding".equals(name)){ coding = filterConfig.getInitParameter(name); } } if(coding == null){ throw new InitException("请初始化编码"); } } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub //从资源文件中读取编码的设置 this.setEncoding(); if(coding == null){ //如果初始化配置出错,则采取页面的编码方式 coding = request.getCharacterEncoding(); } request.setCharacterEncoding(coding); System.out.println("code"); //提交到下一个filter chain.doFilter(request, response); } @Override public void destroy() { // TODO Auto-generated method stub } public String getCoding() { return coding; } public void setCoding(String coding) { this.coding = coding; } private void setEncoding() throws IOException{ Properties prop = new Properties(); InputStream iStream = CharacterFilter.class.getClassLoader().getResourceAsStream("web.propertites"); prop.load(iStream); String encoding = (String) prop.get("encoding"); this.setCoding(encoding); } }
还在持续学习中,继续更新。