SpringBoot上傳文件到服務器
一、客戶端
1、定義上傳文件信息封裝類
public class UploadFileStatus {
/*文件名字*/
private String fileName;
/*文件類型,包括img,video,html,preview_html等*/
private String fileType;
/*文件路徑,用於提示文件服務器將文件存儲到何種路徑之下*/
private String filePath;
/*文件的輸出流*/
private FileInputStream inputStream;
/*文件的大小*/
private long fileSize;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getFileType() {
return fileType;
}
public void setFileType(String fileType) {
this.fileType = fileType;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(FileInputStream inputStream) {
this.inputStream = inputStream;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
}
2、上傳文件工具類
/**
* @Description: 用於發送各種Http請求的工具類
*/
public class HttpUtils {
/**
* @Description: 用於向靜態資源服務器推送數據流(包括圖片,視頻等靜態資源)
* @param targetUrl 目標URL
* @param status 上傳的文件信息
*/
// 發送post請求,獲取String
public static String postFile(String targetUrl, UploadFileStatus status) {
try {
URL url = new URL(targetUrl.trim());
// 打開連接
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
// 設置允許輸入輸出
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
// 設置不用緩存
urlConnection.setUseCaches(false);
// 設置傳遞方式
urlConnection.setRequestMethod("POST");
// 設置維持長連接
urlConnection.setRequestProperty("Connection", "keep-alive");
// 設置字符集
urlConnection.setRequestProperty("Charset", "UTF-8");
// 設置文件長度和類型
urlConnection.setRequestProperty("Content-Length", String.valueOf(status.getFileSize()));
// 設置文件類型
urlConnection.setRequestProperty("Content-Type", "application/x-form-urlencoded");
// 設置傳遞的參數
urlConnection.setRequestProperty("fileName", status.getFileName());
urlConnection.setRequestProperty("fileType", status.getFileType());
urlConnection.setRequestProperty("filePath", status.getFilePath());
// 開始連接請求
urlConnection.connect();
OutputStream out = urlConnection.getOutputStream();
// 獲取上傳文件的輸入流
InputStream fileIS = status.getInputStream();
byte[] tempBytes = new byte[1024];
int byteRead = 0;
// 寫入請求的字符串
while((byteRead = fileIS.read(tempBytes)) != -1) {
out.write(tempBytes, 0, byteRead);
}
out.flush();
fileIS.close();
out.close();
//TODO
System.out.println(status.getFileName() +"." + status.getFileType() + "的上傳回復的code是:" + urlConnection.getResponseCode());
// 請求返回的狀態
if (200 == urlConnection.getResponseCode()) {
// 關閉數據流
status.getInputStream().close();
// 請求返回的數據
InputStream in = urlConnection.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while (-1 != (len = in.read(buffer))) {
baos.write(buffer, 0, len);
baos.flush();
}
return baos.toString("utf-8");
}
} catch (IOException e) {
e.printStackTrace();
return "fail";
}
return "fail";
}
}
二、服務器端
1、接收上傳的文件,並且將上傳的文件存儲在指定路徑下
@RestController
@RequestMapping(value = "/")
public class UploadFileController {
/**
* 接收上傳的文件,並且將上傳的文件存儲在指定路徑下
* @param request
* @return
*/
@RequestMapping(value = "/upload")
public String upload(HttpServletRequest request) {
ServletInputStream sis = null;
FileOutputStream fos = null;
try {
// 文件名
String filename = request.getHeader("fileName");
// 文件類型,例如:jpg、png、pdf...
String fileType = request.getHeader("fileType");
// 存儲路徑
String filePath = request.getHeader("filePath");
File file = new File(filePath+filename+"."+fileType);
if(!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
if(!file.exists()) {
file.createNewFile();
}
sis = request.getInputStream();
fos = new FileOutputStream(file);
byte[] content = new byte[1024];
int len = 0;
while((len=sis.read(content)) > -1) {
fos.write(content, 0, len);
}
fos.flush();
return "success";
} catch (Exception ex) {
ex.printStackTrace();
return "fail";
} finally {
try {
if(sis!=null) {
sis.close();
}
if(fos!=null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2、設置靜態資源映射
@Configuration
public class MyWebMvcConfig extends WebMvcConfigurerAdapter {
/**
* 靜態資源映射
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 當訪問/file下的資源時,會到/root/myFile/下去找
// 例如訪問:http://localhost:8080/file/1.png時會去找/root/myFile/1.png
registry.addResourceHandler("/file/**").addResourceLocations("file:/root/myFile/");
super.addResourceHandlers(registry);
}
}
三、測試
將服務端程序部署在192.168.79.115服務器上,然後在本地運行客戶端程序,實現將本地文件上傳到服務器上,然後可以在服務器上訪問到上傳的文件
測試代碼
@RunWith(SpringRunner.class)
@SpringBootTest
public class FileClientApplicationTests {
@Test
public void uploadFileTest() throws FileNotFoundException {
// 要上傳的文件
File file = new File("E:/defalt-photo.png");
UploadFileStatus fileStatus = new UploadFileStatus();
// 上傳到服務器後的文件名
fileStatus.setFileName("test2");
// 上傳到服務器的哪個位置
fileStatus.setFilePath("/root/myFile/");
// 文件的大小
fileStatus.setFileSize(file.length());
// 文件的類型
fileStatus.setFileType("png");
fileStatus.setInputStream(new FileInputStream(file));
String result = UploadFileUtil.uploadFile("http://192.168.79.115:8090/upload", fileStatus);
System.out.println(result);
}
}
在瀏覽器中訪問:http://192.168.79.115:8090/file/test2.png,就可以看到剛剛上傳的圖片了,注意,需要關閉服務器的防火牆