jfreechart出现ChartDeleter没有序列化问题导致session信息丢失的解决方法

jfreechart0.9版本的在生成图表后出现ChartDeleter没有序列化问题的解决方法,错误信息如下

2009-09-01 16:53:52,066 [] ERROR encoder.EncryptCookieEncoderImpl - Failed to encode cookie state java.io.NotSerializableException: org.jfree.chart.servlet.ChartDeleter at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) at java.util.HashMap.writeObject(HashMap.java:1001) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)

这样图片是能正常显示的,但是这样可能会导致session原有的信息丢失,是因为ChartDeleter是传入session时如果没有经过序列化处理,反序列化回来的时候会破坏session的其它信息。

解决方法如下:把jfreechart的下面两个类取出来,放到自己的工程里

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.jfree.chart.ChartRenderingInfo; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; /** * Utility class used for servlet related JFreeChart operations. * * @author Richard Atkinson */ public class ServletUtilities { /** The filename prefix. */ private static String tempFilePrefix = "jfreechart-"; /** * Returns the prefix for the temporary file names generated by this class. * * @return The prefix (never <code>null</code>). */ public static String getTempFilePrefix() { return ServletUtilities.tempFilePrefix; } /** * Sets the prefix for the temporary file names generated by this class. * * @param prefix the prefix (<code>null</code> not permitted). */ public static void setTempFilePrefix(String prefix) { if (prefix == null) { throw new IllegalArgumentException("Null 'prefix' argument."); } ServletUtilities.tempFilePrefix = prefix; } /** * Saves the chart as a PNG format file in the temporary directory. * * @param chart the JFreeChart to be saved. * @param width the width of the chart. * @param height the height of the chart. * @param session the HttpSession of the client. * * @return the filename of the chart saved in the temporary directory. * * @throws IOException if there is a problem saving the file. */ public static String saveChartAsPNG(JFreeChart chart, int width, int height, HttpSession session) throws IOException { return ServletUtilities.saveChartAsPNG(chart, width, height, null, session); } /** * Saves the chart as a PNG format file in the temporary directory and * populates the ChartRenderingInfo object which can be used to generate * an HTML image map. * * @param chart the chart to be saved (<code>null</code> not permitted). * @param width the width of the chart. * @param height the height of the chart. * @param info the ChartRenderingInfo object to be populated (<code>null</code> permitted). * @param session the HttpSession of the client. * * @return the filename of the chart saved in the temporary directory. * * @throws IOException if there is a problem saving the file. */ public static String saveChartAsPNG(JFreeChart chart, int width, int height, ChartRenderingInfo info, HttpSession session) throws IOException { if (chart == null) { throw new IllegalArgumentException("Null 'chart' argument."); } ServletUtilities.createTempDir(); File tempFile = File.createTempFile( ServletUtilities.tempFilePrefix, ".png", new File(System.getProperty("java.io.tmpdir")) ); ChartUtilities.saveChartAsPNG(tempFile, chart, width, height, info); ServletUtilities.registerChartForDeletion(tempFile, session); return tempFile.getName(); } /** * Saves the chart as a JPEG format file in the temporary directory. * * @param chart the JFreeChart to be saved. * @param width the width of the chart. * @param height the height of the chart. * @param session the HttpSession of the client. * * @return the filename of the chart saved in the temporary directory. * * @throws IOException if there is a problem saving the file. */ public static String saveChartAsJPEG(JFreeChart chart, int width, int height, HttpSession session) throws IOException { return ServletUtilities.saveChartAsJPEG(chart, width, height, null, session); } /** * Saves the chart as a JPEG format file in the temporary directory and * populates the ChartRenderingInfo object which can be used to generate * an HTML image map. * * @param chart the chart to be saved (<code>null</code> not permitted). * @param width the width of the chart * @param height the height of the chart * @param info the ChartRenderingInfo object to be populated * @param session the HttpSession of the client * * @return the filename of the chart saved in the temporary directory * * @throws IOException if there is a problem saving the file. */ public static String saveChartAsJPEG(JFreeChart chart, int width, int height, ChartRenderingInfo info, HttpSession session) throws IOException { if (chart == null) { throw new IllegalArgumentException("Null 'chart' argument."); } ServletUtilities.createTempDir(); File tempFile = File.createTempFile( ServletUtilities.tempFilePrefix, ".jpeg", new File(System.getProperty("java.io.tmpdir")) ); ChartUtilities.saveChartAsJPEG(tempFile, chart, width, height, info); ServletUtilities.registerChartForDeletion(tempFile, session); return tempFile.getName(); } /** * Creates the temporary directory if it does not exist. * Throws a RuntimeException if the temporary directory is null. * Uses the system property java.io.tmpdir as the temporary directory. * Sounds like a strange thing to do but my temporary directory was not created * on my default Tomcat 4.0.3 installation. Could save some questions on the * forum if it is created when not present. */ protected static void createTempDir() { String tempDirName = System.getProperty("java.io.tmpdir"); if (tempDirName == null) { throw new RuntimeException( "Temporary directory system property (java.io.tmpdir) is null"); } // Create the temporary directory if it doesn't exist File tempDir = new File(tempDirName); if (!tempDir.exists()) { tempDir.mkdirs(); } } /** * Adds a ChartDeleter object to the session object with the name JFreeChart_Deleter * if there is not already one bound to the session and adds the filename to the * list of charts to be deleted. * * @param tempFile the file to be deleted. * @param session the HTTP session of the client. */ protected static void registerChartForDeletion(File tempFile, HttpSession session) { // Add chart to deletion list in session if (session != null) { ChartDeleter chartDeleter = (ChartDeleter) session.getAttribute("JFreeChart_Deleter"); if (chartDeleter == null) { chartDeleter = new ChartDeleter(); session.setAttribute("JFreeChart_Deleter", chartDeleter); } chartDeleter.addChart(tempFile.getName()); } else { System.out.println("Session is null - chart will not be deleted"); } } /** * Binary streams the specified file in the temporary directory to the * HTTP response in 1KB chunks * @param filename The name of the file in the temporary directory. * @param response The HTTP response object. * @throws IOException if there is an I/O problem. */ public static void sendTempFile(String filename, HttpServletResponse response) throws IOException { File file = new File(System.getProperty("java.io.tmpdir"), filename); ServletUtilities.sendTempFile(file, response); } /** * Binary streams the specified file to the HTTP response in 1KB chunks * * @param file The file to be streamed. * @param response The HTTP response object. * * @throws IOException if there is an I/O problem. */ public static void sendTempFile(File file, HttpServletResponse response) throws IOException { String mimeType = null; String filename = file.getName(); if (filename.length() > 5) { if (filename.substring(filename.length() - 5, filename.length()).equals(".jpeg")) { mimeType = "image/jpeg"; } else if (filename.substring(filename.length() - 4, filename.length()).equals(".png")) { mimeType = "image/png"; } } ServletUtilities.sendTempFile(file, response, mimeType); } /** * Binary streams the specified file to the HTTP response in 1KB chunks * * @param file The file to be streamed. * @param response The HTTP response object. * @param mimeType The mime type of the file, null allowed. * * @throws IOException if there is an I/O problem. */ public static void sendTempFile(File file, HttpServletResponse response, String mimeType) throws IOException { if (file.exists()) { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); // Set HTTP headers if (mimeType != null) { response.setHeader("Content-Type", mimeType); } response.setHeader("Content-Length", String.valueOf(file.length())); SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z"); response.setHeader("Last-Modified", sdf.format(new Date(file.lastModified()))); BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); byte[] input = new byte[1024]; boolean eof = false; while (!eof) { int length = bis.read(input); if (length == -1) { eof = true; } else { bos.write(input, 0, length); } } bos.flush(); bis.close(); bos.close(); } else { throw new FileNotFoundException(file.getAbsolutePath()); } return; } /** * Perform a search/replace operation on a String * There are String methods to do this since (JDK 1.4) * * @param inputString the String to have the search/replace operation. * @param searchString the search String. * @param replaceString the replace String. * * @return the String with the replacements made. */ public static String searchReplace(String inputString, String searchString, String replaceString) { int i = inputString.indexOf(searchString); if (i == -1) { return inputString; } String r = ""; r += inputString.substring(0, i) + replaceString; if (i + searchString.length() < inputString.length()) { r += searchReplace(inputString.substring(i + searchString.length()), searchString, replaceString); } return r; } } 和

import java.io.File; import java.util.Iterator; import java.util.List; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; /** * Used for deleting charts from the temporary directory when the users session * expires. * * @author Richard Atkinson */ public class ChartDeleter implements HttpSessionBindingListener{ /** The chart names. */ private List chartNames = new java.util.ArrayList(); /** * Blank constructor. */ public ChartDeleter() { 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. */ public void addChart(String filename) { this.chartNames.add(filename); } /** * 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) { return (this.chartNames.contains(filename)); } /** * Binding this object to the session has no additional effects. * * @param event the session bind event. */ public void valueBound(HttpSessionBindingEvent event) { return; } /** * When this object is unbound from the session (including upon session * expiry) the files that have been added to the ArrayList are iterated * and deleted. * * @param event the session unbind event. */ public void valueUnbound(HttpSessionBindingEvent event) { Iterator iter = this.chartNames.listIterator(); while (iter.hasNext()) { String filename = (String) iter.next(); File file = new File(System.getProperty("java.io.tmpdir"), filename); if (file.exists()) { file.delete(); } } return; } }

然后修改ChartDeleter类,使其实现java.io.Serializable接口就ok了,其它东西不需要改动。

public class ChartDeleter implements HttpSessionBindingListener, java.io.Serializable

 

 

你可能感兴趣的:(object,String,session,jfreechart,File,null)