当前位置: 移动技术网 > IT编程>开发语言>Java > SpringBoot开发案例之打造私有云网盘的实现

SpringBoot开发案例之打造私有云网盘的实现

2019年07月19日  | 移动技术网IT编程  | 我要评论

三菱空调维修,海贼王之见证历史,我爱打折

前言

最近在做工作流的事情,正好有个需求,要添加一个附件上传的功能,曾找过不少上传插件,都不是特别满意。无意中发现一个很好用的开源web文件管理器插件 elfinder,功能比较完善,社区也很活跃,还方便二次开发。

环境搭建

软件 地址
springboot
elfinder https://studio-42.github.io/elfinder/

项目截图

周末抽时间做了一个简单的案例,希望对大家有所帮助,下面是简单的项目截图。

 

 

 

 

项目功能

在线新建目录、文件、附件上传、下载、预览、在线打包,图片在线裁剪、编辑,实现列表试图、图标视图等等一些列功能。

项目配置

项目在第三方插件进行二次开发,基于 springboot 注解配置实现。

application.properties 配置:

# 执行类,内部调用,实现前端相关功能
file-manager.command=com.itstyle.cloud.common.elfinder.command
file-manager.thumbnail.width=80
file-manager.volumes[0].node=
file-manager.volumes[0].source=filesystem
file-manager.volumes[0].alias=file
# 文件存放目录,可以自定义
file-manager.volumes[0].path=d:/cloudfile
file-manager.volumes[0]._default=true
file-manager.volumes[0].locale=
file-manager.volumes[0].constraint.locked=false
file-manager.volumes[0].constraint.readable=true
file-manager.volumes[0].constraint.writable=true

elfinderconfiguration 读取配置:

@component
@configurationproperties(prefix="file-manager") //接收application.properties中的file-manager下面的属性
public class elfinderconfiguration {

  private thumbnail thumbnail;

  private string command;

  private list<node> volumes;

  private long maxuploadsize = -1l;

  //省略部分代码
}

elfinderstoragefactory 初始化 基础bean:

@configuration
public class elfinderconfig {

  @autowired
  private elfinderconfiguration elfinderconfiguration;

  @bean(name = "commandfactory")
  public commandfactory getcommandfactory() {
    commandfactory commandfactory = new commandfactory();
    commandfactory.setclassnamepattern(elfinderconfiguration.getcommand()+".%scommand");
    return commandfactory;
  }

  @bean(name = "elfinderstoragefactory")
  public elfinderstoragefactory getelfinderstoragefactory() {
    defaultelfinderstoragefactory elfinderstoragefactory = new defaultelfinderstoragefactory();
    elfinderstoragefactory.setelfinderstorage(getelfinderstorage());
    return elfinderstoragefactory;
  }

  @bean(name = "elfinderstorage")
  public elfinderstorage getelfinderstorage() {
    defaultelfinderstorage defaultelfinderstorage = new defaultelfinderstorage();

    // creates thumbnail
    defaultthumbnailwidth defaultthumbnailwidth = new defaultthumbnailwidth();
    defaultthumbnailwidth.setthumbnailwidth(elfinderconfiguration.getthumbnail().getwidth().intvalue());

    // creates volumes, volumeids, volumelocale and volumesecurities
    character defaultvolumeid = 'a';
    list<node> elfinderconfigurationvolumes = elfinderconfiguration.getvolumes();
    list<volume> elfindervolumes = new arraylist<>(elfinderconfigurationvolumes.size());
    map<volume, string> elfindervolumeids = new hashmap<>(elfinderconfigurationvolumes.size());
    map<volume, locale> elfindervolumelocales = new hashmap<>(elfinderconfigurationvolumes.size());
    list<volumesecurity> elfindervolumesecurities = new arraylist<>();

    // creates volumes
    for (node elfinderconfigurationvolume : elfinderconfigurationvolumes) {

      final string alias = elfinderconfigurationvolume.getalias();
      final string path = elfinderconfigurationvolume.getpath();
      final string source = elfinderconfigurationvolume.getsource();
      final string locale = elfinderconfigurationvolume.getlocale();
      final boolean islocked = elfinderconfigurationvolume.getconstraint().islocked();
      final boolean isreadable = elfinderconfigurationvolume.getconstraint().isreadable();
      final boolean iswritable = elfinderconfigurationvolume.getconstraint().iswritable();

      // creates new volume
      volume volume = volumesources.of(source).newinstance(alias, path);

      elfindervolumes.add(volume);
      elfindervolumeids.put(volume, character.tostring(defaultvolumeid));
      elfindervolumelocales.put(volume, localeutils.tolocale(locale));

      // creates security constraint
      securityconstraint securityconstraint = new securityconstraint();
      securityconstraint.setlocked(islocked);
      securityconstraint.setreadable(isreadable);
      securityconstraint.setwritable(iswritable);

      // creates volume pattern and volume security
      final string volumepattern = character.tostring(defaultvolumeid) + elfinderconstants.elfinder_volume_sercurity_regex;
      elfindervolumesecurities.add(new defaultvolumesecurity(volumepattern, securityconstraint));

      // prepare next volumeid character
      defaultvolumeid++;
    }

    defaultelfinderstorage.setthumbnailwidth(defaultthumbnailwidth);
    defaultelfinderstorage.setvolumes(elfindervolumes);
    defaultelfinderstorage.setvolumeids(elfindervolumeids);
    defaultelfinderstorage.setvolumelocales(elfindervolumelocales);
    defaultelfinderstorage.setvolumesecurities(elfindervolumesecurities);
    return defaultelfinderstorage;
  }
}

clouddiskcontroller 控制层实现:

@controller
@requestmapping("elfinder/connector")
public class clouddiskcontroller {

  private static final logger logger = loggerfactory.getlogger(clouddiskcontroller.class);

  public static final string open_stream = "openstream";
  public static final string get_parameter = "getparameter";

  @resource(name = "commandfactory")
  private elfindercommandfactory elfindercommandfactory;

  @resource(name = "elfinderstoragefactory")
  private elfinderstoragefactory elfinderstoragefactory;

  @requestmapping
  public void connector(httpservletrequest request, final httpservletresponse response) throws ioexception {
    try {
      response.setcharacterencoding("utf-8");
      request = processmultipartcontent(request);
    } catch (exception e) {
      throw new ioexception(e.getmessage());
    }


    string cmd = request.getparameter(elfinderconstants.elfinder_parameter_command);
    elfindercommand elfindercommand = elfindercommandfactory.get(cmd);

    try {
      final httpservletrequest protectedrequest = request;
      elfindercommand.execute(new elfindercontext() {
        @override
        public elfinderstoragefactory getvolumesourcefactory() {
          return elfinderstoragefactory;
        }

        @override
        public httpservletrequest getrequest() {
          return protectedrequest;
        }

        @override
        public httpservletresponse getresponse() {
          return response;
        }
      });
    } catch (exception e) {
      logger.error("unknown error", e);
    }
  }
  //省略部分代码
}

最后,前端页面引入:

<div id="elfinder"></div>
<script type="text/javascript" charset="utf-8">
    window.onload = function() {
      elfinder.prototype.loadcss('/elfinder/jquery-ui-1.12.1.custom/jquery-ui.css');
      $('#elfinder').elfinder({
        url : '/elfinder/connector',
        lang: 'zh_cn',
        height : window.innerheight-20,
        commandsoptions: {
          edit: {
            editors : [
              {
                info:{
                  name:'编辑',
                  urlascontent: false
                },
                // ace editor
                // `mimes` is not set for support everything kind of text file
                load : function(textarea) {
                  var self = this,
                    dfrd = $.deferred(),
                    cdn = './elfinder/ace/',
                    init = function() {
                      if (typeof ace === 'undefined') {
                        console.log(cdn);
                        this.fm.loadscript([
                          cdn+'/ace.js',
                          cdn+'/ext-modelist.js',
                          cdn+'/ext-settings_menu.js',
                          cdn+'/ext-language_tools.js'
                        ], start);
                      } else {
                        start();
                      }
                    },
                    start = function() {
                      var editor, editorbase, mode,
                        ta = $(textarea),
                        tabase = ta.parent(),
                        dialog = tabase.parent(),
                        id = textarea.id + '_ace',
                        ext = self.file.name.replace(/^.+\.([^.]+)|(.+)$/, '$1$2').tolowercase(),
                        // mime/mode map
                        mimemode = {
                          'text/x-php'       : 'php',
                          'application/x-php'    : 'php',
                          'text/html'        : 'html',
                          'application/xhtml+xml'  : 'html',
                          'text/javascript'     : 'javascript',
                          'application/javascript' : 'javascript',
                          'text/css'        : 'css',
                          'text/x-c'        : 'c_cpp',
                          'text/x-csrc'       : 'c_cpp',
                          'text/x-chdr'       : 'c_cpp',
                          'text/x-c++'       : 'c_cpp',
                          'text/x-c++src'      : 'c_cpp',
                          'text/x-c++hdr'      : 'c_cpp',
                          'text/x-shellscript'   : 'sh',
                          'application/x-csh'    : 'sh',
                          'text/x-python'      : 'python',
                          'text/x-java'       : 'java',
                          'text/x-java-source'   : 'java',
                          'text/x-ruby'       : 'ruby',
                          'text/x-perl'       : 'perl',
                          'application/x-perl'   : 'perl',
                          'text/x-sql'       : 'sql',
                          'text/xml'        : 'xml',
                          'application/docbook+xml' : 'xml',
                          'application/xml'     : 'xml'
                        };

                      // set basepath of ace
                      ace.config.set('basepath', cdn);

                      // set base height
                      tabase.height(tabase.height());

                      // detect mode
                      mode = ace.require('ace/ext/modelist').getmodeforpath('/' + self.file.name).name;
                      if (mode === 'text') {
                        if (mimemode[self.file.mime]) {
                          mode = mimemode[self.file.mime];
                        }
                      }

                      // show mime:mode in title bar
                      tabase.prev().children('.elfinder-dialog-title').append(' (' + self.file.mime + ' : ' + mode.split(/[\/\\]/).pop() + ')');
                      // textarea button and setting button
                      $('<div class="ui-dialog-buttonset"/>').css('float', 'left')
                        .append(
                          $('<button>文本框</button>')
                            .button()
                            .on('click', function(){
                              if (ta.data('ace')) {
                                ta.removedata('ace');
                                editorbase.hide();
                                ta.val(editor.session.getvalue()).show().focus();
                                $(this).text('编辑器');
                              } else {
                                ta.data('ace', true);
                                editorbase.show();
                                editor.setvalue(ta.hide().val(), -1);
                                editor.focus();
                                $(this).text('文本框');
                              }
                            })
                        )
                        .append(
                          $('<button>ace editor setting</button>')
                            .button({
                              icons: {
                                primary: 'ui-icon-gear',
                                secondary: 'ui-icon-triangle-1-e'
                              },
                              text: false
                            })
                            .on('click', function(){
                              editor.showsettingsmenu();
                            })
                        )
                        .prependto(tabase.next());

                      // base node of ace editor
                      editorbase = $('<div id="'+id+'" style="width:100%; height:100%;"/>').text(ta.val()).insertbefore(ta.hide());

                      // ace editor configure
                      ta.data('ace', true);
                      editor = ace.edit(id);
                      ace.require('ace/ext/language_tools');
                      ace.require('ace/ext/settings_menu').init(editor);
                      editor.$blockscrolling = infinity;
                      editor.setoptions({
                        theme: 'ace/theme/dawn',
                        mode: 'ace/mode/' + mode,
                        fontsize: '14px',
                        wrap: true,
                        enablebasicautocompletion: true,
                        enablesnippets: true,
                        enableliveautocompletion: true
                      });
                      editor.commands.addcommand({
                        name : "savefile",
                        bindkey: {
                          win : 'ctrl-s',
                          mac : 'command-s'
                        },
                        exec: function(editor) {
                          self.dosave();
                        }
                      });
                      editor.commands.addcommand({
                        name : "closeeditor",
                        bindkey: {
                          win : 'ctrl-w|ctrl-q',
                          mac : 'command-w|command-q'
                        },
                        exec: function(editor) {
                          self.docancel();
                        }
                      });

                      editor.resize();

                      dfrd.resolve(editor);
                    };

                  // init & start
                  init();

                  return dfrd;
                },
                close : function(textarea, instance) {
                  if (instance) {
                    instance.destroy();
                    $(textarea).show();
                  }
                },
                save : function(textarea, instance) {
                  instance && $(textarea).data('ace') && (textarea.value = instance.session.getvalue());
                },
                focus : function(textarea, instance) {
                  instance && $(textarea).data('ace') && instance.focus();
                },
                resize : function(textarea, instance, e, data) {
                  instance && instance.resize();
                }
              }
            ]
          },
          quicklook : {
            // to enable preview with google docs viewer
            googledocsmimes : ['application/pdf', 'image/tiff', 'application/vnd.ms-office', 'application/msword', 'application/vnd.ms-word', 'application/vnd.ms-excel', 'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
          }
        }
      });
    };
  </script>

小结

总体来说个人使用还是非常不错的,当然对于一些成熟的网盘系统还是有一些差距。

源码:https://gitee.com/52itstyle/spring-boot-clouddisk

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网