`
kyo100900
  • 浏览: 637896 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Struts2,Webwork2关于使用FCKeditor,richtexteditor 的解决方法

阅读更多

一 Webwork2 + FCkeditor

 

这个问题由来已久,这里我有一个比较好的办法,和大家分享一下。

Webwork 测试版本为2.2.6  +  WinXP

配置好 Webwork 环境后,在你的项目里建一个类,内容如下:

 

/*
 * Copyright (c) 2002-2003 by OpenSymphony
 * All rights reserved.
 */
package com.leo.controller;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.servlet.ServletContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.webwork.WebWorkException;
import com.opensymphony.webwork.components.AbstractRichtexteditorConnector;
import com.opensymphony.webwork.components.DefaultRichtexteditorConnector;
import com.opensymphony.webwork.util.ServletContextAware;
import com.opensymphony.webwork.views.util.UrlHelper;
import com.opensymphony.xwork.ActionContext;

/**
 * 
 * @author tm_jee
 * @version $Date: 2007-03-29 08:02:59 +0200 (Do, 29 Mrz 2007) $ $Id: DefaultRichtexteditorConnector.java 2883 2007-03-29 06:02:59Z tm_jee $
 */
public class MyConnector extends AbstractRichtexteditorConnector implements ServletContextAware {

    private static final Log _log = LogFactory.getLog(DefaultRichtexteditorConnector.class);

    private static final long serialVersionUID = -3792445192115623052L;

    protected String _actualServerPath = "/user_file/";
    protected String _serverPath = "/user_file/";


	public String getActualServerPath() { return _actualServerPath; }
    public void setActualServerPath(String actualServerPath) { _actualServerPath = actualServerPath; }


    protected String calculateServerPath(String serverPath, String folderPath, String type) throws Exception {
        //return UrlHelper.buildUrl(serverPath, _request, _response, null, _request.getScheme(), true, true, true);
        return UrlHelper.buildUrl(serverPath+type+folderPath, _request, _response, new HashMap(), _request.getScheme(), true, true, true);
    }

    protected String calculateActualServerPath(String actualServerPath, String type, String folderPath) throws Exception {
        String path = "file:////"+servletContext.getRealPath(actualServerPath);
        path = path.trim();
        path = path.replace('\\', '/'); 
        makeDirIfNotExists(path);
        path = path.endsWith("/") ? path : path+"/";
        return path+type+folderPath;
    }

    private ServletContext servletContext;
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    protected Folder[] getFolders(String virtualFolderPath, String type) throws Exception {
        String path = calculateActualServerPath(getActualServerPath(), type, virtualFolderPath);
        makeDirIfNotExists(path);
        java.io.File f = new java.io.File(new URI(path));
        java.io.File[] children = f.listFiles(new FileFilter() {
            public boolean accept(java.io.File pathname) {
                if (! pathname.isFile()) {
                    return true;
                }
                return false;
            }
        });

        List tmpFolders = new ArrayList();
        for (int a=0; a< children.length; a++) {
            tmpFolders.add(new Folder(children[a].getName()));
        }

        return (Folder[]) tmpFolders.toArray(new Folder[0]);
    }

    protected FoldersAndFiles getFoldersAndFiles(String virtualFolderPath, String type) throws Exception {
        String path = calculateActualServerPath(getActualServerPath(), type, virtualFolderPath);
        makeDirIfNotExists(path);
        java.io.File f = new java.io.File(new URI(path));
        java.io.File[] children = f.listFiles();

        List directories = new ArrayList();
        List files = new ArrayList();
        for (int a=0; a< children.length; a++) {
            if (children[a].isDirectory()) {
                directories.add(new Folder(children[a].getName()));
            }
            else {
                try {
                    files.add(new File(children[a].getName(), fileSizeInKBytes(children[a])));
                }
                catch(Exception e) {
                    _log.error("cannot deal with file "+children[a], e);
                }
            }
        }
        
        // TODO 非常重要的一句话,这样才能使用自定义的路径。
        ActionContext.getContext().put("__richtexteditorServerPath", calculateServerPath(get_serverPath(), getCurrentFolder(), getType()));

        return new FoldersAndFiles(
                (Folder[]) directories.toArray(new Folder[0]),
                (File[]) files.toArray(new File[0])
        );
    }

    protected CreateFolderResult createFolder(String virtualFolderPath, String type, String newFolderName) {
        try {
            String tmpPath = calculateActualServerPath(getActualServerPath(), type, virtualFolderPath);
            tmpPath = tmpPath+newFolderName;
            boolean alreadyExists = makeDirIfNotExists(tmpPath);
            if (alreadyExists) {
                return CreateFolderResult.folderAlreadyExists();
            }
        }
        catch(Exception e) {
            _log.error(e.toString(), e);
            return CreateFolderResult.unknownError();
        }
        return CreateFolderResult.noErrors();
    }

    protected FileUploadResult fileUpload(String virtualFolderPath, String type, String filename, String contentType, java.io.File newFile) {
        try {
            String tmpDir = calculateActualServerPath(getActualServerPath(), type, virtualFolderPath);
            makeDirIfNotExists(tmpDir);
            String tmpFile = tmpDir+filename;
            if(makeFileIfNotExists(tmpFile)) {
                // already exists
                int a=0;
                String ext = String.valueOf(a);
                tmpFile = calculateActualServerPath(getActualServerPath(), type, virtualFolderPath)+filename+ext;
                while(makeFileIfNotExists(tmpFile)) {
                    a = a + 1;
                    ext = String.valueOf(a);
                    if (a > 100) {
                        return FileUploadResult.invalidFile();
                    }
                    tmpFile = calculateActualServerPath(getActualServerPath(), type, virtualFolderPath)+filename+ext;
                }
                copyFile(newFile, new java.io.File(new URI(tmpFile)));
                return FileUploadResult.uploadCompleteWithFilenamChanged(filename+ext);
            }
            else {
                copyFile(newFile, new java.io.File(new URI(tmpFile)));
                return FileUploadResult.uploadComplete();
            }
        }
        catch(Exception e) {
            _log.error(e.toString(), e);
            return FileUploadResult.invalidFile();
        }
    }

    protected void unknownCommand(String command, String virtualFolderPath, String type, String filename, String contentType, java.io.File newFile) {
        throw new WebWorkException("unknown command "+command);
    }





    /**
     *
     * @param path
     * @return true if file already exists, false otherwise.
     */
    protected boolean makeDirIfNotExists(String path) throws URISyntaxException {
        java.io.File dir = new java.io.File(new URI(path));
        if (! dir.exists()) {
        	if (_log.isDebugEnabled()) {
        		_log.debug("make directory "+dir);
        	}
            boolean ok = dir.mkdirs();
            if (! ok) {
                throw new WebWorkException("cannot make directory "+dir);
            }
            return false;
        }
        return true;
    }

    /**
     *
     * @param filePath
     * @return true if file already exists, false otherwise
     */
    protected boolean makeFileIfNotExists(String filePath) throws IOException, URISyntaxException {
        java.io.File f = new java.io.File(new URI(filePath));
        if (! f.exists()) {
        	if (_log.isDebugEnabled()) {
        		_log.debug("creating file "+filePath);
        	}
            boolean ok = f.createNewFile();
            if (! ok) {
                throw new WebWorkException("cannot create file "+filePath);
            }
            return false;
        }
        return true;
    }

    protected void copyFile(java.io.File from, java.io.File to) throws FileNotFoundException, IOException {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
        	if (_log.isDebugEnabled()) {
        		_log.debug("copy file from "+from+" to "+to);
        	}
            fis = new FileInputStream(from);
            fos = new FileOutputStream(to);
            int tmpByte = fis.read();
            while(tmpByte != -1) {
                fos.write(tmpByte);
                tmpByte = fis.read();
            }
            fos.flush();
        }
        finally {
            if (fis != null)
                fis.close();
            if (fos != null)
                fos.close();
        }
    }

    protected long fileSizeInKBytes(java.io.File file) throws FileNotFoundException, IOException {
        FileInputStream fis = null;
        long size = 0;
        try {
            fis = new FileInputStream(file);
            size = fis.getChannel().size();
        }
        finally {
            if (fis != null)
                fis.close();
        }
        if (size > 0) {
            size = (size / 100);
        }
        if (_log.isDebugEnabled()) {
        	_log.debug("size of file "+file+" is "+size+" kb");
        }
        return size;
    }
    
    
    
    public String get_serverPath() {
		return _serverPath;
	}
	public void set_serverPath(String path) {
		_serverPath = path;
	}
}

 

 

注意以下变量部分:

1.在MyConnector.java第 42行的变量_actualServerPath 默认为值: /WEB-INF/classes/com/opensymphony/webwork/static/richtexteditor/data/, 从源码 com.opensymphony.webwork.components.DefaultRichtexteditorConnector.java 的第 38

protected String _actualServerPath = "/com/opensymphony/webwork/static/richtexteditor/data/";

以及第 51

 
String path = "file:////"+servletContext.getRealPath("/WEB-INF/classes"+actualServerPath);

 

 

可以得出。  

因此,我这里改成 /user_file 文件夹作为文件上传路径,你可以自由选择。

 

2.在MyConnector.java第 43行的变量_serverPath 表示的是上传完附件后,选择的路径,默认为: /webwork/richtexteditor/data/ 从源码 com.opensymphony.webwork.components.AbstractRichtexteditorConnector.java 的第 73 行:

 

protected String _serverPath = "/webwork/richtexteditor/data/";

 可以看到。 FCKEditor 使用时,会变成: http://IP地址 /项目 /webwork/richtexteditor/data/ . 记住,这里不会带端口号的,这也是唯一美中不足的地方,如果要修改,可能要改动很大了。

 

 因此,我这里改成也 /user_file 文件夹,为了可以在上传成功后, FCKEditor 能够选择上传成功的文件。

 

最后来到MyConnector.java 的第112行:

 

 
// TODO 非常重要的一句话,这样才能使用自定义的路径。
        ActionContext.getContext().put("__richtexteditorServerPath", calculateServerPath(get_serverPath(), getCurrentFolder(), getType()));

 

 

这里我详细说一下: MyConnector.java 继承自 AbstractRichtexteditorConnector.java ,在 AbstractRichtexteditorConnector.java 源码146行左右有这么一段:

 

else if ("CreateFolder".equals(getCommand())) {
			_log.debug("Command "+getCommand()+" detected \n\t type="+getType()+"\n\t folderPath="+getCurrentFolder()+"\n\t newFolderName="+getNewFolderName());
			
			ActionContext.getContext().put("__richtexteditorCommand", getCommand());
			ActionContext.getContext().put("__richtexteditorType", getType());
			ActionContext.getContext().put("__richtexteditorFolderPath", getCurrentFolder());
			ActionContext.getContext().put("__richtexteditorServerPath", calculateServerPath(getServerPath(), getCurrentFolder(), getType()));
			
			CreateFolderResult createFolderResult = createFolder(getCurrentFolder(), getType(), getNewFolderName());
			
			ActionContext.getContext().put("__richtexteditorCreateFolder", createFolderResult);
			
			return CREATE_FOLDER;
		}
   在这段代码的第7行, 计算出的路径永远是父类里默认的 /webwork/richtexteditor/data/ 所以在它的子类 MyConnector.java ,我们重新赋值了一下:  
// TODO 非常重要的一句话,这样才能使用自定义的路径。
        ActionContext.getContext().put("__richtexteditorServerPath", calculateServerPath(get_serverPath(), getCurrentFolder(), getType()));

 

 

这样,就能保证我们刚才定义的 user_file 文件夹生效,文件通过 FCKEditor 上传完后,通过服务器端浏览,可以看到我们上传的图片,然后点确定就可以了。不过,如果你不是默认的 80 端口,那么可能要手动改一改,真是有点遗憾。最后一步,也是最重要的一步,配置我们刚才写的 MyConnector.java

 

<package name="richtexteditor-upload" extends="webwork-default"
		namespace="/webwork/richtexteditor/editor/filemanager/upload">
		<action name="uploader" class="com.leo.controller.MyConnector"
			method="upload">
			<result name="richtexteditorFileUpload" />
		</action>
	</package>

	<package name="richtexteditor-browse" extends="webwork-default"
		namespace="/webwork/richtexteditor/editor/filemanager/browser/default/connectors/jsp">
		<action name="connector" class="com.leo.controller.MyConnector"
			method="browse">
			<result name="getFolders" type="richtexteditorGetFolders" />
			<result name="getFoldersAndFiles"
				type="richtexteditorGetFoldersAndFiles" />
			<result name="createFolder"
				type="richtexteditorCreateFolder" />
			<result name="fileUpload" type="richtexteditorFileUpload" />
		</action>
	</package>

 

一切完成,直接在 JSP 里调用即可:
<ww:richtexteditor toolbarCanCollapse="true" width="700" label=""
					name="txt" value="可以正常上传了。" />

 

 

 

二 Struts2 + Dojo

 

Struts2 部分更简单了。虽然 Struts2 不直接支持 FCKeditor ,但直接 Dojo ,而且个人更喜欢这种简洁的风格,我用的是 Struts2.0.11 版本进行测试,使用时,只要配置两个地方

1. HTML<head /> 标签之间,加上

<s:head theme="ajax"/>

2. textarea 加上主题    

<s:textarea theme="ajax" />

 

就这么简单。

 

 

 

--------------------------------------------------------------------------------------

最近根据网上的文章,更新了一下这个版本。请下载webwork_fckeditor完美解决.rar

 

 

  • 描述: Struts2使用Dojo的richeditor
  • 大小: 53.3 KB
  • 描述: Webwork2使用Fckeditor上传
  • 大小: 60.7 KB
  • webwork_test.rar (22.1 KB)
  • 描述: Webwork修改好的测试程序,不过,Jar包要自己亲自导入,太大了,传不上来。
  • 下载次数: 153
分享到:
评论
3 楼 wu19880125 2008-10-11  
楼主,你好,我遇到了一个问题不知道你能不能 帮我解决一下,我用了sitemesh+struts2写的,按照你说的第二个方案,每次进入页面的时候textarea把当前页面的所有内容都加了进来,不知道我说清楚没有..
2 楼 the_Classic_p 2008-06-12  
感谢    
1 楼 zfting 2008-04-29  
姐姐!connector人家是写了得!
你的代码就
改了人家部分""的String!!
这也叫你写的??

相关推荐

    struts2与webwork2

    Struts2是在Struts和WebWork2的基础上发展而来的新一代框架,它不仅继承了WebWork2的许多优秀特性,如强大的拦截器机制、动态方法调用等,还吸收了Struts框架的广泛认可度和用户基础,形成了一个更加强大、灵活且...

    Struts2-Webwork2-DWR

    **Webwork2** 是 Struts2 的前身,它解决了 Struts1 在处理动态方法调用和类型安全等方面的问题。Webwork2 引入了动作和结果的概念,使模型和视图之间的交互更为清晰。它还支持OGNL(Object-Graph Navigation ...

    Struts2 WebWork的更新产品

    Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与Servlet API完全脱离开,所以Struts 2可以理解为WebWork的更新产品

    struts与webwork的jar包无冲突版 自定义标签无冲突

    "struts与webwork的jar合并,无冲突版"是一个已经解决了这个问题的定制版本,它将Struts和WebWork的jar包进行了适当的合并和调整,使得在同一个项目中可以安全地使用`s:select`这样的自定义标签,而不会引发解析错误...

    Struts 2 技术详解:基于WebWork核心的MVC开发与实践

    WebWork的这些特性被集成到Struts 2中,使得Struts 2成为了一个高效且易用的MVC框架。 **Struts 2的生命周期**: 1. 用户发起HTTP请求。 2. Struts 2 框架接收到请求,解析请求参数。 3. 拦截器链开始执行,按照...

    [Struts 2权威指南--基于WebWork核心的MVC开发(高清完整版) 1/12

    不用多说了,Struts 2权威指南--基于WebWork核心的MVC开发(高清完整版),解压出来有200多M,因为权限不怎么够,我一共分了12卷,是一本不可多得的好书。第一卷附目录: 第1章 Struts 2概述,第2章 Struts 2下的Hello...

    STRUTS和WEBWORK在VALIDATE的区别

    2. 错误处理:STRUTS通过ActionForm对象和跳转策略处理错误,WebWork则使用拦截器链进行错误处理,提供更灵活的控制流程。 3. 验证与业务逻辑的耦合度:STRUTS的验证通常与业务逻辑分离,WebWork允许将验证集成到...

    Struts2 WebWork 2.0 Tags API 中文文档 [CHM]

    Struts2 WebWork 2.0 Tags API 中文文档 [CHM] webwork提供了一套不依赖于显示层技术的标签库。这一章我们将概括性的描述每一个标签, 比如此标签支持的属性,标签的行为等等。 大多数的标签都可以用于所有的模板...

    struts1,struts2,webwork,线程安全问题

    综上所述,Struts1、Struts2和WebWork这三个框架都面临着线程安全问题,但在Struts2中这个问题得到了较好的解决。Struts2通过使用“prototype”作用域管理`Action`实例,有效地避免了线程安全问题。而对于Struts1和...

    struts2中文学习文档

    从给定的文件信息来看,标题“struts2中文学习文档”和描述“struts2的根本webwork2”表明这是一份关于Struts2框架的学习资料,特别强调了Struts2与WebWork2的关系。Struts2是Apache Struts的一个版本,它是一个用于...

    03解决struts2配置文件无提示问题

    Struts 2是Struts的下一代产品,是在 struts 和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构的差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理...

    struts2建立流程

    Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理...

    Struts2权威指南完整版

    而且WebWork不再推出新版本,因此,实际项目开发中原来使用Struts和WebWork都将转入使用Struts2框架.基于这种背景,Struts2将会在短时间内迅速成为MVC领域最流行的框架,将会比原有的Struts框架更流行,更强大.

    struts2开发入门以及webWork开发入门文档

    - `webwork2开发指南.pdf`则是针对WebWork框架的指导手册,帮助理解WebWork的设计原理和用法。 通过以上文档,你可以系统地学习Struts2和WebWork的基本概念、核心组件以及实际应用。在掌握这两个框架的基础上,...

    struts2对webwork的改进

    Struts2是对WebWork框架的重大升级和改进,它在保留WebWork强大特性的基础上,引入了更多优化和新特性,使得整个框架更加灵活且易于使用。以下将详细阐述Struts2对WebWork的改进点: 1. **配置文件的多样化**: 在...

    struts2+webwork+spring.rar

    Struts2、WebWork和Spring是Java Web开发中三个非常重要的框架,它们各自在不同的层面上解决了应用程序的架构问题。这个"struts2+webwork+spring.rar"压缩包文件很可能是提供了一个整合这三个框架的示例项目或者教程...

    struts2的教程,struts2整合了struts1+webwork.基于MVC的Framework

    struts2的教程,struts2整合了struts1+webwork.基于MVC的Framework struts2的教程,struts2整合了struts1+webwork.基于MVC的Framework

    Struts 2中文帮助文档

    Struts 2是Struts的下一代产品,是在 struts 和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构的差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理...

    Struts 2 began as WebWork.

    Struts 2的发展历程始于WebWork,一个由James Holmes在2003年创建的框架,旨在解决早期Struts框架的一些局限性。WebWork以其灵活的动作映射、强大的拦截器机制和对Ajax支持的增强而闻名。 WebWork的核心设计理念是...

    struts2 常用的五个jar包

    Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与Servlet API完全脱离开,所以Struts 2可以理解为WebWork的更新产品。因为Struts 2和Struts 1有着太大的变化,...

Global site tag (gtag.js) - Google Analytics