Java ckfinder2.6.2实现文件上传破解,获取文件信息添加到数据库中

11 篇文章 0 订阅

Java ckfinder2.6.2实现文件上传破解,获取文件信息添加到数据库中

1.首先下载java的ckfinder上传组件最新的是2.6.3,我这里使用的是2.6.2

官网地址:https://cksource.com/ckfinder
但是官网下载的源码,虽然免费,但是会有讨厌的版权信息显示,这里我已经去除了,唯一不足之处就是ckfinder的中文文件夹和中文文件上传会有异常,这是因为,我们的浏览器会自动对中文字符进行url编码,并且根据页面编码格式,所以我们处理这种情况可以使用js提供编码函数,自己encodeurl等等实现自定义编码,但是由于ckfinder的js看不太懂,所以就没有去改,有心的同学可以自己改改看

这里写图片描述

2,配置ckfinder

下载解压后,将,ckfinder文件夹直接拖到web项目的webcontent文件夹xia并将config.xml拖到web-inf下
具体配置我就不讲了
网上多得是,也可参考我的之前写的
http://blog.csdn.net/do_bset_yourself/article/details/51568576?locationNum=1&fps=1

2.1配置里我要将一下,权限控制这块

如果直接配置成这样会,表示任何和都是上传和删除文件

<accessControl>
            <role>*</role>
            <resourceType>*</resourceType>
            <folder>/</folder>
            <folderView>true</folderView>
            <folderCreate>true</folderCreate>
            <folderRename>true</folderRename>
            <folderDelete>true</folderDelete>
            <fileView>true</fileView>
            <fileUpload>true</fileUpload>
            <fileRename>true</fileRename>
            <fileDelete>true</fileDelete>
        </accessControl>

你可以配置为,:

<accessControl>
            <role>admin</role>
            <resourceType>*</resourceType>
            <folder>/</folder>
            <folderView>true</folderView>
            <folderCreate>true</folderCreate>
            <folderRename>true</folderRename>
            <folderDelete>true</folderDelete>
            <fileView>true</fileView>
            <fileUpload>true</fileUpload>
            <fileRename>true</fileRename>
            <fileDelete>true</fileDelete>
        </accessControl>
        <accessControl>
            <role>common</role>
            <resourceType>*</resourceType>
            <folder>/</folder>
            <folderView>true</folderView>
            <folderCreate>false</folderCreate>
            <folderRename>false</folderRename>
            <folderDelete>false</folderDelete>
            <fileView>true</fileView>
            <fileUpload>true</fileUpload>
            <fileRename>true</fileRename>
            <fileDelete>true</fileDelete>
        </accessControl>

只要在session中配置用户分类即可,变量key为这个(CKFinder_UserRole),当然你可以修改下面这个

    <userRoleSessionVar>CKFinder_UserRole</userRoleSessionVar>

工欲善其事必先利其器,所以我们先来分析一下:

3.文件上传分析,和实现:

上传url:
这里写图片描述
参数:
这里写图片描述
看到这里我们会发现,ckfinder的上传参数中根本没有包含文件名称,只包含文件路径和ckfinder自定义的命令观察通过观察源码得知,ckfinder自定义了好多关于文件的命令,具体的大家可以自行探索,这里由于篇幅原因不再赘述

但是我们通过观察返回值,返现response返回一系列字符串,返回文件名称,
这里写图片描述

到了这里我们就可以想到怎么破解了,
只要我们能得到返回response返回的内容不就好了

说干就干:

通过观察源码,我们发现ckfinder所有的请求都会交给com.ckfinder.connector.ConnectorServlet,这个类来处理,所以我们只要继承这个类,并覆写里面的方法就能是该功能,这只是一个servlet,具体的我们只要复写servlet的doget和dopost方法即可,具体来时只是dopost方法,因为文件上传都是post方法

这个并不是难点,难点是,我们如何获取response返回的内容尼?
这时我想到了动态代理的方法,但是这里只是一个简单的功能实现并不需要折磨做,静态代理即可,所以我们只需要实现自己的response实现类,然后在自己的ckfinder处理类中替换response即可
当然大家如果有更简单的方法,欢迎留言告知!!,这个方法的好处就是不用修改源码

想到了这个,我们就可以开始写代码,
但是由于httpservletresponse的方法过多,所以我们可以自己先写一个适配器,然后自己再去基层这个适配器,然后再实现httpservletresponse接口:
httpservletresponse适配器代码如下:

package com.office.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Locale;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
/**
 * @author 都市桃源    (只要路对,就不怕路远)
 * @since 2016年11月2日
 * @!TODO  response 适配器类
 *  项目名称:MyOffice
 */
public class ResponseAdapter  implements HttpServletResponse{
        private HttpServletResponse response ;
        public ResponseAdapter(HttpServletResponse response) {
            super();
            this.response = response;
        }


        @Override
        public void flushBuffer() throws IOException {
            response.flushBuffer();
        }

        @Override
        public int getBufferSize() {
            return  response.getBufferSize();

        }

        @Override
        public String getCharacterEncoding() {
            return response.getCharacterEncoding();
        }

        @Override
        public String getContentType() {
            return response.getContentType();
        }

        @Override
        public Locale getLocale() {
            return response.getLocale();
        }

        @Override
        public ServletOutputStream getOutputStream() throws IOException {//这个是我们唯一要覆写的方法
            return response.getOutputStream();
        }

        @Override
        public PrintWriter getWriter() throws IOException {
            return response.getWriter();
        }

        @Override
        public boolean isCommitted() {
            return response.isCommitted();
        }

        @Override
        public void reset() {
            response.reset();
        }

        @Override
        public void resetBuffer() {
            response.resetBuffer();
        }

        @Override
        public void setBufferSize(int size) {
            response.setBufferSize(size);       
        }

        @Override
        public void setCharacterEncoding(String en) {
            response.setCharacterEncoding(en);
        }

        @Override
        public void setContentLength(int arg0) {
            response.setContentLength(arg0);
        }

        @Override
        public void setContentType(String arg0) {
            response.setContentType(arg0);
        }

        @Override
        public void setLocale(Locale arg0) {
            response.setLocale(arg0);
        }

        @Override
        public void addCookie(Cookie arg0) {
            response.addCookie(arg0);
        }

        @Override
        public void addDateHeader(String arg0, long arg1) {
            response.addDateHeader(arg0, arg1);
        }

        @Override
        public void addHeader(String arg0, String arg1) {
            response.addHeader(arg0, arg1);
        }

        @Override
        public void addIntHeader(String arg0, int arg1) {
            response.addIntHeader(arg0, arg1);
        }

        @Override
        public boolean containsHeader(String arg0) {
            return response.containsHeader(arg0);
        }

        @Override
        public String encodeRedirectURL(String arg0) {
            return response.encodeRedirectURL(arg0);
        }

        @Override
        public String encodeRedirectUrl(String arg0) {
            return response.encodeRedirectUrl(arg0);
        }

        @Override
        public String encodeURL(String arg0) {
            return response.encodeURL(arg0);
        }

        @Override
        public String encodeUrl(String arg0) {
            return response.encodeUrl(arg0);
        }

        @Override
        public String getHeader(String arg0) {
            return response.getHeader(arg0);
        }

        @Override
        public Collection<String> getHeaderNames() {
            return response.getHeaderNames();
        }

        @Override
        public Collection<String> getHeaders(String arg0) {
            return response.getHeaders(arg0);
        }

        @Override
        public int getStatus() {
            return response.getStatus();
        }

        @Override
        public void sendError(int arg0) throws IOException {
            response.sendError(arg0);
        }

        @Override
        public void sendError(int arg0, String arg1) throws IOException {
            response.sendError(arg0, arg1);
        }

        @Override
        public void sendRedirect(String arg0) throws IOException {
         response.sendRedirect(arg0);

        }

        @Override
        public void setDateHeader(String arg0, long arg1) {
            response.setDateHeader(arg0, arg1);     
        }

        @Override
        public void setHeader(String arg0, String arg1) {
            response.setHeader(arg0, arg1);
        }

        @Override
        public void setIntHeader(String arg0, int arg1) {
            response.setIntHeader(arg0, arg1);
        }

        @Override
        public void setStatus(int arg0) {
            response.setStatus(arg0);
        }
        @Override
        public void setStatus(int arg0, String arg1) {
            response.setStatus(arg0,arg1);

        }

}

其实这类写不写都没关系,但是如果我们以后要做更多的扩展,就不必每次都覆写httpservletresponse这个接口了

通过
静态代理类

package com.office.util;

import java.io.IOException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;


/**
 * @author 都市桃源    (只要路对,就不怕路远)
 * @since 2016年11月2日
 * @!TODO 自定义httpservletResponse,实现所有方法
 *  项目名称:MyOffice
 */
public class HttpServletResponseProxy extends ResponseAdapter implements HttpServletResponse{
    private OutputStreamProxy pwxy;
    //自己的httpservletOutputStream类
    public HttpServletResponseProxy(HttpServletResponse response) {
        super(response);
    }

    public OutputStreamProxy getPwxy() {
        return pwxy;
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        pwxy=new OutputStreamProxy(super.getOutputStream());
        return pwxy;
    }

}

**追踪源码发现ckfindersevlet
向页面输出内容使用的是outputStream形式,而不是Wrtter方式,所以我们只要复写getOutputStem**
方法即可,返回我们自己实现的httpservletOutputStream实现类
具体代码

package com.office.util;

import java.io.IOException;
import javax.servlet.ServletOutputStream;




public class OutputStreamProxy extends ServletOutputStream{
    private ServletOutputStream out;
    public OutputStreamProxy(ServletOutputStream out) {
        super();
        this.out = out;
    }


    @Override
    public void write(int b) throws IOException {
        ResponseContentUtil.getBuf().append((char)b);
        //将response输出的内容保存在response缓存区中
        out.write(b);   
    }



}

缓冲区实现编写:

package com.office.util;

/**
 * @author 都市桃源    (只要路对,就不怕路远)
 * @since 2016年11月2日
 * @!TODO 获取response 内容
 *  项目名称:MyOffice
 */
public class ResponseContentUtil {
    static ThreadLocal<StringBuffer> bufs=new ThreadLocal<StringBuffer>();

    public static StringBuffer getBuf(){
        StringBuffer buf=bufs.get();
        if(buf==null){
            buf= new StringBuffer();
            bufs.set(buf);
        }
        return buf;
    }
    public static void clear(){//清空缓存
        bufs.set(new StringBuffer(""));
    }
}

**重点:这里必须使用threadlocal实现,
因为我们必须保证在整个请求中操作的都是个缓存区**

文件信息获取实现保存到数据中:


package com.office.filter;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.ckfinder.connector.ConnectorServlet;
import com.office.biz.FileInfoBiz;
import com.office.entity.Fileinfo;
import com.office.util.HttpServletResponseProxy;
import com.office.util.ResponseContentUtil;

public class MyConnectorServlet extends ConnectorServlet {

    @Override
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
            //获取上传命令
           String command=request.getParameter("command");
           if(command==null){
            super.doPost(request, response);
             return;
           }
           if(command.equals("FileUpload")){
               //每次上传前清空缓存
               ResponseContentUtil.clear();
                    HttpServletResponse myResponse=new HttpServletResponseProxy(response); 
                    super.doPost(request, myResponse);
                    StringBuffer buf=ResponseContentUtil.getBuf();//获取response返回内容
                    //获取文件名
                    String fileName=new String(buf.substring(0,buf.indexOf("|")));
                       //获取当前目录
                     String currentFolder=request.getParameter("currentFolder");

                     Fileinfo info=new Fileinfo();
                     info.setFilename(fileName);
                     info.setRemark("office第二组办公系统文件");
                     info.setFilepath(currentFolder+fileName);
                        Timestamp time=new Timestamp(System.currentTimeMillis());
                     info.setCreatedate(time);
                     info.setFiletypeinfo(null);
                     ServletContext sc = request.getSession().getServletContext();
                     //获取spring容器
                     ApplicationContext app=WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
                     FileInfoBiz infobiz=app.getBean(FileInfoBiz.class);
                     //添加到数据库
                     infobiz.add(info);
                    System.out.println("上传文件路径---------"+currentFolder+fileName);
                }else if(command.equals("DeleteFiles")){
                    List<Fileinfo> files=new ArrayList<Fileinfo>();
                    super.doPost(request, response);
                    int i=0;
                    String paramName = "files[" + i + "][name]";
                    while (request.getParameter(paramName) != null) {
                        //封装文件属性
                        String user=request.getParameter("user");
                        String infoName=request.getParameter(paramName);
                        String type=request.getParameter("files[" + i + "][type]");
                        String folder=request.getParameter("files[" + i + "][folder]");
                        //封装实体
                        Fileinfo info=new Fileinfo();
                        info.setFilename(infoName);
                        Timestamp time=new Timestamp(System.currentTimeMillis());
                        info.setCreatedate(time);
                        info.setFileowner(user);
                        info.setFilepath(folder+infoName);
                        info.setRemark("office第二组办公系统文件");
                        info.setFiletypeinfo(null);
                        files.add(info);
                        paramName = "files[" + (++i) + "][name]";
                        System.out.println("删除路径"+folder+infoName);
                    }
                     ServletContext sc = request.getSession().getServletContext();
                     //获取spring容器
                     ApplicationContext app=WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
                     FileInfoBiz infobiz=app.getBean(FileInfoBiz.class);
                     //根据属性批量删除文件
                     try {
                        infobiz.deleteBatchByProperty(files, "filename");
                    } catch (Exception e) {
                        System.out.println("删除异常");
                    }
                }else if(command.equals("RenameFile")){
                    super.doPost(request, response);
                    String fileName=request.getParameter("fileName");
                    String newFileName=request.getParameter("newFileName");
                     ServletContext sc = request.getSession().getServletContext();
                     //获取spring容器
                     ApplicationContext app=WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
                     FileInfoBiz infobiz=app.getBean(FileInfoBiz.class);
                     infobiz.updateFileName(fileName,newFileName);

                }else{
                    super.doPost(request, response);
                }


    }

}

重点:

文件重命名,移动,删除分析与文件上传一致,所以
大家可以
分析分析,也是很简单。

最后,实现与struts2整合注意事项:

注意1:

为了使struts2的过滤器和ckfinder的servlet过滤路径
不冲突:两种解决方案:
方案1:
修改struts2的过滤路径为.action或者.do

方案二:
自己覆写struts2过滤的过滤方法,不过滤ckfinder的路径:

package com.office.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.dispatcher.Dispatcher;
import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter;

public class MyStrutsFilter extends StrutsPrepareAndExecuteFilter{

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest) req;
        String url=request.getRequestURI();
        if(url==null){
            super.doFilter(req, resp, chain);
            return;
        }
        if(url.indexOf("/ckfinder/core/connector/")>=0){//放行次路径
            chain.doFilter(req, resp);
        }else{
            super.doFilter(req, resp, chain);
        }

    }

    @Override
    protected void postInit(Dispatcher dispatcher, FilterConfig filterConfig) {
        // TODO Auto-generated method stub
        super.postInit(dispatcher, filterConfig);
    }

}

我没有贴源码的习惯,如果真的看不懂可以留言问我要,不过大部分问题都提到了,如果还有没提到的,还望见谅
对了破解的ckfinder.js我会上传的csdn上欢迎大家下载
地址:

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
CKFinder是一个用于文件管理的Web应用程序,它可以方便地集成到Linux系统。下面是安装CKFinder的步骤: 1. 首先,确保你的Linux系统已经安装了Apache或Nginx等Web服务器,并且PHP版本为5.6或更高。 2. 下载CKFinder的安装包。你可以从CKFinder的官方网站(https://ckeditor.com/ckfinder/)上下载最新版本的安装包。 3. 解压安装包。使用以下命令解压下载的安装包: ``` tar -zxvf ckfinder_3.x.x.tar.gz ``` 4. 将解压后的CKFinder文件夹复制到你的Web服务器的根目录下。例如,如果你使用的是Apache服务器,将CKFinder文件夹复制到`/var/www/html/`目录下。 5. 配置CKFinder。进入CKFinder文件夹,将`config.php.sample`文件重命名为`config.php`: ``` cd ckfinder mv config.php.sample config.php ``` 6. 打开`config.php`文件,并根据你的需求进行配置。你需要设置一些基本的参数,如文件上传路径、访问控制等。 7. 配置Web服务器。如果你使用的是Apache服务器,需要在Apache的配置文件添加以下内容: ``` Alias /ckfinder "/var/www/html/ckfinder" <Directory "/var/www/html/ckfinder"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> ``` 8. 重启Web服务器,使配置生效。 9. 访问CKFinder。在浏览器输入CKFinder的URL,例如`http://localhost/ckfinder/`,即可访问CKFinder文件管理界面。 希望以上步骤对你有帮助!如果你还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值