欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot 如何優(yōu)雅的實(shí)現(xiàn)跨服務(wù)器上傳文件的示例

 更新時(shí)間:2020年04月23日 12:09:27   作者:jiangxiaoju  
這篇文章主要介紹了SpringBoot 如何優(yōu)雅的實(shí)現(xiàn)跨服務(wù)器上傳文件的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

項(xiàng)目完整代碼鏈接:代碼鏈接

跨服務(wù)上傳文件示意圖

一、創(chuàng)建項(xiàng)目

  • springboot:2.2.6
  • JDK:1.8

由于資源有限,就用不同端口表示不同服務(wù)器了。

1.1 上傳文件的項(xiàng)目

首先idea快速搭建工具創(chuàng)建一個(gè)springboot項(xiàng)目,名字為fileupload,作為上傳文件的服務(wù)端。

選擇spring web模塊即可


配置相關(guān)參數(shù)

spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=30MB
spring.servlet.multipart.max-request-size=30MB
#文件保存的url,末尾的 / 別漏了
file.upload.path=http://localhost:8888/fileuploadserver/uploads/

添加坐標(biāo)依賴

跨服器上傳所需要的jar包坐標(biāo)

<dependency>
  <groupId>com.sun.jersey</groupId>
  <artifactId>jersey-core</artifactId>
  <version>1.18.1</version>
</dependency>
<dependency>
  <groupId>com.sun.jersey</groupId>
  <artifactId>jersey-client</artifactId>
  <version>1.18.1</version>
</dependency>

1.2 創(chuàng)建fileuploadserver 保存文件服務(wù)器

創(chuàng)建一個(gè)jeex項(xiàng)目,項(xiàng)目名字為fileuploadserver,什么都不需要配置。然后再webapp目錄下創(chuàng)建一個(gè)uploads文件夾,與上面項(xiàng)目設(shè)置的文件保存地址一直,然后配置好tomcat環(huán)境啟動(dòng)即可。記得把web.xml文件里面的配置信息刪掉

如下圖所示

記得改下Http和JMX的端口,免得和其他項(xiàng)目沖突了。

二、編寫服務(wù)器接收文件上傳代碼

編寫一個(gè)controller類,用與處理文件上傳
MultipartFile類用來保存上傳的文件數(shù)據(jù)

package cn.jxj4869.fileupload.controller;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.UUID;

@Controller

public class FileController {
  @Value("${file.upload.path}")
  private String path;


  @RequestMapping("/fileupload/method1")
  @ResponseBody
  private String method1(@RequestParam("upload") MultipartFile upload) throws IOException {
    System.out.println("跨服務(wù)器上傳文件上傳");

    String filename = upload.getOriginalFilename();
    // 把文件的名稱設(shè)置唯一值,uuid
    String uuid = UUID.randomUUID().toString().replace("-", "");
    filename = uuid + "_" + filename;
    // 創(chuàng)建客戶端的對象

    Client client = Client.create();

    // 和圖片服務(wù)器進(jìn)行連接
    WebResource webResource = client.resource(path + filename);

    webResource.put(upload.getBytes());
    return "success";
  }
}

前端代碼

放在/resources/static/目錄下

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>fileupload</title>
</head>
<body>
<h3>method1</h3>
<form method="post" enctype="multipart/form-data" action="fileupload/method1">
  <input type="file" name="upload">
  <br>
  <input type="submit">
</form>
</body>
</html>

上傳效果如下

三、分析存在問題以及解決辦法

3.1 問題分析

正如上面寫的,只要我們關(guān)聯(lián)了服務(wù)器地址之后就可以直接通過put方法把文件上傳上去,這無疑是非常危險(xiǎn)的行為。因?yàn)樵谏蟼鬟^程中并沒有進(jìn)行用戶校驗(yàn),那么如果被人知道了服務(wù)器保存圖片的路徑,甚至不需要知道準(zhǔn)確路徑,只要知道服務(wù)器ip地址就夠了,那么他就可以通過put方法無限量的進(jìn)行服務(wù)器上傳。

根據(jù)apache官方在2017公布的一個(gè)漏洞,如果開啟了put方法,那么就可以任意寫寫入文件到服務(wù)器。但是如果禁用了put方法,那么又有導(dǎo)致一些需要put方法的業(yè)務(wù)無法使用。

一個(gè)解決辦法就是修改tomcat的配置。修改在tomcat的/conf目錄下的web.xml。找到下面這段

readonly設(shè)置成true。這樣就無法通過put往服務(wù)器中寫入文件了。

<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
      <param-name>readonly</param-name>
      <param-value>true</param-value>
    </init-param>
  </servlet>

但是這樣一來,我們就無法通過上述方法來進(jìn)行跨服務(wù)器上傳了,因?yàn)槲募?wù)器已經(jīng)禁止了通過put方法寫入文件。那么這種情況應(yīng)該怎么辦呢?

有一種思路就是把服務(wù)器接收到的文件上傳請求,通過HttpPost再把上傳的文件信息發(fā)送到文件服務(wù)器。由文件服務(wù)器自己處理是否接收保存文件。

3.2 修改項(xiàng)目fileupload的配置

添加HttpPost的相關(guān)坐標(biāo)依賴

  <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>4.3.6</version>
    </dependency>
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpmime</artifactId>
      <version>4.5</version>
    </dependency>
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpcore</artifactId>
      <version>4.4.1</version>
    </dependency>

添加配置:

application.properties

file.upload.path1=http://localhost:8888/fileupload/

3.3 創(chuàng)建fileuploadserver1 項(xiàng)目

創(chuàng)建一個(gè)springboot項(xiàng)目,選擇如**fileload**項(xiàng)目一樣。

創(chuàng)建好之后在/resources/目錄下創(chuàng)建一個(gè)uploads文件夾,用作保存上傳文件的位置。(也可以根據(jù)自己實(shí)際需要,更改文件保存的位置)

配置相關(guān)參數(shù)

# 文件上傳位置 這里是路徑是相對于項(xiàng)目而言,可以根據(jù)實(shí)際情況更改
file.upload.save-path=/uploads/
#文件訪問路徑
file.upload.url=/uploads/**

server.port=8888

#文件大小設(shè)置
spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=30MB
spring.servlet.multipart.max-request-size=100MB

3.4 編寫服務(wù)器接收文件上傳代碼

用數(shù)組的形式接收MultipartFile參數(shù),實(shí)現(xiàn)多文件上傳。

把上傳的文件用MultipartEntityBuilder打包好之后,再用HttpPost發(fā)送到文件服務(wù)器。這里最好需要了解一些HttpPost用法。

package cn.jxj4869.fileupload.controller;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.UUID;

@Controller

public class FileController {

  @Value("${file.upload.path1}")
  private String path1;


  @RequestMapping("/fileupload/method2")
  @ResponseBody
  private String method2(@RequestParam("upload") MultipartFile[] uploads) throws IOException {
    System.out.println("跨服務(wù)器上傳文件上傳");
    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost(path1);
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    for (MultipartFile upload : uploads) {
      String filename = upload.getOriginalFilename();
      builder.addBinaryBody("upload", upload.getBytes(), ContentType.MULTIPART_FORM_DATA, filename);
    }
    try {

      HttpEntity entity = builder.build();
      httpPost.setEntity(entity);
      CloseableHttpResponse response = httpClient.execute(httpPost);
      System.out.println(response.getStatusLine().getStatusCode());
      String s = response.getEntity().toString();
      System.out.println(s);
    } catch (Exception e) {

    } finally {
      httpClient.close();
    }
    return "success";
  }
}

前端部分的代碼

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>fileupload</title>
</head>
<body>
<h3>method2</h3>
<form method="post" enctype="multipart/form-data" action="fileupload/method2">
  <input type="file" name="upload"><br><br>
  <input type="file" name="upload"><br><br>
  <input type="file" name="upload">
  <br><br>
  <input type="submit">
</form>
</body>
</html>

3.5 編寫文件服務(wù)器接收代碼

接收的Controller

ResourceUtils.getURL("classpath:") 獲取當(dāng)前項(xiàng)目所在的路徑,最好別存在中文,可能會出錯(cuò)

package cn.jxj4869.fileuploadserver1.controller;

import com.sun.javafx.scene.shape.PathUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;

import java.util.UUID;

@Controller
public class FileController {

  @Value("${file.upload.save-path}")
  private String savePath;

  @PostMapping("/fileupload")
  @ResponseBody
  private String fileupload(HttpServletRequest request, @RequestParam("upload")MultipartFile[] uploads) throws IOException {
    System.out.println("文件上傳");
    
    String path= ResourceUtils.getURL("classpath:").getPath()+savePath;

    File file = new File(path);
    if (!file.exists()) {
      file.mkdir();
    }
    for (MultipartFile upload : uploads) {
      String filename = upload.getOriginalFilename();
      String uuid = UUID.randomUUID().toString().replace("-", "");
      filename=uuid+"_"+filename;
      upload.transferTo(new File(path,filename));
    }
    return "success";

  }
}

編寫配置類

package cn.jxj4869.fileuploadserver1.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cglib.core.WeakCacheKey;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MySpringMvcConfig implements WebMvcConfigurer {

  @Value("${file.upload.save-path}")
  private String savePath;
  @Value("${file.upload.url}")
  private String url;
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler(url).addResourceLocations("classpath:"+savePath);
  }
}

3.6 效果展示

到此這篇關(guān)于SpringBoot 如何優(yōu)雅的實(shí)現(xiàn)跨服務(wù)器上傳文件的示例的文章就介紹到這了,更多相關(guān)SpringBoot 跨服務(wù)器上傳文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論