(转)struts2中jfreechart的增强

李刚的文了,
http://www.ibm.com/developerworks/cn/java/j-lo-struts2-jfreechart/

关键部分,是struts2中,改写了插件.

分析 Struts 2 官方提供的 JFreeChart 插件不难发现,它的主要作用就是在页面中显示 Action 中的 JFreeChart 对象。因此 JFreeChart 插件所完成的工作非常有限,即使我们在 Struts 2 中整合了 JFreeChart 框架,我们依然需要自己手动创建 JFreeChart 实例,这是非常烦琐的事情。最理想的状况是我们只提供需要显示的数据,而 Struts 2 对 JFreeChart 进行封装,自动生成 JFreeChart 图表,并将其显示在 HTML 页面上。

下面我们将来介绍改进后的 JFreeChart 插件

改进 JFreeChart 插件

前面提到 Struts 2 的 JFreeChart 插件存在一些不够方便的地方,主要是 Struts 2 的 Action 还必须手动创建 JFreeChart 对象,这就显得比较繁琐了。

对于常见的饼图、柱状图,我们可以对 JFreeChart 插件进行适当改进,由 JFreeChart 插件来根据 Dataset 创建 JFreeChart 对象,这样就可以让 Struts 2 Action 开发者更加简便。

JFreeChart 插件的关键就是实现了一个名为“chart”的 Result Type,为了简化 JFreeChart 插件,我们改进这个名为“chart”的 Result Type,下面是改进过的 Result Type 类:


清单 4. CrazyChartResult.java

package org.crazyit.struts2.dispatcher;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.ChartFactory;
import org.jfree.data.general.*;
import org.jfree.data.category.CategoryDataset;
import org.jfree.chart.plot.PlotOrientation;
import org.apache.struts2.dispatcher.ChartResult;

import java.io.OutputStream;

public class CrazyChartResult extends ChartResult
{
private boolean chartSet;
private Dataset dataset;
private String chartType;
private String title;
public CrazyChartResult()
{
super();
}
// 省略了各属性的 setter 和 getter 方法
...
public void execute(ActionInvocation invocation) throws Exception
{
// 获取 dataset
if (!chartSet)
{
System.out.println("!!!!!!!!!!!");
dataset = (Dataset) invocation.getStack()
.findValue("dataset", Dataset.class);
}
// 如果 JFreeChart 不存在,Dataset 也不存在,那将引发异常
if (super.getChart() == null
&& dataset == null)
throw new NullPointerException(
"No JFreeChart object found on the stack with name "
+ super.getValue() + "且创建统计图表的 Dataset 也不存在!");
if (super.getChart() == null
&& dataset != null)
{
if (chartType.equals("pieChart"))
{
// 创建统计图
super.setChart(ChartFactory.createPieChart(
title,  // 图表标题
(PieDataset)dataset, // 数据
true, // 是否显示图例
false, // 是否显示工具提示
false // 是否生成 URL
));
}
else if (chartType.equals("barChart"))
{
super.setChart(ChartFactory.createBarChart(
title,
"横座标",
"纵坐标",
(CategoryDataset)dataset,
PlotOrientation.HORIZONTAL,
true, // 是否显示图例
false, // 是否显示工具提示
false // 是否生成 URL
));
}
else
{
throw new IllegalArgumentException(
"该插件暂不支持" + chartType + "类型的统计图 .");
}
}
// 保证统计图表的高、宽数据存在。
if (super.getHeight() == null)
  throw new NullPointerException("No height parameter was given.");
if (super.getWidth() == null)
  throw new NullPointerException("No width parameter was given.");
// 获取输出图片的二进制输出流
OutputStream os = ServletActionContext
.getResponse().getOutputStream();
try
{
// 输出统计图
if ("png".equalsIgnoreCase(super.getType()))
ChartUtilities.writeChartAsPNG(os, super.getChart()
, super.getWidth(), super.getHeight());
else if ("jpg".equalsIgnoreCase(super.getType())
|| "jpeg".equalsIgnoreCase(super.getType()))
ChartUtilities.writeChartAsJPEG(os, super.getChart()
, super.getWidth(), super.getHeight());
else
throw new IllegalArgumentException(super.getType()
      + " is not a supported render type (only JPG and PNG are).");
}
finally
{
if (os != null) os.flush();
}
}
}




上面程序中粗体字代码就负责根据 Action 中 Dataset 来创建 JFreeChart 对象,从上面源代码中可以看出,这个 JFreeChart 插件只支持创建饼图和柱状图两种;如果开发者希望使用其他其他统计图,则依然需要手动创建 JFreeChart 对象。

提供了上面 CrazyChartResult 类之后,接下来为新的 Struts 2 插件提供 struts-plugin.xml 文件,这个文件的配置非常简单,只要将名为 chart 的 Result Type 改为使用 CrazyChartResult 类即可。下面是扩展后的 JFreeChart 插件中配置文件的代码:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="jfreechart-default" extends="struts-default">   
    <result-types>
    <result-type name="chart"
class="org.crazyit.struts2.dispatcher.CrazyChartResult">
    <param name="height">150</param>
    <param name="width">200</param>
    </result-type>
    </result-types>
    </package>
</struts>



从上面粗体字代码可以看出,此时的 JFreeChart 插件中名为“chart”的 Result Type 已经改为使用 CrazyChartResult 了,这就允许 Struts 2 中 Action 只要提供 Dataset 即可。

将这些资源打包成 JAR 文件,即可放在项目中正常使用了。扩展后的 JFreeChart 插件可下载本文的 struts2-crazytjfreechart-plugin-2.1.6.jar 附件。

使用改进后 JFreeChart 插件

提供了改进后的 JFreeChart 插件之后,接下来开发者开发的 Action 就会简单多了,下面的 Action 只有一个 getDataset() 方法,该方法返回创建 JFreeChart 的 Dataset 对象,不再需要手动创建 JFreeChart 对象——这个工作由扩展后的 JFreeChart 插件完成。

还是前面那个创建饼图的示例程序,但此时的 Action 就简单多了,下面是该 Action 类的代码:


清单 5. ChartAction.java

public class ChartAction extends ActionSupport
{
// 获取生成统计图的 Dataset
public DefaultPieDataset getDataset()
{
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue("Java",47000);
dataset.setValue("Java EE",38000);
dataset.setValue("Ajax",31000);
dataset.setValue("Struts 2",29000);
dataset.setValue("XML",25000);
return dataset;
}
}




上面的 Action 类已经简化多了,该 Action 只需提供一个 Dataset 即可,剩下的事情都交给 JFreeChart 插件来完成。

当然,开发者还应该告诉 JFreeChart 需要创建怎样的统计图、统计图的标题等必要信息,因此配置该 Action 时需要更多的参数,下面是该 Action 的配置代码:


清单 6. struts.xml

<?xml version="1.0" encoding="GBK"?>
<!-- 指定 Struts 2 配置文件的 DTD 信息 -->
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<!-- 配置 Struts 2 应用中的常量 -->
<constant name="struts.custom.i18n.resources"
value="messageResource"/>
<constant name="struts.i18n.encoding" value="GBK"/>
<!-- 配置本应用中的包,继承 jfreechart-default 包 -->
<package name="lee" extends="jfreechart-default">
<!-- 定义一个名为 bookChart 的 Action -->
<action name="bookChart" class="lee.ChartAction">
<result type="chart">
<!-- 定义 JFreeChart 报表的大小 -->
<param name="width">800</param>
<param name="height">600</param>
<!-- 指定统计图的标题 -->
<param name="title">Test Title</param>
<!-- 指定创建一个饼图 -->
<param name="chartType">pieChart</param>
</result>
</action>
</package>
</struts>


猜你喜欢

转载自jackyrong.iteye.com/blog/1086199