Skip to content

Commit

Permalink
read and decrypt uploaded files
Browse files Browse the repository at this point in the history
  • Loading branch information
sbx0 committed Jan 11, 2024
1 parent 44fb28d commit 5c99901
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
import cn.sbx0.todo.service.common.Result;
import cn.sbx0.todo.utils.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
Expand All @@ -15,8 +16,6 @@
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
Expand All @@ -25,35 +24,56 @@
public class FileController {

private static final String UPLOAD_DIR = "C:\\Users\\winmj\\Pictures\\Upload\\";
public static final String ORIGINAL_FILE_NAME = "original_file_name";
public static final String MD5 = "md5";
public static final String JSON_TYPE = ".json";

@PostMapping("/upload")
public Result<String> handleFileUpload(@RequestParam("file") MultipartFile file) {
public Result<FileInfoEntity> handleFileUpload(@RequestParam("file") MultipartFile file) {
String newFileName = UUID.randomUUID().toString();
try {
// 保存文件信息
Map<String, String> info = new HashMap<>();
FileInfoEntity fileInfo = new FileInfoEntity();
// 新的文件名
fileInfo.setFileName(newFileName);
// 原始文件名
String fileName = file.getOriginalFilename();
info.put(ORIGINAL_FILE_NAME, fileName);
fileInfo.setOriginalFileName(fileName);
// MD5
String md5 = calculateMD5(file.getBytes());
info.put(MD5, md5);
Files.writeString(Paths.get(UPLOAD_DIR, newFileName + JSON_TYPE), JSON.parse(info));
fileInfo.setMd5(md5);
Files.writeString(Paths.get(UPLOAD_DIR, newFileName + JSON_TYPE), JSON.parse(fileInfo));

// 保存文件
Path filePath = Paths.get(UPLOAD_DIR, newFileName);
Files.write(filePath, file.getBytes());

return Result.success("Uploaded");
return Result.success(fileInfo);
} catch (IOException | NoSuchAlgorithmException e) {
log.error(e.getMessage(), e);
return Result.failure("Uploading Failed");
}
}

@GetMapping("/download/{fileName}")
public ResponseEntity<FileSystemResource> downloadFile(@PathVariable String fileName) throws IOException {
String filePath = UPLOAD_DIR + fileName;
// 文件信息的地址
String jsonFilePath = filePath + JSON_TYPE;
// 读取文件原始信息
FileInfoEntity fileInfo = JSON.readFromFile(jsonFilePath, FileInfoEntity.class);

FileSystemResource fileSystemResource = new FileSystemResource(filePath);

HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileInfo.getOriginalFileName());
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);

return ResponseEntity.ok()
.headers(headers)
.contentLength(fileSystemResource.contentLength())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(fileSystemResource);
}

private String calculateMD5(byte[] fileBytes) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(fileBytes);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package cn.sbx0.todo.business.file;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class FileInfoEntity {
private String fileName;
private String originalFileName;
private String md5;
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
.failureHandler(failureHandler)
)
.oauth2ResourceServer(oauth2 -> oauth2.jwt(withDefaults()))
.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED))
.exceptionHandling((exceptions) -> exceptions
.authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
.accessDeniedHandler(new BearerTokenAccessDeniedHandler())
Expand Down
7 changes: 7 additions & 0 deletions todo-service/src/main/java/cn/sbx0/todo/utils/JSON.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;

/**
* @author sbx0
* @since 2022/12/2
Expand Down Expand Up @@ -38,6 +41,10 @@ public static <T> T format(String content, Class<T> valueType) {
return null;
}

public static <T> T readFromFile(String filePath,Class<T> valueType) throws IOException {
return OBJECT_MAPPER.readValue(new File(filePath), valueType);
}

public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
return OBJECT_MAPPER.getTypeFactory().constructParametricType(collectionClass, elementClasses);
}
Expand Down
54 changes: 34 additions & 20 deletions todo-web/app/file/components/upload/upload.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, {useState} from 'react';
import {getCookie} from "../../../../apis/cookies";

function DragAndDropUpload() {
const [files, setFiles] = useState([])
const [dragging, setDragging] = useState(false);

const handleDragEnter = (event) => {
Expand All @@ -25,17 +26,17 @@ function DragAndDropUpload() {
event.preventDefault();
setDragging(false);

const files = event.dataTransfer.files;
const uploadFiles = event.dataTransfer.files;
// 处理上传文件的逻辑,例如使用FormData发送到服务器

console.log('Dropped files:', files);
console.log('Dropped files:', uploadFiles);

// 创建 FormData 对象
const formData = new FormData();

// 将每个文件添加到 FormData
for (let i = 0; i < files.length; i++) {
formData.append('file', files[i]);
for (let i = 0; i < uploadFiles.length; i++) {
formData.append('file', uploadFiles[i]);
}

let token, headers;
Expand All @@ -56,8 +57,10 @@ function DragAndDropUpload() {
})
.then(response => response.json())
.then(data => {
// 处理上传成功的逻辑
console.log('Upload success:', data);
let newFiles = files.slice(0);
let file = data.data;
newFiles.push(file);
setFiles(newFiles);
})
.catch(error => {
// 处理上传失败的逻辑
Expand All @@ -66,22 +69,33 @@ function DragAndDropUpload() {
};

return (
<div
className={`flex items-center justify-center h-screen bg-gray-100 ${dragging ? 'border-4 border-dashed border-blue-500' : ''}`}
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
onDragOver={handleDragOver}
onDrop={handleDrop}
>
<div className="bg-white rounded-lg shadow-lg p-6">
<h1 className="text-3xl font-bold mb-4">拖拽上传</h1>
<p className="text-gray-700 mb-4">
拖拽文件到此区域进行上传
</p>
<div className="border-2 border-dashed border-gray-400 p-4">
{dragging ? '放开以上传文件' : '拖拽文件到此区域'}
<div>
<div
className={`flex items-center justify-center h-screen bg-gray-100 ${dragging ? 'border-4 border-dashed border-blue-500' : ''}`}
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
onDragOver={handleDragOver}
onDrop={handleDrop}
>
<div className="bg-white rounded-lg shadow-lg p-6">
<h1 className="text-3xl font-bold mb-4">拖拽上传</h1>
<p className="text-gray-700 mb-4">
拖拽文件到此区域进行上传
</p>
<div className="border-2 border-dashed border-gray-400 p-4">
{dragging ? '放开以上传文件' : '拖拽文件到此区域'}
</div>
</div>
</div>
<div className="p-1 gap-1 grid grid-cols-3 grid-rows-1">
{
files.map((one => {
return <div key={one.fileName}>
<img src={'/api/file/download/' + one.fileName} alt="" loading="lazy"/>
</div>;
}))
}
</div>
</div>
);
}
Expand Down

0 comments on commit 5c99901

Please sign in to comment.