[struts]在线编辑器的使用选择

问题背景:

使用ssh框架开发一个站点,需要使用在线编辑器,以往没用框架直接jsp时使用的是fckeditor编辑器。

这次结合struts框架开发,开始时选择了tinyMCE(扩展性不错,博客园用的也是这个),但项目进行到一半时候发现需要编辑器能够实现上传文件功能,以便

于方便传含图片的新闻及加附件。但是tinymce不支持,需要自己扩展。时间原因,只好重新选择其他编辑器。

什么kindeditor、ueditor看了看,最后选择了kindeditor-v4.1.6。问题来了

问题描述:

1、tinyMCE不支持直接上传文件,需扩展。有时间再整http://www.cnblogs.com/ryanding/archive/2010/11/02/1866694.html

2、kindeditor支持上传文件。但由于struts的过滤器将HttpServletRequest对象包装成MultiPartRequestWrapper,如果直接用示例文件upload_json.jsp。

关键代码:

FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("UTF-8");
List items = upload.parseRequest(request);
Iterator itr = items.iterator();
while (itr.hasNext()) {
    FileItem item = (FileItem) itr.next();
    String fileName = item.getName();
    long fileSize = item.getSize();
    if (!item.isFormField()) {
        //检查文件大小
        if(item.getSize() > maxSize){
            out.println(getError("上传文件大小超过限制。"));
            return;
        }
        //检查扩展名
        String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){
            out.println(getError("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。"));
            return;
        }

        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt;
        try{
            File uploadedFile = new File(savePath, newFileName);
            item.write(uploadedFile);
        }catch(Exception e){
            out.println(getError("上传文件失败。"));
            return;
        }

        JSONObject obj = new JSONObject();
        obj.put("error", 0);
        System.out.println(" url: "+saveUrl + newFileName);
        obj.put("url", saveUrl + newFileName);
        out.println(obj.toJSONString());
    }
}

会发现 upload.parseRequest(request);取不到值。

问题分析:

     kindeditor 在java环境中用到了 commons-fileupload-1.2.1.jar 组件。 在Common- FileUpload中,它把从客户端提交过来的表单封装成一个个FileItem对象,这也是它实现文件上传功能 的核心类。另一个很重要的类就是FileUploadBase,他的功能就是解析请求(request),如进行上传文 件大小验证,请求类型验证(文件上传的enctype要设置成multipart/form-data)等。我们经常用到它 的子类ServletFileUpload。在FileUploadBase解析 request的过程中会将文件保存到内存,如果文件大 小大于我们设置的缓存的大小,它将把文件的其他内容保存到一个临时目录,当我们对FileItem 对象实 现正真上传时会从内存区或临时目录将文件保存到正真的上传目录。

解决方法:

1、指定struts的filter过滤的url类型,防止其对访问jsp页面的请求request进行封装。(已验证)

<url-pattern>*.action</url-pattern>或者<url-pattern>*.do</url-pattern>

2、写个Servlet来代替upload_json.jsp的功能。upload_json.jsp里面的代码大部分都可以复制到Servlet中, upload_json.jsp中的out.prinln返回值用 resp.getWriter().println()代替就行。(未验证)

3、修改upload_json.jsp.修改获得request对象的方法。详见http://www.kaifajie.cn/struts/9086.html

//Struts2 请求 包装过滤器
MultiPartRequestWrapper wrapper = (MultiPartRequestWrapper) request;
//获得上传的文件名
String fileName = wrapper.getFileNames("imgFile")[0];//imgFile,imgFile,imgFile
//获得文件过滤器
File file = wrapper.getFiles("imgFile")[0];(未验证、理论可行)

4、重写action使其可以获得File对象。(已验证)

看完上面几种方法,不知道大家发现没有,其实kindeditor上传文件的方法和以前没什么不一样。唯一不一样的是我们在不了解起上传页面情况下不知道其表单的file域的name属性。通过调试,我们可以发现file对象的实际名称。一般如果file域的name属性为“file”,则对应处理的action类这么写:

public class CommonAction extends ActionSupport{
   
    private static final long serialVersionUID = 1L;
    //所属类型,按模块划分
    private String type;
    //上传文件
    private File file;
    //上传文件名字
    private String fileFileName;
    //返回地址列表(存入数据库)
    private String fileURL;

kindeditor的name属性为imgFile,因此将名字改过来,就可以了。

posted @ 2013-04-11 20:41  wanpp590  阅读(352)  评论(0编辑  收藏  举报