Ueditor自定义图片保存路径

版权声明:本文为博主原创文章,未经博主允许不得转载 https://blog.csdn.net/liujun03/article/details/82345163

此博客承接上篇博客:https://blog.csdn.net/liujun03/article/details/82225611

再使用Ueditor进行图片上传或者多图上传的时候,它的图片默认会保存在项目的根路径拼接上config.json里的imagePathFormat目录下,这是很不合理的,因为你一旦重新构建项目之前的资源就都没了。

目录如:(D:\git\person\spring-ueditor\current\ueditor\jsp\upload\image\20180831\11.png)

我们先走一下图片保存的逻辑,明白了逻辑,才好对源码进行修改:

首先:我们得知道在ueditor.config.js中是定义了一个服务器统一访问接口的,Ueditor编辑器所有的对服务器的访问都是从这个接口开始的,只是传的参数不同而已。访问接口只是实例化ActionEnter对象,并执行其exec方法。我们看一下这个exec()方法,其中是调用了invoke()方法的:

public String exec () {

        String callbackName = this.request.getParameter("callback");

        if ( callbackName != null ) {

            if ( !validCallbackName( callbackName ) ) {
                return new BaseState( false, AppInfo.ILLEGAL ).toJSONString();
            }

            return callbackName+"("+this.invoke()+");";

        } else {
            return this.invoke();
        }

    }

我们的访问并没有发出回调请求,故是直接执行: return this.invoke(); 代码。再看一下这个invoke()方法:

int actionCode = ActionMap.getType( this.actionType );
switch ( actionCode ) {

            case ActionMap.CONFIG:
                return this.configManager.getAllConfig().toString();

            case ActionMap.UPLOAD_IMAGE:
            case ActionMap.UPLOAD_SCRAWL:
            case ActionMap.UPLOAD_VIDEO:
            case ActionMap.UPLOAD_FILE:
                conf = this.configManager.getConfig( actionCode );
                state = new Uploader( request, conf ).doExec();
                break;

            case ActionMap.CATCH_IMAGE:
                conf = configManager.getConfig( actionCode );
                String[] list = this.request.getParameterValues( (String)conf.get( "fieldName" ) );
                state = new ImageHunter( conf ).capture( list );
                break;

            case ActionMap.LIST_IMAGE:
            case ActionMap.LIST_FILE:
                conf = configManager.getConfig( actionCode );
                int start = this.getStartIndex();
                state = new FileManager( conf ).listFile( start );
                break;

        }

我这里只截取了两段代码,具体的可以自己看源码。第一段代码中的this.actionType 是在实例化ActionEnter时就赋值好了,在上传图片时它的值是config.json中的imageActionName(uploadimage),可以看一下ActionMap这个类,里面对各个action都赋予不同的数值构造出map对象。uploadimage对应ActionMap.UPLOAD_IMAGE。

所以在第二段代码中匹配到了这里:

            case ActionMap.UPLOAD_IMAGE:
            case ActionMap.UPLOAD_SCRAWL:
            case ActionMap.UPLOAD_VIDEO:
            case ActionMap.UPLOAD_FILE:
                conf = this.configManager.getConfig( actionCode );
                state = new Uploader( request, conf ).doExec();
                break;

这里首先是得到在不同的actionCode中得到不同的conf对象,我们这里是上传图片,所以匹配的代码是:

case ActionMap.UPLOAD_IMAGE:
                conf.put( "isBase64", "false" );
                conf.put( "maxSize", this.jsonConfig.getLong( "imageMaxSize" ) );
                conf.put( "allowFiles", this.getArray( "imageAllowFiles" ) );
                conf.put( "fieldName", this.jsonConfig.getString( "imageFieldName" ) );
                savePath = this.jsonConfig.getString( "imagePathFormat" );
                //physicalPath = this.jsonConfig.getString( "physicalPath" );
                break;

然后实例化了个Uploader对象,然后执行其doExec()方法:

public final State doExec() {
        String filedName = (String) this.conf.get("fieldName");
        State state = null;

        if ("true".equals(this.conf.get("isBase64"))) {
            state = Base64Uploader.save(this.request.getParameter(filedName),
                    this.conf);
        } else {
            state = BinaryUploader.save(this.request, this.conf);
        }

        return state;
    }

在上传图片时,指定了isBase64 是false,所以直接执行BinaryUploader 的save方法,看一下save()方法:

            String savePath = (String) conf.get("savePath");
            String originFileName = fileStream.getName();
            String suffix = FileType.getSuffixByFilename(originFileName);

            originFileName = originFileName.substring(0,
                    originFileName.length() - suffix.length());
            savePath = savePath + suffix;

            long maxSize = ((Long) conf.get("maxSize")).longValue();

            if (!validType(suffix, (String[]) conf.get("allowFiles"))) {
                return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);
            }

            savePath = PathFormat.parse(savePath, originFileName);

            String physicalPath = (String) conf.get("rootPath") + savePath;
//          String physicalPath = (String) conf.get("physicalPath") + savePath;

            InputStream is = fileStream.openStream();
            State storageState = StorageManager.saveFileByInputStream(is,
                    physicalPath, maxSize);
            is.close();

一步一步走下来,可以知道:String savePath = (String) conf.get(“savePath”); savePath就是config.json中的imagePathFormat的值,savePath = PathFormat.parse(savePath, originFileName); 就是将其中的正则表达式替换了。接下来String physicalPath = (String) conf.get(“rootPath”) + savePath; 这个就是最重要的了,这里拼接出来了图片在磁盘里的存储路径physicalPath ,就是刚开始说的项目的根路径拼接上config.json里的imagePathFormat目录。下面的代码就是将图片存到physicalPath下了。

图片的保存逻辑就是上面那些,所以接下来的改造就简单了。

虽然项目是在哪台服务器上,图片依然要保存在那台服务器上,但是我们可以专门建立一个存放图片的文件夹,而不是放在项目的某个目录下。

首先:在config.json中定义一个路径,就是你要存放图片的固定路径:

"physicalPath": "/data/upload/spring-ueditor/image",
"imageActionName": "uploadimage", /* 执行上传图片的action名称 */

这个physicalPath就是我定义的路径了。这个在实例化ActionEnter时就会从配置文件中读取出来。

上面有说到:

case ActionMap.UPLOAD_IMAGE:
            case ActionMap.UPLOAD_SCRAWL:
            case ActionMap.UPLOAD_VIDEO:
            case ActionMap.UPLOAD_FILE:
                conf = this.configManager.getConfig( actionCode );
                state = new Uploader( request, conf ).doExec();
                break;

this.configManager.getConfig( actionCode );是在配置管理器中根据不同的请求从json文件中读取不同的值出来,所以需要改造一下这个getConfig()方法:

case ActionMap.UPLOAD_IMAGE:
                conf.put( "isBase64", "false" );
                conf.put( "maxSize", this.jsonConfig.getLong( "imageMaxSize" ) );
                conf.put( "allowFiles", this.getArray( "imageAllowFiles" ) );
                conf.put( "fieldName", this.jsonConfig.getString( "imageFieldName" ) );
                savePath = this.jsonConfig.getString( "imagePathFormat" );
                physicalPath = this.jsonConfig.getString( "physicalPath" );
                break;

在这里加了一行:physicalPath = this.jsonConfig.getString( “physicalPath” );

之后将之放入conf这个map中去:conf.put( “physicalPath”, physicalPath );

最终是需要在拼接图片在磁盘里的存储路径physicalPath时:

String physicalPath = (String) conf.get(“rootPath”) + savePath

将(String) conf.get(“rootPath”) 这个项目的根路径 替换为conf.get(“physicalPath”)。

最后总结一下我对源码做出的改变:

1.在config.json第4行加上

"physicalPath": "/data/upload/spring-ueditor/image",

2.将config.json中imagePathFormat修改为:

"imagePathFormat": "/{time}{rand:6}",

这样是为了时间戳+随机6位数为图片名,图片直接存放在physicalPath下 ,方便服务器中nginx做代理

3.在ConfigManager.java第86行加上:

String physicalPath = null;

4.在ConfigManager.java第103行加上:

physicalPath = this.jsonConfig.getString( "physicalPath" );

5.在ConfigManager.java第145行加上:

conf.put( "physicalPath", physicalPath );

6.将BinaryUploader.java第72行改为:

String physicalPath = (String) conf.get("physicalPath") + savePath;

7.将config.json中imageUrlPrefix修改为自己制定的域名或者ip

"imageUrlPrefix": "http://devws.image.cn", /* 图片访问路径前缀 */

之后将你配置的域名或者ip指向服务器的physicalPath路径

这样就行了。

猜你喜欢

转载自blog.csdn.net/liujun03/article/details/82345163
今日推荐