使用HttpSessionBindingListener监听器删除JFreechart生成的垃圾图片

        最近用JFreechart做报表,因为用的是struts2,所以没有用JFreechart的自带用于生成图片的servlet,即org.jfree.chart.servlet.DisplayChart这个类,因此就不能使用JFreeChart提供的监听器org.jfree.chart.servlet.ChartDeleter用来删除垃圾图片,该监听器的原理是:当session失效时,则删除由该session产生的图片文件。而且我要在jsp页面显示三张图片,用流的话,又不知道怎么实现。所以我只好直接生成图片存放在本地磁盘上,但是这样时间久了,就会产生大量的垃圾文件,为了解决这个问题,我参考了一下JFreechart用于删除垃圾图片的监听器,重写了一个监听器,来实现JFreechart自带监听器的功能。

重写的监听器:

package cn.edu.gcu.crm.listener;

import java.io.File;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

@SuppressWarnings("serial")
public class JFreeChartDeleter implements HttpSessionBindingListener, Serializable {

	/** The chart names. */
	@SuppressWarnings("rawtypes")
	private List chartNames = new java.util.ArrayList();

	/**
	 * 文件目录
	 */
	public String tmpdir = "";

	public JFreeChartDeleter() {
		super();
	}

	/**
	 * Add a chart to be deleted when the session expires
	 * 
	 * @param filename
	 *            the name of the chart in the temporary directory to be
	 *            deleted.
	 */
	@SuppressWarnings("unchecked")
	public void addChartFileName(String filename) {
		this.chartNames.add(filename);
	}

	/**
	 * add a chart file tmep dir to be deleted when the session expires
	 * 
	 * @param tmpdir
	 *            the dir of the chart in the temporary directory to be deleted.
	 */
	public void addTempdir(String tmpdir) {
		this.tmpdir = tmpdir;
	}

	/**
	 * Checks to see if a chart is in the list of charts to be deleted
	 * 
	 * @param filename
	 *            the name of the chart in the temporary directory.
	 * 
	 * @return A boolean value indicating whether the chart is present in the
	 *         list.
	 */
	public boolean isChartAvailable(String filename) {
		System.out.println("\n  img fileName======>>"+filename);
		return (this.chartNames.contains(filename));
	}
	
	
	
	/**
	 * 用session监听器删除生成的垃圾图片
	 * 
	 * @param request
	 * @param tmpdir图片存放的临时目录
	 * @param fileName图片的文件名称
	 */
	public static void deleteTempImg(HttpServletRequest request, String tmpdir, String fileName) {
		HttpSession session = request.getSession(false);
		if (session != null) {
			// 获取session监听器
			JFreeChartDeleter jFreeChartDeleter = (JFreeChartDeleter) session.getAttribute("JFreeChart_Deleter");
			if (jFreeChartDeleter == null) {
				jFreeChartDeleter = new JFreeChartDeleter();
				session.setAttribute("JFreeChart_Deleter", jFreeChartDeleter);
			}

			// 判断是否已经在session监听器中的待删除列表当中
			boolean isChartInUserList = false;
			isChartInUserList = jFreeChartDeleter.isChartAvailable(fileName);
			// 如果不在在session监听器中的待删除列表当中,则将其加入待删除列表
			if (!isChartInUserList) {
				jFreeChartDeleter.addChartFileName(fileName);
				jFreeChartDeleter.addTempdir(tmpdir);
			}
		}
	}
	
	

	public void valueBound(HttpSessionBindingEvent event) {
		return;
	}

	/**
	 * valueUnbound方法将被以下任一条件触发 删除文件的操作
	 * a. 执行session.setAttribute("JFreeChart_Deleter",非JFreeChartDeleter对象) 时。
	 * b.执行session.removeAttribute("JFreeChart_Deleter") 时。 
	 * c.执行session.invalidate()时。 
	 * d.session超时后。
	 */
	@SuppressWarnings("rawtypes")
	public void valueUnbound(HttpSessionBindingEvent event) {
		Iterator iter = this.chartNames.listIterator();
		while (iter.hasNext()) {
			String filename = (String) iter.next();
			File file = new File(tmpdir, filename);
			if (file.exists()) {
				file.delete();
			}
		}
		return;
	}
}

在web.xml的配置:

<!-- 监听器用来删除垃圾图片。当session失效时,则删除由该session产生的图片文件 -->
	<listener>
		<listener-class>cn.edu.gcu.crm.listener.JFreeChartDeleter</listener-class>
	</listener>


并且我把JFreechart生成柱状图、饼图和线性图简单封装了一下,写成一个工具类。如下所示:

package cn.edu.gcu.crm.utils;

import java.awt.Font;
import java.awt.Rectangle;
import java.io.File;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryAxis3D;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberAxis3D;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot3D;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer3D;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;

import cn.edu.gcu.crm.domain.ReportBean;
import cn.edu.gcu.crm.listener.JFreeChartDeleter;

/**
 * 报表生成工具类
 * 
 * @author Administrator
 * 
 */

public class JFreeChartUtils {
	/**
	 * 生成饼图
	 * 
	 * @param title主标题
	 * @param reportBeans封装的数据
	 * @param request
	 * @param response
	 * @param servletContext
	 */
	public static void generatePie2Jpeg(String title, List<ReportBean> reportBeans, HttpServletRequest request, ServletContext servletContext) {

		try {
			if (reportBeans != null && reportBeans.size() > 0) {

				DefaultPieDataset dataset = new DefaultPieDataset();
				// dataset.setValue("签约客户", 6);
				for (ReportBean reportBean : reportBeans) {
					dataset.setValue(reportBean.getType(), reportBean.getCount());
				}

				JFreeChart jFreeChart = ChartFactory.createPieChart3D(title, // 主标题
						dataset, // 图表需要的数据
						true, // 是否显示图例
						true, // 是否显示工具提示
						true); // 是否产生url链接

				// ========================处理乱码 start========================

				// 1. 获取图表区域对象
				PiePlot3D PiePlot3D = (PiePlot3D) jFreeChart.getPlot();

				// 6. 处理主标题乱码
				jFreeChart.getTitle().setFont(new Font("宋体", Font.BOLD, 18));
				// 7. 处理子标题乱码
				jFreeChart.getLegend().setItemFont(new Font("宋体", Font.BOLD, 18));

				// 处理饼图信息乱码
				PiePlot3D.setLabelFont(new Font("宋体", Font.BOLD, 18));

				/*
				 * 按格式输出饼图提示信息 dataset.setValue("签约客户", 6);
				 * dataset.setValue("重要客户", 4); dataset.setValue("成交客户", 7);
				 * dataset.setValue("潜在客户", 2);
				 * 
				 * String format = "{0}:{1}({2})"; {0}: 签约客户 {1}: 6 {2}: 6所占的百分比
				 * : () 等,程序员可以随便添加的内容
				 */
				String format = "{0}:{1}({2})";
				PiePlot3D.setLabelGenerator(new StandardPieSectionLabelGenerator(format));
				// ===================处理乱码 end==========================

				// ***************************************************************************************
				// //保存生成的图形到某个路径下
				// 获取图片的保存的路径
				String tmpdir = servletContext.getRealPath("/temp");
				// 利用时间生成文件名
				String pieFileName = "pie" + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss") + ".jpeg";
				File file = new File(tmpdir, pieFileName);
				ChartUtilities.saveChartAsJPEG(file, jFreeChart, 800, 450);
				// 将文件名放在request域中
				request.setAttribute("pieFileName", pieFileName);

				// ********************************************************************************
				// 用session监听器删除生成的垃圾图片
				JFreeChartDeleter.deleteTempImg(request, tmpdir, pieFileName);

			}
		} catch (Exception e) {
			throw new RuntimeException();
		}

	}

	



	/**
	 * 生成柱状体
	 * 
	 * @param title主标题
	 * @param xAxisTitlex轴标题
	 * @param yAxisTitley轴标题
	 * @param reportBeans封装的数据
	 * @param request
	 * @param servletContext
	 */
	public static void generateBar2Jpeg(String title, String xAxisTitle, String yAxisTitle, List<ReportBean> reportBeans, HttpServletRequest request, ServletContext servletContext) {

		try {
			if (reportBeans != null && reportBeans.size() > 0) {

				DefaultCategoryDataset dataset = new DefaultCategoryDataset();

				// dataset.addValue(6, "客户等级", "签约客户");
				for (ReportBean reportBean : reportBeans) {
					dataset.setValue(reportBean.getCount(), xAxisTitle, reportBean.getType());
				}

				JFreeChart freeChart = ChartFactory.createBarChart3D(title, // 主标题
						xAxisTitle, // 类型类别,X轴标题
						yAxisTitle, // 值,Y轴标题
						dataset, // 图表需要的数据
						PlotOrientation.VERTICAL, // 图表的方向,水平or垂直
						true, // 是否显示图例
						true, // 是否显示工具提示
						true); // 是否产生url链接

				// ******************* 处理乱码 start *******************
				// 1. 获取图表区域对象
				CategoryPlot categoryPlot = (CategoryPlot) freeChart.getPlot();
				// 2. 通过图表区域对象获取X轴
				CategoryAxis3D categoryAxis3D = (CategoryAxis3D) categoryPlot.getDomainAxis();
				// 3. 通过图表区域对象获取Y轴
				NumberAxis3D numberAxis3D = (NumberAxis3D) categoryPlot.getRangeAxis();

				// 4. 处理X轴的乱码
				// 4.1 处理X轴上的乱码
				categoryAxis3D.setTickLabelFont(new Font("宋体", Font.BOLD, 18));
				// 4.2 处理X轴下的乱码
				categoryAxis3D.setLabelFont(new Font("宋体", Font.BOLD, 18));

				// 5. 处理Y轴的乱码
				// 5.1 处理Y轴上的乱码
				numberAxis3D.setTickLabelFont(new Font("宋体", Font.BOLD, 18));
				// 5.2 处理Y轴下的乱码
				numberAxis3D.setLabelFont(new Font("宋体", Font.BOLD, 18));

				// 6. 处理主标题乱码
				freeChart.getTitle().setFont(new Font("宋体", Font.BOLD, 18));
				// 7. 处理子标题乱码
				freeChart.getLegend().setItemFont(new Font("宋体", Font.BOLD, 18));
				// ******************* 处理乱码 end *******************

				// ******************* 设置刻度 start *******************

				// // 设置Y轴不是使用自动刻度
				// numberAxis3D.setAutoTickUnitSelection(false);
				// // 设置刻度
				// NumberTickUnit numberTickUnit = new NumberTickUnit(2);
				// numberAxis3D.setTickUnit(numberTickUnit);

				// ******************* 设置刻度 end *******************

				// 获取绘图区域对象
				BarRenderer3D barRenderer3D = (BarRenderer3D) categoryPlot.getRenderer();
				// 处理图形的宽度
				barRenderer3D.setMaximumBarWidth(0.08);
				// 处理柱体上的数字
				barRenderer3D.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
				// 处理柱体上的数字可见
				barRenderer3D.setBaseItemLabelsVisible(true);
				// 处理柱体上的数字的字体
				barRenderer3D.setBaseItemLabelFont(new Font("宋体", Font.BOLD, 18));

				// ***************************************************************************************
				// //保存生成的图形到某个路径下
				// 获取图片的保存的路径
				String realPath = servletContext.getRealPath("/temp");

				// 利用时间生成文件名
				String barFileName = "bar" + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss") + ".jpeg";

				File file = new File(realPath, barFileName);
				ChartUtilities.saveChartAsJPEG(file, freeChart, 800, 450);
				// 将文件名放在request域中
				request.setAttribute("barFileName", barFileName);
				// ***************************************************************************************
				// 用session监听器删除生成的垃圾图片
				JFreeChartDeleter.deleteTempImg(request, realPath, barFileName);
			}
		} catch (Exception e) {
			throw new RuntimeException();
		}

	}

	public static void generateLine2Jpeg(String title, String xAxisTitle, String yAxisTitle, List<ReportBean> reportBeans, HttpServletRequest request, ServletContext servletContext) {
		try {

			DefaultCategoryDataset dataset = new DefaultCategoryDataset();

			// dataset.addValue(6, "客户等级", "签约客户");
			for (ReportBean reportBean : reportBeans) {
				dataset.setValue(reportBean.getCount(), xAxisTitle, reportBean.getType());
			}

			if (reportBeans != null && reportBeans.size() > 0) {
				JFreeChart freeChart = ChartFactory.createLineChart(title, // 主标题
						xAxisTitle, // 类型类别,X轴标题
						yAxisTitle, // 值,Y轴标题
						dataset, // 图表需要的数据
						PlotOrientation.VERTICAL, // 图表的方向,水平or垂直
						true, // 是否显示图例
						true, // 是否显示工具提示
						true); // 是否产生url链接

				// ********* 处理乱码 start  **********************
				// 1. 获取图表区域对象
				CategoryPlot categoryPlot = (CategoryPlot) freeChart.getPlot();
				// 2. 通过图表区域对象获取X轴
				CategoryAxis categoryAxis = (CategoryAxis) categoryPlot.getDomainAxis();
				// 3. 通过图表区域对象获取Y轴
				NumberAxis numberAxis = (NumberAxis) categoryPlot.getRangeAxis();

				// 4. 处理X轴的乱码
				// 4.1 处理X轴上的乱码
				categoryAxis.setTickLabelFont(new Font("宋体", Font.BOLD, 18));
				// 4.2 处理X轴下的乱码
				categoryAxis.setLabelFont(new Font("宋体", Font.BOLD, 18));

				// 5. 处理Y轴的乱码
				// 5.1 处理Y轴上的乱码
				numberAxis.setTickLabelFont(new Font("宋体", Font.BOLD, 18));
				// 5.2 处理Y轴下的乱码
				numberAxis.setLabelFont(new Font("宋体", Font.BOLD, 18));

				// 6. 处理主标题乱码
				freeChart.getTitle().setFont(new Font("宋体", Font.BOLD, 18));
				// 7. 处理子标题乱码
				freeChart.getLegend().setItemFont(new Font("宋体", Font.BOLD, 18));
				// ************ 处理乱码 end  ******************

				// *********************** 设置刻度 start ***************************
				// 设置Y轴不是使用自动刻度
				// numberAxis.setAutoTickUnitSelection(false);
				// // 设置刻度
				// NumberTickUnit numberTickUnit = new NumberTickUnit(4);
				// numberAxis.setTickUnit(numberTickUnit);
				// *********************** 设置刻度 end  ******************************

				// ***************************************************************************
				// //获取绘图区域对象
				LineAndShapeRenderer lineAndShapeRenderer = (LineAndShapeRenderer) categoryPlot.getRenderer();
				// 处理线上的数字
				lineAndShapeRenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
				// 处理线上的数字可见
				lineAndShapeRenderer.setBaseItemLabelsVisible(true);
				// 处理柱体上的数字的字体
				lineAndShapeRenderer.setBaseItemLabelFont(new Font("宋体", Font.BOLD, 12));

				// **************************************************************************
				// 处理拐角处的点()矩形
				Rectangle rectangle = new Rectangle(8, 8);
				lineAndShapeRenderer.setSeriesShape(0, rectangle);
				lineAndShapeRenderer.setSeriesShapesVisible(0, true);

				// ****************************************************************************
				// //保存生成的图形到某个路径下
				// 获取图片的保存的路径
				String realPath = servletContext.getRealPath("/temp");

				// 利用时间生成文件名
				String lineFileName = "line" + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss") + ".jpeg";

				File file = new File(realPath, lineFileName);
				ChartUtilities.saveChartAsJPEG(file, freeChart, 800, 450);
				// 将文件名放在request域中
				request.setAttribute("lineFileName", lineFileName);
				// 用session监听器删除生成的垃圾图片
				JFreeChartDeleter.deleteTempImg(request, realPath, lineFileName);

			}
		} catch (Exception e) {
			throw new RuntimeException();
		}
	}
	
	
	
	
	
	
	
	
}

在上面的报表工具了中调用重写的监听器,如在生成线性图的方法中:

// 用session监听器删除生成的垃圾图片
JFreeChartDeleter.deleteTempImg(request, realPath, lineFileName);

然后就是在struts2的action中调用工具类生成报表了,调用代码如下:

ServletContext servletContext = ServletActionContext.getServletContext();
JFreeChartUtils.generatePie2Jpeg("客户等级统计报表", reportBeans, request, servletContext);
JFreeChartUtils.generateBar2Jpeg("客户等级统计报表", "客户等级", "数量", reportBeans, request, servletContext);
JFreeChartUtils.generateLine2Jpeg("客户等级统计报表", "客户等级", "数量", reportBeans, request, servletContext);

其中reportBeans是用于封装数据用的,并且是一个list集合

public class ReportBean {

	private String type;//类型
	private Long count;//数量
}

最后,就是在jsp页面的显示图片:

<img src="${pageContext.request.contextPath}/temp/${barFileName}" border="0"> 
<img src="${pageContext.request.contextPath}/temp/${lineFileName}" border="0">
<img src="${pageContext.request.contextPath}/temp/${pieFileName}" border="0">

如此就大功告成了。这样就能自动删除JFreechart生成的垃圾图片了。

使用该监听器有如下几种情况可自动删除删除JFreechart生成的垃圾图片

/**
     * a. 执行session.setAttribute("JFreeChart_Deleter",非JFreeChartDeleter对象) 时。
     * b.执行session.removeAttribute("JFreeChart_Deleter") 时。
     * c.执行session.invalidate()时。
     * d.session超时后。一般为30 分钟
     */

例如在产生图片的action中,一开始直接从session中删除JFreeChart_Deleter,即

session.removeAttribute("JFreeChart_Deleter")
就可以在每一次生成新图片的时候删除上一次生成的图片。




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值