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

編輯推薦:程序員技術問答平臺
瀏覽器

網站導航:博客園首頁  我的主頁  新聞  閃存  小組  博問  社區  知識庫安全

相關文章
相關標籤/搜索