BirtViewer和Struts2框架的整合

做者: 晋哥哥 发表于 2009-08-21 17:24 原文连接 阅读: 383 评论: 0html

      最近和同事在作一个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判断了,读者本身能够改进。很少说了,上代码。
<

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

>   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   * 
 25   *         BirtFilter
 26   *          com.linkage.system.filter.BirtFilter
 27   * 
 28   * 
 29   *         BirtFilter
 30   *          /*
 31   * 
 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  }

评论: 0 查看评论 发表评论java

购买博客园2010T恤,留下2010年的记念程序员


最新新闻:
· 迈过社会化网络:互联网的新时代(2010-07-21 21:19)
· 戴尔新推安全浏览器 基于Firefox 3.6(2010-07-21 21:02)
· 微软研究员认为密码能够简单又安全(2010-07-21 20:58)
· 苹果称80%财富100强企业已在使用iPhone(2010-07-21 20:54)
· 苹果10亿美圆的数据中心将于今年建成,官方还没有对其用途表态(2010-07-21 17:51)
web

编辑推荐:程序员技术问答平台
浏览器

网站导航:博客园首页  我的主页  新闻  闪存  小组  博问  社区  知识库安全

相关文章
相关标签/搜索