Simulate——Filter以及Request、Response对象在Tomcat上的实现——merry Christmas day!!!...

自定义Servlet与Filter实现
本文详细介绍了一种自定义Servlet容器的过程,包括自定义Servlet、Filter及其实现原理。通过模拟Tomcat服务器行为,实现了HTTP请求处理流程,并展示了如何通过Filter进行请求前后的处理。

 

以下模拟Filter和Request以及Response,只是将其中的原理阐述清楚,代码上可能出在较多问题,实现的功能也不很完全,但是足以阐述明白Filter的实现方式和原理了! 

完全自定义规范,实现类似于Tomcat的Server 

讲述Servlet和Filter

 


 

所有的规范放在servletapi文件夹中(注意建立的是source folder)

Servlet.java


package org.chinasoft.servlet; /** * Servlet接口 * @author lilei * @version 1.0 * @time 2010-12-25 下午12:02:27 */ public interface Servlet { /** * * @param req 封装客户端的请求 * @param resp 封装服务器端响应的请求 */ void service(Request req, Response resp); }  

 

Request.java

package org.chinasoft.servlet; import java.io.Reader; /** * 封装客户端请求的对象 * @author lilei * @version 1.0 * @time 2010-12-25 下午12:04:12 */ public interface Request { /** * * @param name key值 * @return 客户端传递过来的参数值 */ String getParameter(String name); /** * * @return 通往客户端的输入流 */ Reader getIn(); }  


 

 

Response.Java

package org.chinasoft.servlet; import java.io.Writer; /** * 封装客户端响应的对象 * @author lilei * @version 1.0 * @time 2010-12-25 下午12:06:53 */ public interface Response { /** * * @return 服务器端响应客户端的输出流 */ Writer getWriter(); }  

 

 

Filter.java

package org.chinasoft.filter; import org.chinasoft.servlet.Request; import org.chinasoft.servlet.Response; /** * 过滤器的规范 * @author lilei * @version 1.0 * @time 2010-12-25 上午10:18:43 */ public interface Filter { /** * 进行过滤的方法 * @param chain 过滤的连锁 */ void doFilter(FilterChain chain, Request req, Response resp); }  


FilterChain.java

 

package org.chinasoft.filter; import java.util.Iterator; import org.chinasoft.servlet.Request; import org.chinasoft.servlet.Response; import org.chinasoft.servlet.Servlet; /** * 持有所有过滤器集合上的迭代器的引用 * 通过此引用进行过滤的递归操作 * @author lilei * @version 1.0 * @time 2010-12-25 上午10:19:55 */ public class FilterChain { /** * 过滤器上的迭代器句柄 */ private Iterator<Filter> iterator; private Servlet servlet; private Request req; private Response resp; /** * 拿到所有过滤器上的迭代器,通过此迭代器,进行递归,实现过滤的操作 */ public void doFilter() { if(iterator.hasNext()) { Filter filter = iterator.next(); filter.doFilter(this, req, resp); } else { servlet.service(req, resp); } } /** * * @return 过滤器上的迭代器 */ public Iterator<Filter> getIterator() { return iterator; } /** * * @param iterator 设置过滤器对象 */ public void setIterator(Iterator<Filter> iterator) { this.iterator = iterator; } public Servlet getServlet() { return servlet; } public void setServlet(Servlet servlet) { this.servlet = servlet; } public Request getReq() { return req; } public void setReq(Request req) { this.req = req; } public Response getResp() { return resp; } public void setResp(Response resp) { this.resp = resp; } }  

 

服务器端模拟,实现上面定义的规范 

 

服务器的监听类Monitor.java

package org.chinasoft.startup; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.chinasoft.config.Config; import org.chinasoft.filter.Filter; import org.chinasoft.handler.HandlerSession; import org.chinasoft.servlet.Servlet; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; public class Monitor implements Runnable { private ServerSocket server; private int port; public static Map<String, Object> SERVLETS = new HashMap<String, Object>(); public static List<Filter> allFilters = new ArrayList<Filter>(); public Monitor(int port) { this.port = port; Config.setWebRoot("webapps"); } private void service() { try { server = new ServerSocket(port); } catch (IOException e1) { System.out.println("服务器监听失败!"); } while (true) { try { Socket client = server.accept(); new Thread(new HandlerSession(client)).start(); } catch (IOException e) { e.printStackTrace(); } } } private void monitor(String dir) { File root = new File(dir); File[] children = root.listFiles(); for (int index = 0; index < children.length; index++) { File child = children[index]; iterator(child); } } private void iterator(File child) { File[] children = child.listFiles(); // 所有WEBAPP的根目录 for (int i = 0; i < children.length; i++) { File fChild = children[i]; if (fChild.isDirectory()) { String name = fChild.getName(); if (name.equals("WEB-INF")) { File path = new File(fChild.getPath() + "/web.xml"); try { BufferedReader in = new BufferedReader( new InputStreamReader(new FileInputStream(path))); parseXML(in); } catch (FileNotFoundException e) { continue; } } } else { continue; } } } private void parseXML(BufferedReader in) { SAXBuilder sax = new SAXBuilder(); Document doc = null; try { doc = sax.build(in); } catch (JDOMException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } Element root = doc.getRootElement(); List<Element> children = root.getChildren(); System.out.println(children); int size = children.size(); /**对于Servlet的解析**/ for (int index = 0; index < size; index++) { Element child = children.get(index); if (child.getName().equals("servlet")) { Element servletName = child.getChild("servlet-name"); String text = servletName.getText(); Element servletClass = child.getChild("servlet-class"); String classStr = servletClass.getText(); System.out.println(classStr); Servlet servlet = null; try { servlet = (Servlet) Class.forName(classStr).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } for (int i = 0; i < size; i++) { Element c = children.get(i); if (c.getName().equals("servlet-mapping")) { Element na = c.getChild("servlet-name"); if (na.getText().equals(text)) { Element ch = c.getChild("url-pattern"); String url = ch.getText(); SERVLETS.put(url, servlet); System.out.println(SERVLETS); } } } } /**对于Filter的解析**/ if (child.getName().equals("filter")) { Element filterName = child.getChild("filter-name"); String text = filterName.getText(); Element filterClass = child.getChild("filter-class"); String classStr = filterClass.getText(); System.out.println(classStr); Filter filter = null; try { filter = (Filter) Class.forName(classStr).newInstance(); allFilters.add(filter); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } for (int i = 0; i < size; i++) { Element c = children.get(i); if (c.getName().equals("filter-mapping")) { Element na = c.getChild("filter-name"); if (na.getText().equals(text)) { Element ch = c.getChild("url-pattern"); String url = ch.getText(); //Filter的通配操作并没有实现 //SERVLETS.put(url, filter); //System.out.println(SERVLETS); } } } } } } @Override public void run() { this.monitor(Config.getWebRoot()); this.service(); } }  

 

RequestImpl.java

package org.chinasoft.handler; import java.io.BufferedReader; import java.io.Reader; import java.util.Map; import org.chinasoft.servlet.Request; public class RequestImpl implements Request{ private Map<String, String> parameters; private BufferedReader read; @Override public String getParameter(String name) { return parameters.get(name); } @Override public Reader getIn() { return read; } public Map<String, String> getParameters() { return parameters; } public void setParameters(Map<String, String> parameters) { this.parameters = parameters; } public BufferedReader getRead() { return read; } public void setRead(BufferedReader read) { this.read = read; } }  

 

ResponseImpl.java

package org.chinasoft.handler; import java.io.Writer; import org.chinasoft.servlet.Response; public class ResponseImpl implements Response { private Writer out; @Override public Writer getWriter() { return out; } public Writer getOut() { return out; } public void setOut(Writer out) { this.out = out; } }  

 

 

关于配置的管理类:Config.java

package org.chinasoft.config; public class Config { private static String webRoot; public static String getWebRoot() { return webRoot; } public static void setWebRoot(String webRoot) { Config.webRoot = webRoot; } }  

 

 

 

 

以下是应用程序中自定义的Servlet和Filter,当然继承的也是自己定义的规范

 

MyServlet.java

package org.chinasoft.samples; import java.io.IOException; import java.io.Writer; import org.chinasoft.servlet.Request; import org.chinasoft.servlet.Response; import org.chinasoft.servlet.Servlet; public class MyServlet implements Servlet { @Override public void service(Request req, Response resp) { String username = req.getParameter("username"); String password = req.getParameter("password"); Writer out = resp.getWriter(); try { out.write("<h1>用户名是" + username + "</h1><br/>"); out.write("hello world。。。"); out.write("<h1>用户密码是" + password + "</h1><br/>"); out.flush(); } catch (IOException e) { e.printStackTrace(); } } }  

 

 

TimeFilter.java

package org.chinasoft.samples; import java.io.PrintWriter; import org.chinasoft.filter.Filter; import org.chinasoft.filter.FilterChain; import org.chinasoft.servlet.Request; import org.chinasoft.servlet.Response; public class TimeFilter implements Filter { @Override public void doFilter(FilterChain chain, Request req, Response resp) { PrintWriter out = new PrintWriter(resp.getWriter()); out.println("start:" + System.currentTimeMillis()); out.println("<br/>"); out.flush(); chain.doFilter(); out.println("end:" + System.currentTimeMillis()); out.println("<br/>"); out.flush(); } }  

 

LogFilter.java

package org.chinasoft.samples; import java.io.PrintWriter; import org.chinasoft.filter.Filter; import org.chinasoft.filter.FilterChain; import org.chinasoft.servlet.Request; import org.chinasoft.servlet.Response; public class LogFilter implements Filter { @Override public void doFilter(FilterChain chain, Request req, Response resp) { PrintWriter out = new PrintWriter(resp.getWriter()); out.println("filter log start"); out.println("<br/>"); out.flush(); chain.doFilter(); out.println("filter log end"); out.println("<br/>"); out.flush(); } }  

 

 

web.xml的配置,由于在自己的Server中并没有对命名空间进行解析,所以web.xml中的命名空间要去掉,否则程序出错!

<?xml version="1.0" encoding="UTF-8"?> <web-app> <welcome-file-list> <welcome-file>HelloWorld.html</welcome-file> </welcome-file-list> <servlet> <servlet-name>helloworld</servlet-name> <servlet-class>org.chinasoft.samples.MyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>helloworld</servlet-name> <url-pattern>/helloworld</url-pattern> </servlet-mapping> <filter> <filter-name>TimeFilter</filter-name> <filter-class>org.chinasoft.samples.TimeFilter</filter-class> </filter> <filter-mapping> <filter-name>TimeFilter</filter-name> <url-pattern>/TimeFilter</url-pattern> </filter-mapping> <filter> <filter-name>LogFilter</filter-name> <filter-class>org.chinasoft.samples.LogFilter</filter-class> </filter> <filter-mapping> <filter-name>LogFilter</filter-name> <url-pattern>/LogFilter</url-pattern> </filter-mapping> </web-app> 

 

访问的URL:http://localhost:8888/helloworld?username=admin&password=123

 

 

测试类:TestHttpServer.java

import org.chinasoft.startup.Monitor; public class TestHttpServer { public static void main(String[] args) { Monitor monitor = new Monitor(8888); new Thread(monitor).start(); } }  

 

程序运行的结果: start:1293249373812 filter log start 用户名是admin hello world。。。 用户密码是123 filter log end end:1293249373812  

从程序的执行结果可以看出,在Servlet执行前后,两个过滤器都被调用了,如果还想加入别的过滤器,就可以自定了,比如权限的,事物的,安全的,审核的,,等等,随意发挥,,,,,,,,,

 

转载于:https://www.cnblogs.com/freehell/archive/2010/12/25/2355288.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值