Springmvc+kindeditor+Nginx+tomcat实现附件附件分离处理

一. 原理

kindeditor复制上传图片--》web控制器MultipartFile获取到图片--》CloseableHttpClient方式将附件提交至附件处理远程服务器--》远程服务器Tomcat(也可以使用nginx)部署web附件处理后台--》远程附件服务器使用nginx映射静态文件提供附件的下载于查看

 

二. kindeditor复制上传图片

KindEditor.ready(function(K) {
    var editor1 = K.create('textarea[name="content1"]', {
        cssPath : '<%=request.getContextPath()%>/kindeditor/plugins/code/prettify.css',
        uploadJson : '<%=request.getContextPath()%>/files/upload.do',
        allowFileManager : true,
        afterCreate : function() {
            var self = this;
            K.ctrl(document, 13, function() {
                self.sync();
                document.forms['example'].submit();
            });
            K.ctrl(self.edit.doc, 13, function() {
                self.sync();
                document.forms['example'].submit();
            });
        }
    });
    prettyPrint();
});

三. web控制器MultipartFile获取到图片,通过CloseableHttpClient方式将附件提交至附件处理远程服务器

配置内容:

常量:

/*
 * 文件存储服务器地址
 */
public static String FILE_SERVER_URL="";
/*
 * 文件下载查看地址
 */
public static String FILE_VIEW_URL="";
/*
 * 文件服务器toekn
 */
public static String FILE_SERVER_TOKEN="";

控制器:

@ResponseBody
@RequestMapping(value = "/upload", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
public void upload(@RequestParam(value = "imgFile", required = false) MultipartFile file,HttpServletRequest request,HttpServletResponse response) throws Exception {
注:kindeditor文本编辑器附件上传id都是imgFile,复制图片隐藏的附件上传id也是
   JSONObject succMap = new JSONObject();
   if(file.getSize()==0){
      succMap.put("error", 1);
      succMap.put("msg", "附件内容为空!");
   }
   if (file!=null&&!file.isEmpty()) {
      String suffix=file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
      Boolean isLegal=Arrays.asList(Constant.FILEEXTENSION).contains(suffix.toLowerCase());
      if(file.getSize()>1024*1024*10){
         succMap.put("error", 1);
         succMap.put("msg", "文件大于10M!");
      }else if(file.getOriginalFilename().getBytes("utf-8").length>50){

         succMap.put("error", 1);
         succMap.put("msg", "文件名超过50个字符!");
      }else if (!isLegal) {
         succMap.put("error", 1);
         succMap.put("msg", "文件格式错误!");
      }else{
         Date date=new Date();
         SimpleDateFormat datePathFormat = new SimpleDateFormat("yyyyMM");
         String path=datePathFormat.format(date);
         String storeName=service.tx_getFilesId()+suffix;

         String url="/"+path+"/"+storeName;

         String furl = UUID.randomUUID().toString() + suffix;

         //因为transferTo只能将文件存储至硬盘位置,无法存储至服务器,而httpPost可以
         //所以先将文件临时存放至项目路径
         String tempPath = request.getRealPath("/temp/"+storeName);
         File tempFile = new File(tempPath);
         file.transferTo(tempFile);

         //将临时存放的文件存入远程nginx文件路径(httpPost方法需要file文件,这个file变量不可以是文件流,只能是有路径的文件,所以上面需要先存放临时文件)
         int res_code =  PostFileToRemote(furl, tempFile,url); //调用PostFileToRemote方法

         //删除临时文件
         tempFile.delete();
         succMap.put("error", 0);
         succMap.put("url", Constant.FILE_VIEW_URL+url);
      }
   }
   PrintWriter out = response.getWriter();
   out.print(succMap.toJSONString());
   out.close();
}
/**
 * 上传文件至远程服务器
*/
public int PostFileToRemote(String uuidName, File file,String path) throws Exception{
   int code =500;
   CloseableHttpClient httpclient = HttpClients.createDefault(); //创建一个httpclient

       try {
      HttpPost httppost = new HttpPost(Constant.FILE_SERVER_URL);
      //REMOTE_FILESERVER_UPLOAD_URL此路径写在Constant类里面
      HttpEntity reqEntity = MultipartEntityBuilder.create()
            .addPart("token", new StringBody(Constant.FILE_SERVER_TOKEN,ContentType.TEXT_PLAIN))//token验证
            .addPart("path", new StringBody(path,ContentType.TEXT_PLAIN))
            .addPart("bin", new FileBody(file, ContentType.APPLICATION_OCTET_STREAM,file.getName()))
            .build();
      httppost.setEntity(reqEntity);

      CloseableHttpResponse response = httpclient.execute(httppost);
      try {
         EntityUtils.consume(response.getEntity());
         code = response.getStatusLine().getStatusCode();
      } finally {
         response.close();
      }
   } catch (Exception e) {
      e.printStackTrace();
   } finally {
      try {
         httpclient.close();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
   return code;
}

四. 远程服务器Tomcat(也可以使用nginx)部署web附件处理后台

private static String token="";//与前端密钥进行比较
private static String url="";//存储在文件服务器的位置

@ResponseBody
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public Map<String,Object> upload(HttpServletRequest req) throws IOException {
    Map<String,Object> retMap = new HashMap<String,Object>();

    String pageToken=req.getParameter("token");
    String path=req.getParameter("path");//存储相对路径,如/201902/201902120001.png

    //获取文件保存配置项
    // 构造Properties对象
    Properties properties = new Properties();

    // 定义配置文件输入流
    InputStream is = null;
    try {
        // 获取配置文件输入流
        is = FileController.class.getResourceAsStream("/setting.properties");
        // 加载配置文件
        properties.load(is);
        // 读取配置文件
        token=(String) properties.get("token");// token密钥
        url=(String) properties.get("url");// 文件保存路径
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 判断输入流是否为空
        if (null != is) {
            try {
                // 关闭输入流
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    if(!token.equals(pageToken)){
        retMap.put("result","0");
        retMap.put("msg","token身份验证错误!");
    }else{
        CommonsMultipartResolver resolver = new CommonsMultipartResolver(
                req.getServletContext());
        if (resolver.isMultipart(req)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) req;
            // 取得request中的所有文件名
            Iterator<String> iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                String fileName = iter.next();
                // 取得上传文件
                List<MultipartFile> mfs = multiRequest.getFiles(fileName);
                for(MultipartFile file:mfs){

                    File tempFile = new File(url+path);
                    File fileParent = tempFile.getParentFile();
                    if(!fileParent.exists()){
                        //如果存储文件的父文件夹不存在就创建
                        fileParent.mkdirs();
                    }

                    InputStream inputStream=file.getInputStream();
                    FileOutputStream fos=new FileOutputStream(tempFile);
                    byte[]buffer=new byte[1024];
                    int len=0;
                    while ((len=inputStream.read(buffer))!=-1) {
                        fos.write(buffer,0, len);
                    }
                    inputStream.close();
                    fos.close();
                }
            }
            retMap.put("result","1");
            retMap.put("msg","上传成功");
        }
    }

    return retMap;
}

五. 远程附件服务器使用nginx映射静态文件提供附件的下载于查看

location  ~ .*\.(gif|jpg|jpeg|png)$ {
            root   html/files; 
              proxy_store on;  
              proxy_store_access user:rw group:rw all:rw;  
              proxy_temp_path     html/files;#图片访问路径  
              proxy_redirect     off;  
              proxy_set_header    Host 127.0.0.1;  
              client_max_body_size  10m;  
              client_body_buffer_size 1280k;  
              proxy_connect_timeout  900;  
              proxy_send_timeout   900;  
              proxy_read_timeout   900;  
              proxy_buffer_size    40k;  
              proxy_buffers      40 320k;  
              proxy_busy_buffers_size 640k;  
              proxy_temp_file_write_size 640k;  
              if ( !-e $request_filename)  
              {  
                 proxy_pass http://127.0.0.1:8079;#默认80端口  
              }  
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值