核心J2EE模式 - 截取过滤器

核心J2EE模式 - 截取过滤器

背景

呈现层请求处理机制接收许多不同类型的请求,这些请求需要不同类型的处理。一些请求被简单转发到适当的处理程序组件,而其他请求必须在进一步处理之前进行修改,审核或未压缩。

存在的问题

需要预处理和后处理客户端Web请求和响应。

当请求进入Web应用程序时,它通常必须在主处理阶段之前通过几个入口测试。例如,

  • 客户端是否经过身份验证?
  • 客户端是否有有效的会话?
  • 客户端的IP地址是否受信任的网络?
  • 请求路径是否违反任何约束?
  • 客户端使用什么编码来发送数据?
  • 我们是否支持客户端的浏览器类型?

其中一些检查是测试,导致是或否答案,决定处理是否继续。其他检查将输入的数据流处理成适合处理的形式。

经典的解决方案包括一系列条件检查,任何失败的检查都会中止请求。嵌套if / else语句是一种标准策略,但是这种解决方案导致代码脆弱性和复制和粘贴风格的编程,因为过滤流程和过滤器的操作被编译到应用程序中。

以灵活和不显眼的方式解决这个问题的关键是拥有一个简单的机制,用于添加和删除处理组件,其中每个组件完成特定的过滤操作。

军队

  • 诸如检查数据编码方案或关于每个请求的记录信息的公共处理按照每个请求完成。
  • 需要集中共同的逻辑。
  • 服务应该容易地添加或删除不引人注目,而不影响现有组件,以便它们可以以各种组合使用,例如
    • 日志和身份验证
    • 调试和转换特定客户端的输出
    • 解压缩和转换输入的编码方案

创建可插拔过滤器,以标准方式处理公共服务,而不需要更改核心请求处理代码。过滤器拦截传入请求和传出响应,允许预处理和后处理。我们能够不引人注意地添加和删除这些过滤器,而不需要更改现有的代码。

实际上,我们能够通过各种常见的服务(如安全性,日志记录,调试等)来装饰我们的主要处理。这些过滤器是独立于主应用程序代码的组件,它们可以以声明方式添加或删除。例如,可以修改部署配置文件以设置一个过滤器链。相同的配置文件可能包括特定URL到此过滤器链的映射。当客户端请求与此配置的URL映射匹配的资源时,链中的过滤器在调用所请求的目标资源之前都按顺序进行处理。

结构体

图7.1表示截取滤波器模式。

 
图7.1截取过滤器模式类图

参与者和责任

图7.2表示截取滤波器模式。


图7.2截取滤波器序列图

FilterManager

FilterManager管理过滤器处理。它以正确的顺序创建具有相应过滤器的FilterChain,并启动处理。

FilterChain

FilterChain是独立过滤器的有序集合。

FilterOne,FilterTwo,FilterThree

这些是映射到目标的各个过滤器。FilterChain协调其处理。

目标

目标是客户端请求的资源。

策略

自定义过滤策略

过滤器是通过开发人员定义的自定义策略实现的。这不如首选标准过滤策略的灵活性和功能更低,这在下一节中介绍,仅适用于支持2.3 servlet规范的容器。自定义过滤器策略的功能不那么强大,因为它不能以标准和便携的方式提供请求和响应对象的包装。另外,请求对象不能修改,如果过滤器要控制输出流,必须引入某种缓冲机制。要实现自定义过滤策略,开发人员可以使用Decorator模式[GoF]来围绕核心请求处理逻辑包装过滤器。例如,可能会有一个包装认证过滤器的调试过滤器。实施例7.1和实施例7。

示例7.1实现过滤器 - 调试过滤器

 1 public class DebuggingFilter implements Processor {
 2  private Processor target;//  处理器目标;
 3
 4   public DebuggingFilter(processor myTarget){
 5     target = myTarget;
 6   }
 7
 8   public void execute(ServletRequest req,
 9   ServletResponse res) throws IOException,
10     ServletException {
11     //在这里做一些过滤处理,比如
12     //显示请求参数
13     target.execute(req,res);
14   }
15 }

示例7.2实现过滤器 - 核心处理器

 1 public class CoreProcessor implements Processor {
 2   private Processor target;
 3   public CoreProcessor()   {
 4     this(null);
 5   }
 6
 7   public CoreProcessor(Processor myTarget)   {
 8     target = myTarget;
 9   }
10
11   public void execute(ServletRequest req,
12       ServletResponse res) throws IOException,
13       ServletException   {
14  //在这里做核心处理
15 } }

在servlet控制器中,我们委托一个被调用processRequest来处理传入请求的方法 ,如例7.3所示。

示例7.3处理请求

public void processRequest(ServletRequest req,
  ServletResponse res)
  throws IOException, ServletException {
  Processor processors = new DebuggingFilter(
    new AuthenticationFilter(new CoreProcessor()));
  processors.execute(req, res);
//然后调度到下一个资源,这可能是
  //要显示的视图
  dispatcher.dispatch(req, res); }

仅作为示例目的,假设每个处理组件在执行时都会写入标准输出。例7.4显示了可能的执行输出。

示例7.4写入标准输出的消息

调试过滤器预处理完成...
认证过滤处理完成...
核心处理完成...
调试过滤器后处理完成...

一系列处理器按顺序执行。每个处理器,除了链中的最后一个,被认为是一个过滤器。最终的处理器组件是我们封装我们要为每个请求完成的核心处理的地方。考虑到这种设计,当我们要修改处理请求的方式时,我们需要更改CoreProcessor类以及任何过滤器类中的代码。

图7.3是描述使用示例7.1,示例7.2和示例7.3的过滤器代码时的控制流程的序列图。

 
图7.3自定义过滤策略的序列图,装饰器实现

请注意,当我们使用装饰器实现时,每个过滤器直接调用下一个过滤器,尽管使用通用接口。或者,可以使用FilterManager和FilterChain实现此策略。在这种情况下,这两个组件协调和管理过滤器处理,并且各个过滤器不能直接相互通信。这个设计近似于servlet 2.3兼容的实现,尽管它仍然是一个自定义策略。示例7.5是仅仅创建FilterChain的FilterManager类的列表,如例7.6所示。FilterChain以适当的顺序向链中添加过滤器(为了简洁起见,这在FilterChain构造函数中完成,但通常会被替换为注释),处理过滤器,并最终处理目标资源。

 
图7.4自定义过滤策略的顺序图,非分配器实现

示例7.5 FilterManager - 自定义过滤器策略

public class FilterManager {
  public void processFilter(Filter target,
    javax.servlet.http.HttpServletRequest request,
    javax.servlet.http.HttpServletResponse response)
    throws javax.servlet.ServletException,
      java.io.IOException       {
    FilterChain filterChain = new FilterChain();

     //过滤器管理器在此构建过滤器链
    //如有必要

    //通过过滤器链管理请求
    filterChain.processFilter(request, response);

      //进程目标资源
    target.execute(request, response);
  }
}

示例7.6 FilterChain - 自定义过滤器策略

public class FilterChain {
  //过滤器链 filter chain
  private Vector myFilters = new Vector();

  // 创建新的 FilterChain
  public FilterChain()  {
    // 插件默认过滤服务为例
    // 只要。这通常会在
    // FilterManager,但是在这里完成了例子目的
    addFilter(new DebugFilter());
    addFilter(new LoginFilter());
    addFilter(new AuditFilter());
  }

  public void processFilter(
    javax.servlet.http.HttpServletRequest request,
    javax.servlet.http.HttpServletResponse response)
  throws javax.servlet.ServletException,
    java.io.IOException         {
    Filter filter;

    // 应用过滤器
    Iterator filters = myFilters.iterator();//迭代器过滤器
    while (filters.hasNext())
    {
      filter = (Filter)filters.next();
      //通过各种请求和响应
      //筛选器
      filter.execute(request, response);
    }
  }

  public void addFilter(Filter filter)  {
    myFilters.add(filter);
  }
}

这个策略不允许我们创建与我们想要的一样灵活或强大的过滤器。一个,过滤器以编程方式添加和删除。虽然我们可以编写专有的机制来处理通过配置文件添加和删除过滤器,但我们仍然无法包装请求和响应对象。另外,没有复杂的缓冲机制,这种策略不能提供灵活的后处理。

标准过滤策略提供了解决这些问题的解决方案,利用了2.3 Servlet规范的功能,该规范为过滤困境提供了一个标准的解决方案。

注意

在撰写本文时,Servlet 2.3规范是最终草案。

标准过滤策略

过滤器使用部署描述符进行声明性控制,如servlet规范版本2.3中所述,在本文??中,它是最终草案形式。servlet 2.3规范包括用于构建过滤器链的标准机制,并且不引人注目地从这些链中添加和去除过滤器。过滤器围绕接口构建,并通过修改Web应用程序的部署描述符以声明方式添加或删除。

我们的这个策略的例子是创建一个过滤器来预处理任何编码类型的请求,以便每个请求可以在我们的核心请求处理代码中类似处理。为什么这样做是必要的?包含文件上传的HTML表单使用与大多数表单不同的编码类型。因此,随着上传的表单数据不能通过简单的 getParameter()调用获得。因此,我们创建两个预处理请求的过滤器,将所有编码类型转换为单一一致的格式。我们选择的格式是将所有表单数据作为请求属性使用。

一个过滤器处理类型的标准表单编码, application/ x-www-form-urlencoded另一个处理较不常见的编码类型 multipart/form-data,用于包含文件上传的表单。过滤器将所有表单数据转换为请求属性,因此核心请求处理机制可以以相同的方式处理每个请求,而不是用于不同编码的特殊外壳。

示例7.8显示了使用通用应用程序表单编码方案转换请求的过滤器。例7.9显示了处理使用多部分格式编码方案的请求的转换的过滤器。这些过滤器的代码基于servlet规范版本2.3的最终草案。也使用基本过滤器,这两个过滤器都从该过滤器继承(参见“过滤策略”一节)。基本过滤器(如示例7.7所示)为标准过滤器回调方法提供了默认行为。

示例7.7基本过滤器 - 标准过滤器策略

public class BaseEncodeFilter implements
      javax.servlet.Filter {
  private javax.servlet.FilterConfig myFilterConfig;

  public BaseEncodeFilter()     {  }

  public void doFilter(
    javax.servlet.ServletRequest servletRequest,
    javax.servlet.ServletResponse servletResponse,
    javax.servlet.FilterChain filterChain)
  throws java.io.IOException,
    javax.servlet.ServletException {
    filterChain.doFilter(servletRequest,
        servletResponse);
  }

  public javax.servlet.FilterConfig getFilterConfig()
  {
    return myFilterConfig;
  }

  public void setFilterConfig(
    javax.servlet.FilterConfig filterConfig) {
      myFilterConfig = filterConfig;
  }
}

示例7.8 StandardEncodeFilter - 标准过滤器策略

public class StandardEncodeFilter
  extends BaseEncodeFilter {
  //创建新的 StandardEncodeFilter
  public StandardEncodeFilter()   {  }

  public void doFilter(javax.servlet.ServletRequest
    servletRequest,javax.servlet.ServletResponse
    servletResponse,javax.servlet.FilterChain
    filterChain)
  throws java.io.IOException,
    javax.servlet.ServletException {

    String contentType =
      servletRequest.getContentType();
    if ((contentType == null) ||
      contentType.equalsIgnoreCase(
        "application/x-www-form-urlencoded"))     {
      translateParamsToAttributes(servletRequest,
        servletResponse);
    }

    filterChain.doFilter(servletRequest,
      servletResponse);
  }

  private void translateParamsToAttributes(
    ServletRequest request, ServletResponse response)
  {
    Enumeration paramNames =
        request.getParameterNames();

    while (paramNames.hasMoreElements())     {
      String paramName = (String)
          paramNames.nextElement();

      String [] values;

      values = request.getParameterValues(paramName);
      System.err.println("paramName = " + paramName);
      if (values.length == 1)
        request.setAttribute(paramName, values[0]);
      else
        request.setAttribute(paramName, values);
    }
 }
}

示例7.9 MultipartEncodeFilter - 标准过滤器策略

 1 public class MultipartEncodeFilter extends
 2   BaseEncodeFilter {
 3   public MultipartEncodeFilter() { }
 4   public void doFilter(javax.servlet.ServletRequest
 5     servletRequest, javax.servlet.ServletResponse
 6     servletResponse,javax.servlet.FilterChain
 7     filterChain)
 8   throws java.io.IOException,
 9     javax.servlet.ServletException {
10     String contentType =
11       servletRequest.getContentType();
12     // 只有当这个请求是多部分的时候才过滤这个请求编码
13     if (contentType.startsWith(
14                 "multipart/form-data")){
15       try {
16         String uploadFolder =
17           getFilterConfig().getInitParameter(
18               "UploadFolder");
19         if (uploadFolder == null) uploadFolder = ".";
20
21         /** The MultipartRequest class is:
22         * Copyright (C) 2001 by Jason Hunter
23         * <[email protected]>. All rights reserved.
24         **/
25         MultipartRequest multi = new
26           MultipartRequest(servletRequest,
27                            uploadFolder,
28                            1 * 1024 * 1024 );
29         Enumeration params =
30                  multi.getParameterNames();
31         while (params.hasMoreElements()) {
32           String name = (String)params.nextElement();
33           String value = multi.getParameter(name);
34           servletRequest.setAttribute(name, value);
35         }
36
37         Enumeration files = multi.getFileNames();
38         while (files.hasMoreElements()) {
39           String name = (String)files.nextElement();
40           String filename = multi.getFilesystemName(name);
41           String type = multi.getContentType(name);
42           File f = multi.getFile(name);
43          //在这一点上,做一些事情
44           //文件,必要时
45         }
46       }
47       catch (IOException e)
48       {
49         LogManager.logMessage(
50           "error reading or saving file"+ e);//读取或保存文件错误
51       }
52     } // end if
53     filterChain.doFilter(servletRequest,
54                          servletResponse);
55   } // end method doFilter()
56 }

示例7.10中的以下摘录来自包含此示例的Web应用程序的部署描述符。它显示了这两个过滤器如何注册,然后映射到资源,在这种情况下是一个简单的测试servlet。此外,该示例的序列图如图7.5所示。

示例7.10部署描述符 - 标准过滤器策略

.
.
.
<filter>
    <filter-name>StandardEncodeFilter</filter-name>
    <display-name>StandardEncodeFilter</display-name>
    <description></description>
    <filter-class> corepatterns.filters.encodefilter.
            StandardEncodeFilter</filter-class>
  </filter>
  <filter>
    <filter-name>MultipartEncodeFilter</filter-name>
    <display-name>MultipartEncodeFilter</display-name>
    <description></description>
    <filter-class>corepatterns.filters.encodefilter.
            MultipartEncodeFilter</filter-class>
    <init-param>
      <param-name>UploadFolder</param-name>
      <param-value>/home/files</param-value>
    </init-param>
 </filter>
.
.
.
<filter-mapping>
    <filter-name>StandardEncodeFilter</filter-name>
    <url-pattern>/EncodeTestServlet</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>MultipartEncodeFilter</filter-name>
    <url-pattern>/EncodeTestServlet</url-pattern>
  </filter-mapping>
.

 
图7.5拦截滤波器,标准滤波器策略编码转换示例的序列图

当客户端向控制器servlet发出请求时,StandardEncodeFilter和MultiPartEncodeFilter拦截控制。容器通过调用它们的doFilter方法来满足过滤器管理器和向量控件对这些过滤器的作用 。在完成处理之后,每个过滤器将控制权传递到其包含的FilterChain,FilterChain指示执行下一个过滤器。一旦两个过滤器已经接收并随后放弃了控制,接收控制的下一个组件就是实际的目标资源,在这种情况下是控制器servlet。

在servlet规范2.3版中支持的过滤器也支持包装请求和响应对象。该功能提供了比使用自定义过滤策略建议的自定义实现可以构建的功能更强大的机制。当然,组合这两种策略的混合方法也可以定制,但仍然缺乏Servlet规范支持的标准过滤策略的功能。

基本过滤策略

基本过滤器用作所有过滤器的公共超类。通用特性可封装在基本过滤器中,并在所有过滤器之间共享。例如,基本过滤器是在“声明过滤器策略”中包含容器回调方法的默认行为的好地方。例7.11显示了如何做到这一点。

示例7.11基本过滤器策略

 1 public class BaseEncodeFilter implements
 2   javax.servlet.Filter {
 3   private javax.servlet.FilterConfig myFilterConfig;
 4
 5   public BaseEncodeFilter()             {       }
 6
 7   public void doFilter(javax.servlet.ServletRequest
 8     servletRequest,javax.servlet.ServletResponse
 9     servletResponse, javax.servlet.FilterChain
10     filterChain) throws java.io.IOException,
11     javax.servlet.ServletException {
12
13     filterChain.doFilter(servletRequest,
14       servletResponse);
15   }
16
17   public javax.servlet.FilterConfig getFilterConfig() {
18     return myFilterConfig;
19   }
20
21   public void
22   setFilterConfig(javax.servlet.FilterConfig
23     filterConfig) {
24     myFilterConfig = filterConfig;
25   }
26 }

模板过滤策略

使用所有其他继承的基本过滤器(请参阅本章中的“基本过滤策略”)允许基类提供模板方法[Gof]功能。在这种情况下,基本过滤器用于指定每个过滤器必须完成的一般步骤,同时留下如何将该步骤完成到每个过滤器子类的细节 。通常,这些将被粗略定义,简单地在每个模板上施加有限结构的基本方法。此策略也可以与任何其他过滤策略相结合。示例7.12和示例7.13中的列表显示了如何将此策略与“声明过滤策略”配合使用。

示例7.12显示了一个名为TemplateFilter的基本过滤器,如下所示。

示例7.12使用模板过滤器策略

 1 public abstract class TemplateFilter implements
 2   javax.servlet.Filter {
 3   private FilterConfig filterConfig;
 4
 5   public void setFilterConfig(FilterConfig fc) {
 6     filterConfig=fc;
 7   }
 8
 9   public FilterConfig getFilterConfig()         {
10     return filterConfig;
11   }
12
13   public void doFilter(ServletRequest request,
14     ServletResponse response, FilterChain chain)
15     throws IOException, ServletException {
16     // 所有过滤器的通用处理可以在这里
17     doPreProcessing(request, response, chain);
18
19     // 所有过滤器的通用处理可以在这里
20     doMainProcessing(request, response, chain);
21
22     // 所有过滤器的通用处理可以在这里
23     doPostProcessing(request, response, chain);
24
25     // 所有过滤器的通用处理可以在这里
26
27     // 将控制权传递给链中的下一个过滤器
28     // 到目标资源
29     chain.doFilter(request, response);
30   }
31   public void doPreProcessing(ServletRequest request,
32     ServletResponse response, FilterChain chain) {
33   }
34
35   public void doPostProcessing(ServletRequest request,
36     ServletResponse response, FilterChain chain) {
37   }
38
39   public abstract void doMainProcessing(ServletRequest
40    request, ServletResponse response, FilterChain
41    chain);
42 }

给定TemplateFilter的这个类定义,每个过滤器都被实现为只能实现该doMainProcessing方法的子类。但是,如果需要,这些子类可以选择实现所有三种方法。示例7.13是实现一个强制性方法(由我们的模板过滤器指定)和可选的预处理方法的过滤器子类的示例。另外,使用该策略的序列图如图7.6所示。

示例7.13调试过滤器

public class DebuggingFilter extends TemplateFilter {
  public void doPreProcessing(ServletRequest req,
    ServletResponse res,FilterChain chain){
    //在这里做一些预处理
  }

  public void doMainProcessing(ServletRequest req,
    ServletResponse res,FilterChain chain){
    //做主要处理;
  }
}

 
图7.6截取过滤器,模板过滤器策略序列图

在图7.6的序列图中,过滤器子类(如DebuggingFilter)通过覆盖抽象doMainProcessing方法(可选) doPreProcessing和(和) 来定义特定的处理 doPostProcessing。因此,模板过滤器对每个过滤器的处理强加了一个结构,并为每个过滤器提供了一个封装代码的地方。

后果

  • 集中控制与松散耦合处理器 
     过滤器提供了处理多个请求处理的中心位置,控制器也是如此。过滤器更适合按照目标资源(如控制器)进行最终处理的按摩请求和响应。此外,控制器经常将诸如认证,记录,加密等的许多不相关的公共服务的管理联系在一起,而过滤允许可以以各种组合组合的更多松散耦合的处理程序。
  • 改进可重用性 
     过滤器可以促进更清洁的应用程序分区,并鼓励重用。这些可插拔拦截器从现有代码中透明地添加或删除,并且由于它们的标准接口,它们可以任意组合工作,并且可重复使用于不同的演示。
  • 声明性和灵活性配置 
     无需重新编译核心代码库,大量服务就以不同的排列组合。
  • 信息共享是无效的 
     过滤器之间的共享信息可能是低效的,因为根据定义,每个过滤器松散耦合。如果过滤器之间必须共享大量的信息,那么这种方法可能被证明是昂贵的。

相关模式

  • 前端控制器 
     控制器解决了一些类似的问题,但更适合处理核心处理。
  • 装饰器[GoF] 
     拦截过滤器模式与Decorator模式相关,该模式提供动态可插入的包装器。
  • 模板方法[GoF] 
     模板方法模式用于实现模板过滤策略。
  • Interceptor [POSA2] 
     拦截过滤器模式与Interceptor模式相关,允许透明地添加服务并自动触发。
  • 管道和过滤器[POSA1] 
     拦截过滤器模式与管道和过滤器模式相关。
时间: 2024-10-12 15:57:00

核心J2EE模式 - 截取过滤器的相关文章

Java核心类库-IO-文件过滤器(FilenameFilter)

文件操作过滤器(FilenameFilter): listFiles(FilenameFilter filter )方法 : 实际就相当于: //文件过滤器(FilenameFilter)public class FileDemo1 { public static void main(String[] args) { File dir = new File("C:/Users/37335/Desktop/Java应用框架"); File[] fs = dir.listFiles(new

JAVA DAO(Data Access Object)的个人总结

最近上课,老师提到DAO,也是因为后面做作业的需要,就花了一点时间,来看一下DAO,也只是泛泛而谈,自己学习的一些总结,也希望给想学习的新手一些帮助吧. 1.什么是DAO 说来说去,DAO到底是什么呢?神神秘秘的,让我们来一层层的解开她的面纱.在核心J2EE模式中是这样介绍的:为了建立一个健壮的J2EE应用,应该将所有对数据源的访问操作抽象封装在一个公共的API当中.用程序设计的语言来说,就是建立一个接口,接口中定义了此应用程序中将会用到的所有事物方法.在这个应用程序中,当需要和数据源进行交互的

jta 知识

JTA知识(转载原文地址:http://blog.csdn.net/it_man/article/details/7230215) Java Transaction API,译为Java事务API.JTA允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据.JTA主要用于分布式的多个数据源的两阶段提交的事务,而JDBC的Connection提供的单个数据源的事务; 后者因为只涉及到一个数据源,所以其事务可以由数据库自己单独实现, 而JTA事务因为其分布式和多数据源的特性

DAL、DAO、ORM、Active Record辨析

转自:http://blog.csdn.net/suiye/article/details/7824943 模型 Model 模型是MVC中的概念,指的是读取数据和改变数据的操作(业务逻辑).一开始我们直接把和数据库相关的代码放在模型里(sql直接写在代码中),这样就会导致以后的维护相当麻烦.业务逻辑的修改都需要开发者重新写sql,如果项目需要分库,需要将sql语句抽出来,放到单独的一层.这一层就是DAL(数据访问层). 持久层Persistence 持久层只是一个逻辑概念而已,主要任务是负责把

每个Java开发人员都应该知道的4个Spring注释

这是每个Java开发人员都应该知道的最重要的Spring注解.感谢优锐课老师对本文提供的一些帮助. 随着越来越多的功能被打包到单个应用程序或一组应用程序中,现代应用程序的复杂性从未停止增长.尽管这种增长带来了一些惊人的好处,例如丰富的功能和令人印象深刻的多功能性,但它要求开发人员使用越来越多的范例和库.为了减少开发人员的工作量以及开发人员必须记住的信息量,许多Java框架都转向了注解. 特别是Spring,它以注解的使用而闻名,它使开发人员仅用少数几个注解就可以创建完整的表示状态转移(REST)

颠覆性的商业模式+专注产品(其实也有大量创新)——互联网核心是用户体验+提高效率

文 / 王云辉 公众号:科技杂谈(keji_zatan) 这几天,一篇文章流传甚广. 这篇文章说,小米CEO雷军约见6名互联网专家,做了一场为时3小时的闭门交流,但它既没有说6位专家姓甚名谁,也没有一字提及专家发言. 全文的核心,只有一段雷军新煲的心灵鸡汤.从为什么干小米,小米当前的状态,到小米的未来去向,雷军都给出了完整的逻辑和阐述. 在最近唱衰小米的舆论大势下,这篇文章其实可以被理解为,雷军面对外界质疑的变相回应. 在文章中,雷军表示,他做小米的出发点,是要让老百姓用上优质的产品,而经过当前

MVC模式简介

MVC架构是一个复杂的架构,其实现也显得非常复杂.但是,我们已经总结出了很多可靠的设计模式,多种设计模式结合在一起,使MVC架构的实现变得相对简单易行.Views可以看作一棵树,显然可以用Composite Pattern来实现.Views和Models之间的关系可以用Observer Pattern体现.Controller控制Views的显示,可以用Strategy Pattern实现.Model通常是一个调停者,可采用Mediator Pattern来实现. 现在让我们来了解一下MVC三个

为什么要使用MVC模式,MVC模式的优势有哪些?请写出你熟悉的MVC轻量级框架名称。

MVC就是常说的:模型(Model),视图(View)和控制Controller) 它把业务处理和Jsp页面分开了.而以前的Jsp页面是把所有的代码都写在Jsp页面中,那样不利于维护 MVC模式的目的就是实现Web系统的职能分工. MVC模式的好处: 1.各施其职,互不干涉 在MVC模式中,三个层各施其职,所以如果一旦哪一层的需求发生了变化,就只需要更改相应的层中的代码而不会影响到其它层中的代码. 2.有利于开发中的分工 在MVC模式中,由于按层把系统分开,那么就能更好的实现开发中的分工.网页设

【转载】Servlet Filter(过滤器)、Filter是如何实现拦截的、Filter开发入门

Servlet Filter(过滤器).Filter是如何实现拦截的.Filter开发入门 Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能.例如实现URL级别的权限访问控制.过滤敏感词汇.压缩响应信息等一些高级功能. Servlet API中提供了一个Filter接口,开发web应用时