BirtViewer和Struts2框架的整合

      最近和同事在做一个birt相关的东西< Birt扫盲>,web这块是用ssh框架,MVC框架用的是struts2。同事负责报表展现这一块,考虑到工期,他选择了使用birt标签来展现birt报表。这一来,问题就出现了。因为web这块是在一个老项目的基础上添加的模块,很多配置都不要再修改,其中就有struts2的核心过滤器,拦截了/*和*.jsp,而如果使用birt标签的话,它自己向birt引擎(配置为servlet)发出的请求通通都被struts2过滤了,结果只要一到含有birt标签的页面,就会报异常:在xx下找不到xxAction。算是个冲突吧。问题的关键点就是:birt标签对于servlet的请求,被struts2的核心过滤器过滤了。如果从零开始做,这或许不是什么难事,但是项目里很多配置都定死了,没办法,只能想其他路子。

方案一:修改birtViewer相关的servlet源码
      将birt的servlet的url-mapping配置为类似于/preview.birt的话,是会被struts2的核心过滤器放过的,于是我反编译了birt的servlet的源码,发现请求路径基本都是硬编码的,不管了,一通乱改,基本都是将xxx改成xxx.birt,然后居然可以预览到报表的轮廓了,不过还是有NullPointer,没办法,这么改源码不是办法。

方案二:写过滤器,使对于servlet的请求跳过struts2的处理
      今天看struts2的核心过滤器的源码,灵感突然来了,我也写个过滤器,先于struts2的过滤器执行,在过滤器里直接将请求转发到对应的servlet。果然奏效!对于类似的需求,也可以采用同样的办法。
      这个url-pattern和代码还没解耦,可以修改web.xml,这样代码就不需要对url判断了,读者自己可以改进。不多说了,上代码。
  1  /**
  2   * BirtFilter.java 2009-8-21
  3   * by shoru
  4    */
  5  package  com.shoru.filter;
  6 
  7  import  java.io.IOException;
  8  import  java.util.HashMap;
  9  import  java.util.Map;
 10  import  java.util.Set;
 11 
 12  import  javax.servlet.Filter;
 13  import  javax.servlet.FilterChain;
 14  import  javax.servlet.FilterConfig;
 15  import  javax.servlet.RequestDispatcher;
 16  import  javax.servlet.ServletContext;
 17  import  javax.servlet.ServletException;
 18  import  javax.servlet.ServletRequest;
 19  import  javax.servlet.ServletResponse;
 20  import  javax.servlet.http.HttpServletRequest;
 21 
 22  /**
 23   * BirtViewer和Struts2框架整合必须配置此拦截器。 如下配置web.xml,注意struts2的核心过滤器必须配置在BirtFilter之后。
 24   * <filter>
 25   *        <filter-name>BirtFilter</filter-name>
 26   *         <filter-class>com.linkage.system.filter.BirtFilter</filter-class>
 27   * </filter>
 28   * <filter-mapping>
 29   *        <filter-name>BirtFilter</filter-name>
 30   *         <url-pattern>/*</url-pattern>
 31   * </filter-mapping>
 32   * 
 33   * @description
 34   *  @author  Shoru
 35   * @date 2009-8-21
 36   *  @version  1.0.0
 37   *  @since  1.0
 38    */
 39  public   class  BirtFilter  implements  Filter {
 40       /**
 41       * 容器,封装birt相关功能的uri和所对应Servlet名的键值对
 42        */
 43      Map < String, String >  map  =   new  HashMap < String, String > ();
 44 
 45       /**
 46       * Context.
 47        */
 48      ServletContext context;
 49 
 50       /**
 51       * debug开关
 52        */
 53       static   boolean  debug  =   false ;
 54 
 55       /**
 56       * @description
 57       *  @author  Shoru
 58       * @date 2009-8-21
 59       *  @version  1.0.0
 60        */
 61       public   void  destroy() {
 62          map  =   null ;
 63      }
 64 
 65       /**
 66       * 过滤birt请求,转发到对应的servlet,以绕过其他过滤器,e.g. struts2
 67       * 
 68       * @description
 69       *  @author  Shoru
 70       * @date 2009-8-21
 71       *  @version  1.0.0
 72       *  @param  request
 73       *  @param  response
 74       *  @param  fc
 75       *  @throws  IOException
 76       *  @throws  ServletException
 77        */
 78       public   void  doFilter(ServletRequest request, ServletResponse response,
 79                           FilterChain fc)
 80           throws  IOException, ServletException {
 81 
 82          HttpServletRequest req  =  (HttpServletRequest)request;
 83          String uri  =  req.getRequestURI();
 84           if  (debug) {
 85              System.out.println( " >>>Requesting  "   +  uri  +   " ? "
 86                                  +  req.getQueryString());
 87          }
 88          Set < String >  keys  =  map.keySet();
 89 
 90           for  (String key : keys) {
 91               /*
 92               * TODO:这里的判断只是简单地调用contains方法,这样就带来较多限制。
 93               * 比如工程子目录的命名、struts2命名空间等都受到birtViewer的约束。待改进。
 94                */
 95               if  (uri.contains(key)) {
 96                  RequestDispatcher rd  =   this .context.getNamedDispatcher(map.get(key));
 97                   if  (rd  !=   null ) {
 98                       if  (debug) {
 99                          System.out.println( " >>>Redirect successfully executed " );
100                      }
101                       //  跳过其他过滤器,跳转到对应的servlet
102                      rd.forward(request, response);
103                  }  else  {
104                       if  (debug) {
105                          System.out.println( " >>>Redirect unsuccessfully executed " );
106                      }
107                  }
108                   return ;
109              }
110          }
111 
112           //  将请求交给下一个过滤器
113          fc.doFilter(request, response);
114      }
115 
116       /**
117       * @description
118       *  @author  Shoru
119       * @date 2009-8-21
120       *  @version  1.0.0
121       *  @param  fc
122       *  @throws  ServletException
123        */
124       public   void  init(FilterConfig fc)
125           throws  ServletException {
126 
127           this .context  =  fc.getServletContext();
128           /*
129           * 这里注意,在项目目录的命名时,不要取和birt内置的一些servlet名重复。 请根据项目的web.xml自行配置。
130           * (包括frameset、run、preview、download、parameter、document、output)
131            */
132          map.put( " frameset " " ViewerServlet " );
133          map.put( " preview " " EngineServlet " );
134      }
135  }

你可能感兴趣的:(struts2)