A rich text editor for the Web FCK everyone should not be unfamiliar with it, the most recent project encountered a problem, that is, every time you restart the server through the FCK upload
The file is completely lost, which may be caused by the server deploying the application again over the war each time it reboots.
There are currently 3 of solutions to this problem:
1, write a background process dedicated to maintain FCK uploaded files.
2, bit FCK specifically deploy a server.
3, the implementation of FCK upload and download function (is the file can upload to any specified path, not the relative path of the application).
I do not know the network warrior Door there is no other solution, everyone functional learning.
In the above scenario, the first scheme is mainly to move the folder before and after the service restart, which is time-consuming to maintain when the file is large, or it may be in the process of moving
The file was lost due to external causes. The second scheme to build a server for FCK, maintenance more trouble. To think about it or to use the third option is more appropriate.
After reading the source code of FCK, finally found the implementation method. Now on the specific implementation of written down for netizens to refer to, there are wrong, not reasonable place also hope to correct.
First we finish uploading the text to the specified directory. In order to meet the requirements we need to implement the FCK connector interface. In this interface it is stated that several methods are required
Want us to achieve:
Init (final ServletContext ServletContext);
FileUpload (final resourcetype type, final string CurrentFolder, final string filename,final InputStream InputStream)
CreateFolder (final resourcetype type, final string CurrentFolder, final string newfolder)
GetFiles (resourcetype type, String currentfolder)
Getfolders (final resourcetype type, final String CurrentFolder)
The following is the implementation class for the connector interface Contextconnector
package COM.BZLCCN.OA.COMMON.FCK; Import Java.io.File; Import Java.io.FileFilter; Import Java.io.FileOutputStream; Import java.io.IOException; Import Java.io.InputStream; Import java.util.ArrayList; Import Java.util.Arrays; Import Java.util.HashMap; Import java.util.List; Import Java.util.Map; Import Javax.servlet.ServletContext; Import Net.fckeditor.connector.Connector; Import net.fckeditor.connector.exception.FolderAlreadyExistsException; Import net.fckeditor.connector.exception.InvalidCurrentFolderException; Import net.fckeditor.connector.exception.InvalidNewFolderNameException; Import net.fckeditor.connector.exception.WriteException; Import Net.fckeditor.handlers.ResourceType; Import Net.fckeditor.tool.UtilsFile; Import Org.apache.commons.io.IOUtils; Import Org.apache.commons.io.filefilter.DirectoryFileFilter; Import Org.apache.commons.io.filefilter.FileFileFilter; Import Org.slf4j.Logger; Import Org.slf4j.LoggerFactory; public class Contextconnector implements ConnectoR {Private final Logger Logger = Loggerfactory.getlogger (contextconnector.class); protected ServletContext ServletContext; Initializes public void init (final ServletContext ServletContext) throws Exception {this.servletcontext = ServletContext; String Defaultabsolutepath = Utilspath.getrealuserfilesabsolutepath (); if (Defaultabsolutepath = = null) {Logger.error ("the context root cannot is resolved against the local filesystem"); Logge R.info ("Your servlet container/application Server does not expand deployed war files"); Logger. Debug ("Use another Connector implementation (e.g. localconnector) and consult http://www.fckeditor.net/forums/ viewtopic.php?f=6&t=11568 "); throw new NullPointerException ("The real context root cannot is resolved against the local filesystem"); The file is uploaded to the path we specified, and the path's acquisition is implemented in Utilspath. Public String fileupload (final resourcetype type, final string CurrentFolder, final string fileName, final InputStream INP Utstream) throws Invalidcurrentfolderexception, writeexceptIon {String Absolutepath = Utilspath.getrealuserfilesabsolutepath (); File Typedir = Getorcreateresourcetypedir (Absolutepath, type); File Currentdir = new file (Typedir, CurrentFolder); if (!currentdir.exists () | | |!currentdir.isdirectory ()) throw new Invalidcurrentfolderexception (); File NewFile = new file (Currentdir, fileName); File Filetosave = Utilsfile.getuniquefile (Newfile.getabsolutefile ()); try {ioutils.copylarge (InputStream, New FileOutputStream (Filetosave));} catch (IOException e) {throw new writeexception (); return Filetosave.getname (); //Create folder public void CreateFolder (final resourcetype type, final string CurrentFolder, final string newfolder) throws Inv Alidcurrentfolderexception, Invalidnewfoldernameexception, folderalreadyexistsexception {String AbsolutePath = Utilspath.getrealuserfilesabsolutepath (); File Typedir = Getorcreateresourcetypedir (Absolutepath, type); File Currentdir = new file (Typedir, CurrentFolder); if (!currentdir.exists () | |!currentdir.isdirectory () throw new Invalidcurrentfolderexception (); File Newdir = new file (Currentdir, NewFolder); if (newdir.exists ()) throw new Folderalreadyexistsexception (); if (!newdir.mkdir ()) throw new Invalidnewfoldernameexception (); //Get all Files public list<map<string, object>> getfiles (resourcetype type, String CurrentFolder) throws invalidcurrentfolderexception {String Absolutepath = Utilspath.getrealuserfilesabsolutepath (); File Typedir = Getorcreateresourcetypedir (Absolutepath, type); File Currentdir = new file (Typedir, CurrentFolder); if (!currentdir.exists () | | |!currentdir.isdirectory ()) throw new Invalidcurrentfolderexception (); Collect files list<map<string, object>> files; Map<string, object> Filemap; file[] filelist = Currentdir.listfiles ((filefilter) filefilefilter.file); Files = new arraylist<map<string, object>> (filelist.length); for (file file:filelist) {filemap = new hashmap<string, object> (2); Filemap.put (connector.key_name, file. GetName ()); Filemap.put (Connector.key_size, File.length ()); Files.add (FILEMAP); return to files; //Get all Folders public list<string> getfolders (final resourcetype type, final String CurrentFolder) throws Invalidcurre ntfolderexception {String Absolutepath = Utilspath.getrealuserfilesabsolutepath (); File Typedir = Getorcreateresourcetypedir (Absolutepath, type); File Currentdir = new file (Typedir, CurrentFolder); if (!currentdir.exists () | | |!currentdir.isdirectory ()) throw new Invalidcurrentfolderexception (); string[] filelist = currentdir.list (directoryfilefilter.directory); Return Arrays.aslist (filelist); //Create a directory based on the type of upload file. protected static file Getorcreateresourcetypedir (final String baseDir, final resourcetype type) {file Dir = new File (base Dir, Type.getpath ()); if (!dir.exists ()) dir.mkdirs (); return dir; } }
The code for the Utilspath tool class used in the above Contextconnector class is as follows:
package com.bzlccn.oa.common.fck; import Org.slf4j.Logger; import Org.slf4j.LoggerFactory; Import com.bzlccn.oa.common.util.Constants; Import Com.bzlccn.oa.common.util.OSUtil; Import com.bzlccn.oa.common.util.exception.SystemConfigrationException; public class Utilspath {private static final Logger Logger = Loggerfactory.getlogger (utilspath.class), public static Stri Ng Getrealuserfilesabsolutepath () {String path = ""; try {//need to judge the operating system used, set the path according to the different system. if (osutil.isunixlikesystem () = = true) {Path = constants.getpropertyof (Constants.fck_linux_path);} else {path = Constan Ts.getpropertyof (Constants.fck_windows_path); } catch (Systemconfigrationexception e) {if (Osutil.isunixlikesystem () = = true) {path = '//usr/local/oa//fck ';} else {path = ' c://oa//fck ';} Logger.info ("Configuration file error, use default path (" +path+ ") Save FCK upload file); return path; } }
In order for the uploaded files to cross the platform (currently only support Liunx and Windwos), the current system needs to be used. The tool classes are as follows:
Package com.bzlccn.oa.common.util; public class Osutil {private static final String Windows = "Windows";/** * Determining the type of the current operating system * * @return false means window Sy Stem, true means Unix like system */public static Boolean Isunixlikesystem () {String name = System.getproperty (Constants. Os_name_key); if (name!= null) {if (Name.touppercase (). IndexOf (WINDOWS) = = 1) {//it means it ' Unix like system return true;}} False } }
In order to achieve the upload path flexible configuration also need to write a read configuration file tool class:
Package Com.bzlccn.oa.common.util import org.apache.commons.configuration.Configuration; import Org.apache.commons.configuration.ConfigurationException; Import org.apache.commons.configuration.PropertiesConfiguration; Import com.bzlccn.oa.common.util.exception.SystemConfigrationException; public class Constants {//FCK file upload public static final String fck_windows_path= ' Fck.windows.path '; public static final Str ing fck_linux_path= "Fck.linux.path"; static{try {config = new propertiesconfiguration ("Fckeditor.properties");} catch (ConfigurationException e) {e.printst Acktrace (); } public static string getpropertyof (String key) throws systemconfigrationexception{if (config = = null) {throw new Syst Emconfigrationexception ("Can not configure system"); return config.getstring (key); public static void Main (String args[]) throws ConfigurationException, systemconfigrationexception{System.out.println (Getpropertyof ("port")); } }
In order to upload the file to the specified path of the function has been basically implemented, as long as let FCK call our Contextconnector class on it, how to let FCK call our own
Implementation of this Contextconnector class, as long as the configuration of the configuration file can be. Simply add the following configuration file to the FCK configuration file:
Connector.impl=com.bzlccn.oa.common.fck.contextconnector
Here is the question of how to display the file we uploaded. The implementation is, first of all, we have to write a servlet to download the file, the specific code is as follows:
Package COM.BZLCCN.OA.COMMON.FCK; Import Java.io.FileInputStream; Import java.io.IOException; Import Java.io.InputStream; Import javax.servlet.ServletException; Import Javax.servlet.ServletOutputStream; Import Javax.servlet.http.HttpServlet; Import Javax.servlet.http.HttpServletRequest; Import Javax.servlet.http.HttpServletResponse; Import Org.apache.taglibs.standard.extra.spath.Path; public class Fckdownloadservlet extends HttpServlet {private static final long serialversionuid = -5742008970929377161l; @Override protected void doget (final httpservletrequest request, final httpservletresponse response) throws Servletexception, IOException {doPost (request,response);} @Override protected void DoPost (final httpservletrequest Request, final HttpServletResponse response) throws Servletexception, IOException {String path=request.getparameter (" Path "); Request.setcharacterencoding ("UTF-8"); Response.setcharacterencoding ("UTF-8"); Setresponsecontenttype (Response,path); Response.setheader ("CAche-control "," No-cache "); if (path!=null) {Path=utilspath.getrealuserfilesabsolutepath () +path;} else{Path=this.getservletcontext (). Getrealpath ("/images/sign/no. JPG "); } InputStream is = new FileInputStream (path); Servletoutputstream Servletoutputstream=response.getoutputstream (); Loop out the data in the stream byte[] b = new byte[100]; int Len; try {while (len = Is.read (b)) > 0) {servletoutputstream.write (b, 0, Len);} catch (IOException e) {e.printstacktr Ace (); }finally{if (servletoutputstream!=null) {Servletoutputstream.flush (); Servletoutputstream.close ();} if (Is!= null) . Close (); }/** * ContentType * @param eresponse * Based on file name extension * @param path/private void Setresponsecontenttype (HttpServletResponse Response,string path) {string contenttype= "Image/jpg;charset=utf-8"; if (path!=null) {string exname=path.substring ( Path.lastindexof (".") +1); if ("Bmp|gif|jpeg|jpg|png". IndexOf (Exname.tolowercase ()) >=0) {contenttype= "image/" +exname+ "; Charset=utf-8";} if ("Swf|fla". IndexOf (Exname).toLowerCase ()) >=0) {contenttype= "Application/x-shockwave-flash;charset=utf-8";}} Response.setcontenttype (ContentType); } }
To call our Fckdownloadservlet in order for FCK to display a picture, we also need to overload the Getuserfilespath method in the Serverrootpathbuilder class to implement the following
package COM.BZLCCN.OA.COMMON.FCK; Import Javax.servlet.http.HttpServletRequest; Import Net.fckeditor.requestcycle.impl.ServerRootPathBuilder; public class Contextpathbuilder extends Serverrootpathbuilder {@Override public String Getuserfilespath (final HttpServletRequest request) {return Request.getcontextpath (). Concat ("/fck/download.servlet?path=");/"/fck/ Download.servlet? " To be consistent with the Fckdownloadservlet path configured in Web.xml. } }
The Getuserfilespath method in the
Above class is primarily to get the path to the display file. How to get FCK to call our Getuserfilespath method, pass the or to
write to FCK configuration file:
Connector.userpathbuilderimpl = Com.bzlccn.oa.common.fck.ContextPathBuilder
Haha, so you can, and so on, not yet finished, but also need to configure Fckdownloadservlet, in the Web.xml need to enter:
<servlet>
<servlet-name>connectorservlet</servlet-name>
<servlet-class>net.fckeditor.connector.connectorservlet</servlet-class>
< Load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>fckdownloadservlet</servlet-name>
<servlet-class> Com.bzlccn.oa.common.fck.fckdownloadservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ConnectorServlet</servlet-name>
<!--don't wrap this line otherwise Glassfish'll fail to load this file-->
<url-pattern>/fckeditor/editor/filemanager/connectors/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FCKDownloadServlet</servlet-name>
<url-pattern>/fck/download.servlet</url-pattern>
</servlet-mapping>
Next, FCK's overall configuration file is posted:
Connector.useractionimpl=net.fckeditor.requestcycle.impl.enableduseraction
Connector.impl=com.bzlccn.oa.common.fck.contextconnector
Connector.userpathbuilderimpl = Com.bzlccn.oa.common.fck.ContextPathBuilder
Fck.windows.path=c:/oa/fck
Fck.linux.path=/home/oa/fck
One more thing to say is that the FCK version we use is 2.6.5.
Write a little hasty, inevitably have the wrong place to correct, more pat brick.
Implementation of the effect as shown in figure: