`
zongpin
  • 浏览: 3437 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
文章分类
社区版块
存档分类
最新评论

birt集成spring,利用外部数据源(详解)

阅读更多
首先,要感谢3Seefans,是他的文章给了我启示。原文地址如下:http://3seefans.iteye.com/blog/305696原文内容如下:********************************************************************************************************************************************
********************************************************************************************************************************************
********************************************************************************************************************************************

最近离职了,也没去找工作,好堕落呀,闲来没事干,想总结下上个项目的一些东西,也好给自己一个不工作的交代。

    上个项目是邮政的一个揽投项目,是我和我同学两个人做的,在这个项目中报表是一个难点,一开始想用jasper来做,因为涉及到的业务统计比较复杂,后来换成了birt,实践才发现birt确实功能强大。

     有关birt的一些基本用法,这里就不啰嗦了,网上太多这样的资料了,这里谈下,birt怎么在spring里面集成。

    birt有他单独的一套引擎,其强大的script支持促使其可以利用外部的数据缘,这也是集成spring的一个必要条件。

    这里先看看报表要做成什么样子。

报表1:

日期 年票类 文书类 票务类 车辆类 小计 
业务量 代收款总金额 业务量 代收款总金额 业务量 代收款总金额 业务量 代收款总金额 业务量 代收款总金额 
                      
2008-12-05 264 228302 255 215673.5     294 259918 813 703893.5 
合计 264 228302 255 215673.5     294 259918 813 703893.5

           


报表2:

投递段名称 业务种类 业务量 代收款总金额
投递段010101    
  车辆类 44 64966
  文书类 35 51348.5
  年票类 34 49860
  小计 113 166174.5
投递段010102    
  车辆类 4 5302
  文书类 3 3470.5
  年票类 2 2527
  小计 9 11299.5
业务种类合计    
  年票类 36 52387
  文书类 38 54819
  车辆类 48 70268
总体合计 122 177474

报表3:

日期 投递段 当日业务总量 揽投成功情况 待处理
1天 2天 3天 4天 5天 6天 7天 8天 9天 10天 11天 12天 13天 14天 揽投中
2008-12-05 010101 113 24 9                         79
2008-12-05 010102 9                             9
                 
揽投失败情况
日期 投递段    
  揽投失败3
2008-12-05 010101   1
010102    
        这里就不每个报表一一详述,以第一个报表做例子来详解:

看第一报表,是典型的交叉表,关于交叉表的设计,这里不啰嗦,

这个报表用的是script数据源,其中有四个参数,startDate(开始时间),endDate(结束时间),businessKind(业务种类),ranksId(投递队伍)。

1.在工程中建立一个BirtFactory单例工厂类,用于统一去获取外表的数据,

/**
* 提供给birt使用的Factory
*
* @author 3SeeFans
*/
public class BirtFactory {

private static final Logger logger = LoggerFactory.getLogger(BirtFactory.class);

private static BirtFactory instance;


private static ApplicationContext context = AppContext.CONTEXT;

private final StatisticsManager manager = (StatisticsManager) context.getBean("statisticsManager");


private BirtFactory() {
logger.debug("Init the instance of BirtFactory...");
}

public static BirtFactory getInstance() {
if (instance == null) {
   if (context == null) {
    logger.debug("Get application context from birt-context.xml");
    context = new ClassPathXmlApplicationContext("birt-context.xml");//(zongpin加注释:这是通过第二种方式得到context,如果是第一种方式,此句不要)
   }
   instance = new BirtFactory();
}
return instance;
}

public List<MacroAnalysisBean> getMacroAnalysisData(Date startDate, Date endDate, Long businessKindId, Long ranksId) {
return manager.getMacroAnalysisData(startDate, endDate, businessKindId, ranksId);
}

public List<DeliverCollectBean> getDeliverCollectData(Date startDate, Date endDate, Long businessKindId,
   String depId) {
return manager.getDeliverCollectData(startDate, endDate, businessKindId, depId);
}

public List<DeliverAnalysisBean> getDeliverAnalysisData(Date startDate, Date endDate, String depId) {
return manager.getDeliverAnalysisData(startDate, endDate, depId);
}

public List<DeliverAnalysisFailBean> getDeliverAnalysisFailData(Date startDate, Date endDate, String depId) {
return manager.getDeliverAnalysisFailData(startDate, endDate, depId);
}
}

这里须注意点,StatisticsManager是负者业务相关的service类,配置在spring容器里,

这里birtFacotry通过两种方式得到ApplicationContext 。

第一种就是通过实现SerletContextListener得到servletContext,再通过

public static final ServletContext servletContext = AppContextLoader.getInstance().getServletContext();

public static final ApplicationContext CONTEXT = WebApplicationContextUtils
   .getRequiredWebApplicationContext(servletContext);

得到ApplicationContext ;通过注入的方式得到StatisticsManager。

第二种就是birt从新启动一个容器完全独立,先增加birt-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
default-autowire="byName" default-lazy-init="true">

<context:property-placeholder location="classpath:init.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"
p:username="${jdbc.username}" p:password="${jdbc.password}" />

<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource">
<property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">${hibernate.dialect}</prop>
    <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
   </props>
</property>
</bean>

<!-- 保证POJO中标注@Required的属性被注入 -->
<bean
class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" />

<bean id="statisticsManager" class="com.gzpost.lantou.service.StatisticsManager" />

</beans>

2.配置script数据源:

在script 中的open方法加

factory = new Packages.com.gzpost.lantou.proxy.BirtFactory.getInstance();

collectList=factory.getMacroAnalysisData(params["startDate"].value,params["endDate"].value,params["businessKindId"].value,params["ranksId"].value);
iterator = collectList.iterator();

fech方法中加

if(iterator.hasNext() == false ){
return false;
} else{
var collectBean = iterator.next();
row["kindName"]=collectBean.getKindName();
row["acceptDate"] = collectBean.getAcceptDate();
row["totalCount"]=collectBean.getTotalCount();
row["totalPrice"]=collectBean.getTotalPrice();
return true;
}

colse方法中加

collectList = null;
iterator = null;
colectBean = null;
factory=null;

这样script数据原就配置好了,很简单吧。

3.报表显示:

在jsp页面加入相应的标签

<div id="content">
    <c:choose>
     <c:when test="${endDate!=null&&startDate!=null}">
      <birt:viewer id="birtViewer"
       reportDesign="reports/macroAnalysis.rptdesign" format="HTML"
       showNavigationBar="false" width="800" height="480" left="0"
       top="0" showParameterPage="false" showTitle="false">
       <birt:param name="startDate" value="${startDate}" />
       <birt:param name="endDate" value="${endDate}" />
       <birt:param name="businessKindId" value="${businessKindId}" />
       <birt:param name="ranksId" value="${ranksId}" />
      </birt:viewer>
     </c:when>
    </c:choose>
   </div>

执行相应的action就可以了。 ********************************************************************************************************************************************
********************************************************************************************************************************************
********************************************************************************************************************************************


其中,关键部分就是获得ApplicationContext的配置,通过翻转,获得配置中的service服务,以查询数据。
如何获得ApllicationContext,3seefans给了两种方式,先不说第一种。
第二种方式就是新建一个配置文件,然后通过private static ApplicationContext context = new ClassPathXmlApplicationContext("birt-context.xml");
得到配置,接着通过private final StatisticsManager manager = (StatisticsManager) context.getBean("statisticsManager"); 获得那个可以查询数据的service。
这种方法实现简单,但是却是WEB应用存在两个连接数据库的配置,上面是通过spring和hibernate结合实现的,而项目中往往还有通过连接池配置实现的,因此无法达到统一。况且上述配置的service往往也存在与项目原始配置的ApplicationContext.xml文件中,即会出现重复配置,那么,第一种方法才是一种最好的方法。
3seefans提到:“第一种就是通过实现SerletContextListener得到servletContext,再通过

public static final ServletContext servletContext = AppContextLoader.getInstance().getServletContext();

public static final ApplicationContext CONTEXT = WebApplicationContextUtils
   .getRequiredWebApplicationContext(servletContext);

得到ApplicationContext ;通过注入的方式得到StatisticsManager。”
可是当我用这个方法的时候,却发现没有AppContextLoader这个类。最后,通过琢磨,用了如下的方法来实现的:
首先,编写一个类
test.birt.InitServlet,代码如下:
public class InitServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
public static ServletContext SERVLET_CONTEXT;
public void init() throws ServletException

SERVLET_CONTEXT = getServletContext();
}
}
接着,在web.xml中加入如下代码:
<servlet> 
    <servlet-name>Birt config</servlet-name> 
    <servlet-class>test.birt.InitServlet</servlet-class> 
    <load-on-startup>2</load-on-startup> 
</servlet>
然后,改写3seefans提供的BirtFactory中获得context的代码为:
private static ApplicationContext context = WebApplicationContextUtils
.getRequiredWebApplicationContext(InitServlet.SERVLET_CONTEXT);
这样,就可以实现birt和项目公用同一个配置文件了。
分享到:
评论
3 楼 zongpin 2009-11-25  
private static ApplicationContext context = WebApplicationContextUtils
.getRequiredWebApplicationContext(InitServlet.SERVLET_CONTEXT);
这样,就可以实现birt和项目公用同一个配置文件了。
anckey 写道
你好,我取得InitServlet.SERVLET_CONTEXT的时候空值,也就是说我servlet只初始化一次后,没办法取得值了,怎么处理呢?

怎么会是空呢?你再看看你的配置吧~最好把你的web.xml发上来大家看看。
2 楼 anckey 2009-07-30  
你好,我取得InitServlet.SERVLET_CONTEXT的时候空值,也就是说我servlet只初始化一次后,没办法取得值了,怎么处理呢?
1 楼 3Seefans 2009-07-16  
很少上javaeye了,我一般在百度写博客,关于第一种得到applicationContext,之前没有说清楚
也就是你写个listener类实现ServletContextListener ,并实现contextInitialized方法,在里面加入AppContextLoader.getInstance().setServletContext(sc);
其中AppContextLoader代码为:
/**
* 用于存储ServletContext
* @
*
*/
public class AppContextLoader {

private static final Logger logger = LoggerFactory.getLogger(AppContextLoader.class);

private static AppContextLoader instance;

private ServletContext sc;

private AppContextLoader() {
logger.info("Init ServletContextLoader");
}

public static AppContextLoader getInstance() {
if (instance == null) {
instance = new AppContextLoader();
}
return instance;
}

public ServletContext getServletContext() {
return sc;
}

public void setServletContext(ServletContext sc) {
this.sc = sc;
}
}

你要得到spring上下文:ApplicationContext CONTEXT = WebApplicationContextUtils
.getRequiredWebApplicationContext(AppContextLoader.getInstance().getServletContext());
就行了

相关推荐

    thunderbird C++ 源代码

    Thunderbird是一款开源、免费的邮件客户端,由Mozilla基金会开发,其源代码主要使用C++语言编写。这款软件在设计上与Microsoft的Outlook类软件有相似之处,但更注重自由软件的理念和网络安全性。在深入探讨Thunder...

    Spring Boot MyBatis配置Druid多数据源oracle《--》mysql test finally.rar

    参考这个https://mrbird.cc/Spring-Boot-MyBatis Druid.html做的 配置多个数据源同时访问mysql和oracle数据库 互相交换数据 个人学习用 仅供参考 欢迎指教

    Flappy Bird 源代码 贴图 以及 音效

    《Flappy Bird源代码、贴图与音效详解——Unity游戏开发深度剖析》 Flappy Bird,这款在2014年风靡全球的小游戏,以其简单却极具挑战性的玩法吸引了无数玩家。对于长安大学的学生,尤其是那些正在学习游戏动画开发...

    flappy bird源代码

    本文将深入探讨使用C++语言实现Flappy Bird源代码的相关知识点,帮助读者理解游戏背后的编程逻辑。 一、游戏引擎与C++ 在C++中实现Flappy Bird,首先需要了解的是如何构建一个基本的游戏框架。C++是一种高效且灵活...

    Flappybird Swift源代码

    《Swift编程语言实现Flappy Bird游戏详解》 Swift是一种由苹果公司开发的开源编程语言,以其简洁、安全和高效的特点,被广泛应用于iOS、macOS、watchOS和tvOS等平台的应用开发。在游戏开发领域,Swift同样表现出色...

    FlappyBird源代码

    《FlappyBird源代码解析与学习指南》 FlappyBird是一款广受欢迎的休闲游戏,以其简单易上手的玩法和高难度挑战吸引了大量玩家。本文将深入探讨使用C#编程语言实现的FlappyBird源码,帮助读者了解游戏背后的编程逻辑...

    Flappy Bird源代码

    《Flappy Bird源代码解析与学习指南》 Flappy Bird,这款曾经风靡全球的手机游戏,以其简单却又极具挑战性的玩法吸引了无数玩家。而它的源代码,对于想要深入理解游戏开发,特别是Java编程和2D游戏制作的开发者来说...

    FlappyBird 源代码

    《FlappyBird 源代码解析与学习指南》 FlappyBird是一款广受欢迎的休闲游戏,以其简单易上手的操作和极具挑战性的游戏体验而闻名。Android版的FlappyBird源代码提供了深入理解游戏开发的窗口,对于学习移动游戏开发...

    自制flappy bird 详解

    基于cocos2d-x 3.8 引擎 制作的flappy bird

    Flybird创作,源代码见博客主页!

    【标题】"Flybird创作,源代码见博客主页!" 提示我们这是一份与Flybird相关的创作项目,其中可能包含编程源代码。Flybird可能是该项目的名称或开发者昵称,而“源代码见博客主页”意味着我们可以在这个项目的博客...

    flybird_java源代码

    本文将深入探讨名为"flybird_java源代码"的学习资源,包括两个版本:FlappyBird2和FlappyBird1,它们都是Java语言实现的经典游戏——Flappy Bird的源代码。 首先,让我们了解Flappy Bird的基本概念。Flappy Bird是...

    YOLO鸟类检测数据集 bird_VOCtrainval2012.zip

    YOLO(You Only Look Once)是一种著名的实时目标检测系统,其设计目的是为了高效地在图像中定位并识别出多...通过利用这个数据集,开发者可以训练出高效、准确的鸟类检测模型,用于实际应用或进一步的计算机视觉研究。

    Faster-RCNN鸟类检测 bird_dataset飞鸟检测数据集.rar

    VOC鸟类检测数据集,标签格式为xml和txt两种,类别名为bird, 数量有1万多张,可以直接用于目标检测 SSD、YOLOv3、Faster-RCNN等鸟类检测

    flappybird源代码

    《Flappy Bird源代码解析与学习指南》 Flappy Bird是一款在2013年由越南开发者Dong Nguyen创作的极简主义风格的休闲游戏,它以其简单却极具挑战性的玩法风靡全球。本文将深入探讨使用C语言编写的Flappy Bird源代码...

    flappy bird游戏源代码IOS版

    《Flappy Bird游戏源代码iOS版深度解析》 Flappy Bird是一款曾经风靡全球的简单却又极具挑战性的手机游戏。这款游戏以其独特的像素艺术风格、简单的游戏操作以及难以掌握的游戏机制吸引了无数玩家。对于开发者来说...

    spring-cloud-bird:简化spring cloud 开发

    spring-cloud-birdinstall在根目录下执行mvn -Drevision=1.0.0 install项目介绍spring-cloud-bird-examplesdemospring-cloud-bird-common公共工具类和封装类spring-cloud-bird-dependencies所有依赖的管理 spring-...

    flappybird的微信小程序源代码

    2. **数据管理与绑定**:在JavaScript中,利用微信小程序的`Page`对象进行数据管理,并通过`data`属性将数据绑定到视图层。在“Flappy Bird”中,游戏状态如小鸟的位置、管道的位置等都需要实时更新并反映到界面上。...

    Flappy Bird C语言编写的源代码及图片

    《Flappy Bird C语言编程详解及游戏开发过程》 Flappy Bird是一款在全球范围内广受欢迎的休闲游戏,以其简单却又极具挑战性的玩法吸引了无数玩家。在这个主题下,我们将深入探讨使用C语言来编写Flappy Bird的源代码...

Global site tag (gtag.js) - Google Analytics