大家安安,今天來實作小畫家後端功能
1.上傳圖片 <-今天會介紹的
2.下載圖片
3.列出圖片網址
先設定application.properties的設定
# 允許多檔案上傳
spring.servlet.multipart.enabled=true
# Threshold after which files are written to disk.
spring.servlet.multipart.file-size-threshold=2KB
# 檔案最大大小
spring.servlet.multipart.max-file-size=200MB
# Max Request Size
spring.servlet.multipart.max-request-size=215MB
1.設計資料庫,處理entity
上傳圖片API,在資料庫應該要有幾個欄位
1.1資料格式,是jpg,txt之類的,之後若要分開列出比較方便
1.2ID
1.3檔案名稱
1.4使用者名稱
1.5檔案位置(要存取相對位置,這樣取出才方便)
@Repository
@Entity
@Table(name = "file_machan")
public class FileUpDownModel {
// public FileUpDownModel(Integer id, Integer userId, String userName, String fileName, String type, String typeFormat, String fileDirectory) {
// this.id = id;
// this.userId = userId;
// this.userName = userName;
// this.fileName = fileName;
// this.type = type;
// this.filesize = typeFormat;
// this.fileDirectory = fileDirectory;
// }
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Integer id;
public FileUpDownModel(){
}
public String getImgurl() {
return imgurl;
}
public void setImgurl(String imgurl) {
this.imgurl = imgurl;
}
@Column(name = "imgurl")
private String imgurl;
@Column(name = "username")
private String userName;
@Column(name = "filename")
private String fileName;
@Column(name = "type")
private String type;
public String getFilesize() {
return filesize;
}
public void setFilesize(String filesize) {
this.filesize = filesize;
}
@Column(name = "filesize")
private String filesize;
@Column(name = "filedirectory")
private String fileDirectory="";
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFileDirectory() {
return fileDirectory;
}
public void setFileDirectory(String fileDirectory) {
this.fileDirectory = fileDirectory;
}
}
2.Repository
一樣,列出fileDirectory跟找全部
@Repository
public interface UpLoadRepository extends JpaRepository<FileUpDownModel,Integer> {
FileUpDownModel findByFileDirectory (String fileDir);
List<FileUpDownModel> findAll();
}
3.Service
先用依賴注入注入@Autowired repository
宣告一個path代表他要存在哪
@Service
public class
FileUpLoadService {
@Autowired
UpLoadRepository upLoadRepository;
private Path fileStoreLocation;..}
3.1 constructor
@Autowired
public FileUpLoadService (FileUpDownModel upLoadModel){
this.fileStoreLocation = Paths.get("/home/uuko/web/web-socket-project/src/main/resources/static/").toAbsolutePath().normalize();
try {
Files.createDirectories(this.fileStoreLocation);
} catch (IOException e) {
try {
throw new Exception("Could not create the directory where the uploaded files will be stored",e);
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
3.2
public String storeNewFile(MultipartFile multipartFile,String userName,String fileSize) throws Exception {..}
拿到原本的fileName
String orgFileName = StringUtils.cleanPath(multipartFile.getOriginalFilename());
String newFileName = "";
判斷如果原本的fileName中有不符合元素
丟出exception
if (orgFileName.contains("..")){
throw new Exception("有不合法的元素 " + orgFileName);
}
拿ip
String command = "powershell -c "$(ipconfig | where {$_ -match 'IPv4.+\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' } | out-null; $Matches[1]) > C:\Users\uuko\Desktop\web\web-socket-project\src\main\resources\ip.txt";
String fileExtension="";
String fileOrgName="";
fileExtension=orgFileName.substring(orgFileName.lastIndexOf("."));
fileOrgName=orgFileName.substring(0,orgFileName.lastIndexOf("."));
newFileName=userName+"_"+fileOrgName+fileExtension;
接下來拿目標儲存地址,並複製到位置
Path targetLocation = this.fileStoreLocation.resolve(newFileName);
Files.copy(multipartFile.getInputStream(),targetLocation, StandardCopyOption.REPLACE_EXISTING);
FileUpDownModel checkIfRepeat=upLoadRepository.findByFileDirectory(newFileName);
然後找到directory,看有沒有這個directory,然後把它存入資料庫
if (checkIfRepeat!=null){
checkIfRepeat.setImgurl("http://"+line0+":8080/"+newFileName);
checkIfRepeat.setUserName(userName);
checkIfRepeat.setFileName(newFileName);
checkIfRepeat.setType(multipartFile.getContentType());
checkIfRepeat.setFilesize(fileSize);
checkIfRepeat.setFileDirectory(fileStoreLocation+"\\"+newFileName);
upLoadRepository.save(checkIfRepeat);
}
else {
FileUpDownModel newFileModel = new FileUpDownModel();
newFileModel.setImgurl("http://"+line0+":8080/"+newFileName);
newFileModel.setType(multipartFile.getContentType());
newFileModel.setFilesize(fileSize);
newFileModel.setFileName(newFileName);
newFileModel.setUserName(userName);
newFileModel.setFileDirectory(fileStoreLocation+"\\"+newFileName);
upLoadRepository.save(newFileModel);
}
return newFileName;
4.Controller
上傳
@PostMapping("/uploadFile")
public UploadFileResponse uploadFile(@RequestParam("file")MultipartFile file
, @RequestParam("userName") String userName) throws Exception {
String fileName=fileUpLoadService.storeNewFile(file,userName,String.valueOf(file.getSize()));
...
然後用servlet創出url並塞入資料庫
String fileDownLoadUrL = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/downloadFile/")
.path(fileName)
.toUriString();
**重點,要讓外面的人可以拿到圖片
就需要讓圖片是存在static資料夾才能拿到