Tomcat详解系列(2) - 如何设计一个简单的web容器

组件实现
在HttpServer中
public void await() {
//…

    // create Response object
    Response response = new Response(output);
    response.setRequest(request);

    // 不再有response自己处理
    //response.sendStaticResource();

    // 而是如果以/servlet/开头,则委托ServletProcessor处理
    if (request.getUri().startsWith("/servlet/")) {
      ServletProcessor1 processor = new ServletProcessor1();
      processor.process(request, response);
    } else {
      // 原有的静态资源处理
      StaticResourceProcessor processor = new StaticResourceProcessor();
      processor.process(request, response);
    }

// ....

}
ServletProcessor 如何处理的?
public class ServletProcessor1 {

public void process(Request request, Response response) {

// 获取servlet名字
String uri = request.getUri();
String servletName = uri.substring(uri.lastIndexOf("/") + 1);

// 初始化URLClassLoader
URLClassLoader loader = null;
try {
  // create a URLClassLoader
  URL[] urls = new URL[1];
  URLStreamHandler streamHandler = null;
  File classPath = new File(Constants.WEB_ROOT);
  // the forming of repository is taken from the createClassLoader method in
  // org.apache.catalina.startup.ClassLoaderFactory
  String repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator)).toString() ;
  // the code for forming the URL is taken from the addRepository method in
  // org.apache.catalina.loader.StandardClassLoader class.
  urls[0] = new URL(null, repository, streamHandler);
  loader = new URLClassLoader(urls);
} catch (IOException e) {
  System.out.println(e.toString() );
}

// 用classLoader加载上面的servlet
Class myClass = null;
try {
  myClass = loader.loadClass(servletName);
}
catch (ClassNotFoundException e) {
  System.out.println(e.toString());
}

// 将加载到的class转成Servlet,并调用service方法处理
Servlet servlet = null;
try {
  servlet = (Servlet) myClass.newInstance();
  servlet.service((ServletRequest) request, (ServletResponse) response);
} catch (Exception e) {
  System.out.println(e.toString());
} catch (Throwable e) {
  System.out.println(e.toString());
}

}
}
Repsonse
public class PrimitiveServlet implements Servlet {

public void init(ServletConfig config) throws ServletException {
System.out.println(“init”);
}

public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
System.out.println(“from service”);
PrintWriter out = response.getWriter();
out.println(“Hello. Roses are red.”);
out.print(“Violets are blue.”);
}

public void destroy() {
System.out.println(“destroy”);
}

public String getServletInfo() {
return null;
}
public ServletConfig getServletConfig() {
return null;
}

}
访问 URL

利用外观模式改造
上述代码存在一个问题,

// 将加载到的class转成Servlet,并调用service方法处理
Servlet servlet = null;
try {
servlet = (Servlet) myClass.newInstance();
servlet.service((ServletRequest) request, (ServletResponse) response);
} catch (Exception e) {
System.out.println(e.toString());
} catch (Throwable e) {
System.out.println(e.toString());
}
这里直接处理将request和response传给servlet处理是不安全的,因为request可以向下转型为Request类,从而ServeletRequest便具备了访问Request中方法的能力。

public class Request implements ServletRequest {
// 一些public方法
}
public class Response implements ServletResponse {

}
解决的方法便是通过外观模式进行改造:

RequestFacade为例
public class RequestFacade implements ServletRequest {

private ServletRequest request = null;

public RequestFacade(Request request) {
this.request = request;
}

/* implementation of the ServletRequest*/
public Object getAttribute(String attribute) {
return request.getAttribute(attribute);
}

public Enumeration getAttributeNames() {
return request.getAttributeNames();
}

public String getRealPath(String path) {
return request.getRealPath(path);
}


Process中由传入外观类
Servlet servlet = null;
RequestFacade requestFacade = new RequestFacade(request); // 转换成外观类
ResponseFacade responseFacade = new ResponseFacade(response);// 转换成外观类
try {
servlet = (Servlet) myClass.newInstance();
servlet.service((ServletRequest) requestFacade, (ServletResponse) responseFacade);
}
catch (Exception e) {
System.out.println(e.toString());
}
catch (Throwable e) {
System.out.println(e.toString());
}

亚马逊测评 www.yisuping.cn
USB Microphone https://www.soft-voice.com/

Wooden Speakers https://www.zeshuiplatform.com/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值