qq200874 发表于 2013-1-15 02:36:58

修改Fckeditor图片上传功能(java版)

                 Fckeditor默认是带图片上传的功能 但是这不能满足我们的要求 比如说有的版本的Fckeditor有中文乱码的问题,我用的这个Fckediotr上传图片还有Bug,另外也没办法给图片加水印,传上去的图片还是放在工程下的将来会导致图片越来越庞大,怎么办呢? 我们自己动手丰衣足食,把fckeditor改造成我们需要的.
 
               我用的Fckeditor的jar包是2.5版本的 这个版本图片没有中文乱码 另外如果有中文乱码的问题我建议也不要把图片名称改为UUID名称,因为当用户把自己的图片传上去的时候 想点浏览在去找这张图片的时候 他发现上面的那么多的名字根本分不清哪个是他这次传上来的.有人会问那图片名字重复了怎么办呢?Fckeditor已经考虑到这个问题了 他检测到服务器上有这个名字的图片他会自动重命名.废话不多说了我们来看我是怎么干的.
 
             我们要解决的几个问题
             1.上传图片放到服务器的一个物理位置而不是工程下.
             2.解决Fckeditor2.5版本中图片上传 没有flush的问题
             3.增加水印功能.
          
               Fckeditor低版本的时候我们需要重写一个Servlet 但是我发现这个版本图片上传功能是放在一个类下的而不是
旧版本中的ConnectorServlet.那既然需要重写一个类 而这个类呢有是ConnectorServlet中调用的那我们是不是得先重写ConnectorServlet 然后在重写这个类,然后再把自己写的ConnectorServlet配置到web.xml中呢?不用那么麻烦我不是那样做的 看下图我是怎么做的 ,并请大家自己思考为什么可以这么做.
 
             
http://dl.iteye.com/upload/attachment/234773/19037e13-da7b-3fa0-95bf-8a3d0c51ad86.jpg
 
                           我在工程下建了和fckeditor相同的包结构然后把我需要重写的类从Fckeditor源代码中拷了过来
 好了 我们开始修改吧
 
                 Dispatcher.java中doPost方法
  
            
UploadResponse doPost(final HttpServletRequest request) {logger.debug("Entering Dispatcher#doPost");//String type = null;Context context = ThreadLocalData.getContext();context.logBaseParameters();UploadResponse uploadResponse = null;// check permissions for user actionsif (!RequestCycleHandler.isEnabledForFileUpload(request))uploadResponse = UploadResponse.getFileUploadDisabledError();// check parameterselse if (!Command.isValidForPost(context.getCommandStr()))uploadResponse = UploadResponse.getInvalidCommandError();else if (!ResourceType.isValidType(context.getTypeStr()))uploadResponse = UploadResponse.getInvalidResourceTypeError();else if (!UtilsFile.isValidPath(context.getCurrentFolderStr()))uploadResponse = UploadResponse.getInvalidCurrentFolderError();else {// call the Connector#fileUploadResourceType type = context.getDefaultResourceType();FileItemFactory factory = new DiskFileItemFactory();ServletFileUpload upload = new ServletFileUpload(factory);try {List<FileItem> items = upload.parseRequest(request);// We upload just one file at the same timeFileItem uplFile = items.get(0);// Some browsers transfer the entire source path not just the// filenameString fileName = FilenameUtils.getName(uplFile.getName());logger.debug("Parameter NewFile: {}", fileName);// check the extensionif (type.isNotAllowedExtension(FilenameUtils.getExtension(fileName)))uploadResponse = UploadResponse.getInvalidFileTypeError();// Secure image check (can't be done if QuickUpload)else if (type.equals(ResourceType.IMAGE)&& PropertiesLoader.isSecureImageUploads()&& !UtilsFile.isImage(uplFile.getInputStream())) {uploadResponse = UploadResponse.getInvalidFileTypeError();} else {String sanitizedFileName = UtilsFile.sanitizeFileName(fileName);//修改为UUID文件名称我这里注释掉了 如下代码可以把上传的图片名称改为UUID//sanitizedFileName = UUID.randomUUID().toString()+sanitizedFileName.substring(sanitizedFileName.lastIndexOf("."), sanitizedFileName.length());logger.debug("Parameter NewFile (sanitized): {}",sanitizedFileName);String newFileName = connector.fileUpload(type, context.getCurrentFolderStr(), sanitizedFileName, uplFile.getInputStream());String fileUrl = UtilsResponse.fileUrl(RequestCycleHandler.getUserFilesPath(request), type, context.getCurrentFolderStr(), newFileName);//Fckeditor上传有两种 一种是上传图片 一种是上传附件//如果是图片的话 我用这个action来预览图片if(type.equals(ResourceType.IMAGE)){fileUrl = "tumbnail.action?fileName="+sanitizedFileName;}//如果是上传附件的话 用如下的action来下载附件else if(type.equals(ResourceType.FILE)){    sanitizedFileName = URLEncoder.encode(sanitizedFileName, "utf-8");fileUrl = request.getContextPath()+"/attachmentDownload.action?fileName="+sanitizedFileName;}if (sanitizedFileName.equals(newFileName))uploadResponse = UploadResponse.getOK(fileUrl);else {uploadResponse = UploadResponse.getFileRenamedWarning(fileUrl, newFileName);logger.debug("Parameter NewFile (renamed): {}",newFileName);}}uplFile.delete();} catch (InvalidCurrentFolderException e) {uploadResponse = UploadResponse.getInvalidCurrentFolderError();} catch (WriteException e) {uploadResponse = UploadResponse.getFileUploadWriteError();} catch (IOException e) {uploadResponse = UploadResponse.getFileUploadWriteError();} catch (FileUploadException e) {uploadResponse = UploadResponse.getFileUploadWriteError();}}logger.debug("Exiting Dispatcher#doPost");return uploadResponse;} 
   
   AbstractLocalFileSystemConnector.java 中 fileUpload方法
 
 
public String fileUpload(final ResourceType type, final String currentFolder, final String fileName, final InputStream inputStream) throws InvalidCurrentFolderException, WriteException {String absolutePath = getRealUserFilesAbsolutePath(RequestCycleHandler.getUserFilesAbsolutePath(ThreadLocalData.getRequest()));      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());OutputStream outputStream = null;try {outputStream = new FileOutputStream(fileToSave);IOUtils.copyLarge(inputStream, outputStream);} catch (IOException e) {throw new WriteException();} finally {try {    if (outputStream != null) {    //这里解决这个版本中图片上传没有flush的bugoutputStream.flush();IOUtils.closeQuietly(outputStream);}    IOUtils.closeQuietly(inputStream);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}String format = fileToSave.getName().substring(fileToSave.getName().lastIndexOf(".") + 1, fileToSave.getName().length());//下面给图片加水印//如果是图片的话 加水印if (ImageUtils.isPicture(format)) {ImageUtils.pressImage(servletContext.getRealPath("themes/cms/image/") +"\\"+ "sxgajj.png", newFile.getAbsoluteFile().getAbsolutePath());}return fileToSave.getName();} 
   另外还有图片预览的action 和 加水印的代码
 
   图片预览的action代码
 
  
public class FckImgPreviewAction {private String fileName;public String execute() {if (fileName != null) {    //图片在服务器上的物理存放路径String path = ResourceBundle.getBundle("sysConfig").getString("userFilePath.image");File file = new File("/" + path + fileName);HttpServletResponse resp = ServletActionContext.getResponse();OutputStream os = null;InputStream is = null;if (file.exists()) {try {is = new FileInputStream(file);os = resp.getOutputStream();IOUtils.copyLarge(is, os);} catch (IOException e) {e.printStackTrace();}finally{try {IOUtils.closeQuietly(is);if(os != null){os.flush();IOUtils.closeQuietly(os);}} catch (IOException e) {e.printStackTrace();}}}}return null;}public String getFileName() {return fileName;}public void setFileName(String fileName) {this.fileName = fileName;}} 
 
  
/** * @param pressImg 水印文件路径 * @param targetImg 目标文件路径 */public final static void pressImage(String pressImg, String targetImg) {FileOutputStream out = null;try {File _file = new File(targetImg);Image src = ImageIO.read(_file);int wideth = src.getWidth(null);int height = src.getHeight(null);BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);Graphics g = image.createGraphics();g.drawImage(src, 0, 0, wideth, height, null);// 水印文件File _filebiao = new File(pressImg);Image src_biao = ImageIO.read(_filebiao);int wideth_biao = src_biao.getWidth(null);int height_biao = src_biao.getHeight(null);g.drawImage(src_biao, wideth - wideth_biao, height - height_biao, wideth_biao, height_biao, null);// /g.dispose();out = new FileOutputStream(targetImg);JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);encoder.encode(image);} catch (Exception e) {e.printStackTrace();}finally{if(out!=null){try {out.flush();out.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}} 
   还有个重要的类差点忘了  GetResponse.java  GetResponse方法 
 
   让fck在上传完图片后 fck图片预览图片url正确的显示
  
public GetResponse(Command command, ResourceType type,String currentFolder, String constructedUrl) {try {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();document = builder.newDocument();} catch (ParserConfigurationException e) {throw new RuntimeException(e);}Element root = document.createElement("Connector");document.appendChild(root);root.setAttribute("command", command.getName());root.setAttribute("resourceType", type.getName());Element currentFolderElement = document.createElement("CurrentFolder");currentFolderElement.setAttribute("path", currentFolder);if(type.equals(ResourceType.IMAGE)){constructedUrl = "tumbnail.action?fileName=";}else if(type.equals(ResourceType.FILE)){constructedUrl = "attachmentDownload.action?fileName=";}currentFolderElement.setAttribute("url", constructedUrl);//System.out.println(constructedUrl);root.appendChild(currentFolderElement);} 
 
    ok了 看下效果
 
 
 

 http://dl.iteye.com/upload/attachment/234843/740a138d-2b50-37af-a032-595c7f8554bd.jpg
 

http://dl.iteye.com/upload/attachment/234846/70c17b64-4c6c-3015-8f0c-f4ccb199112b.jpg
 
 
            
  
http://dl.iteye.com/upload/attachment/234849/09d95bee-adf3-3b1c-88c8-be6f4c526c8e.jpg
          
 

 
 
 
 
 
 
 
 
页: [1]
查看完整版本: 修改Fckeditor图片上传功能(java版)