tomcat利用外观模式保护数据

        外观模式其实就是将细粒度的对象包装成粗粒度的对象。举个现实的例子,有四台电脑可以随便访问,可能客户a要访问第一台和第二台,客户b要访问第二台和第三台....这种情况下互相间的调用关系是和复杂的。外观模式就好比我通过一台路由器连接了四台电脑,这样客户统一通过路由器去访问需要访问的电脑。这样就大大加强了系统的易用性和可维护性。

       外观模式还有一个作用就是可以保护底层对象的数据,tomcat在设计时就利用到了这一点。一个简单的servlet处理器uml图如下:


       ServletProcess1的process方法用来处理servlet请求,该方法接收实现servletRequest和servletResponse接口的request和response,里面存放着请求信息和响应信息。process方法如下:

import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandler;
import java.io.File;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class ServletProcessor1 {

  public void process(Request request, Response response) {

    String uri = request.getUri();//获取uri的方法
    String servletName = uri.substring(uri.lastIndexOf("/") + 1);
    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.
      System.out.println("repository:"+repository);
      urls[0] = new URL(null, repository, streamHandler);
      loader = new URLClassLoader(urls);
    }
    catch (IOException e) {
      System.out.println(e.toString() );
    }
    Class myClass = null;
    try {
      myClass = loader.loadClass(servletName);
    }
    catch (ClassNotFoundException e) {
      System.out.println(e.toString());
    }

    Servlet servlet = null;

    try {
      servlet = (Servlet) myClass.newInstance();
     <span style="color:#ff0000;"> servlet.service((ServletRequest) request, (ServletResponse) response);</span>
    }
    catch (Exception e) {
      System.out.println(e.toString());
    }
    catch (Throwable e) {
      System.out.println(e.toString());
    }

  }
}
注意其中红色的代码部分,这里将request和response直接向上转型为servletRequest和servletResponse传给了servlet的services方法。

        这里的servlet其实就是request所要请求的servlet方法,就是我们在web编程时自己新建的一个servlet方法。那么问题就来了,作为tomcat用户的web程序员在servlet的service方法中接收到了由request和response向上转型而来的servletRequest和servletResponse。web程序员就可以将servletRequest和servletResponse向下转型为request和response,这样web程序员就可以调用request和response中的一些处理方法,而这些方法自然是不应该被用户调用的。这里便可以通过外观模式保护request和response中的数据和方法。

        外观类设计的uml如下:


      RequestFacade类的定义如下:

import java.io.IOException;
import java.io.BufferedReader;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;

import javax.servlet.AsyncContext;
import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class RequestFacade implements ServletRequest {

  private ServletRequest request = null;

  public RequestFacade(Request request) {
    this.request = request;//将servletrequest接口具体对应到request中
  }

  /* implementation of the ServletRequest*/
  public Object getAttribute(String attribute) {
    return request.getAttribute(attribute);
  }
.........
}
外观类的作用就是将Request向上转型为ServletRequest,并用直接调用的方式实现接口。外观类实现了ServletRequest的所有方法,且通过将ServletRequset设置为private类型屏蔽掉了Request类中的一些数据和方法。通过外观类,我们只要在process方法中做一点修改就可以保证web程序员在实现service方法时无法访问Request的敏感数据和方法:

 RequestFacade requestFacade = new RequestFacade(request);//在requestfacade中将request强制转化为servletrequest
    ResponseFacade responseFacade = new ResponseFacade(response);
    try {
      servlet = (Servlet) myClass.newInstance();
      servlet.service((ServletRequest) requestFacade, (ServletResponse) responseFacade);
    }
通过上面的方式,在service接收到的ServletRequest和ServletResponse只能向下转型为 RequestFacade和 ResponseFacade。而外观类已经屏蔽掉了Request和Response中的敏感方法和数据,从而实现了数据安全。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值