Skip to content

Instantly share code, notes, and snippets.

@thomasJang
Created May 28, 2017 10:48
Show Gist options
  • Save thomasJang/aec2fd1c30d2e8de911103ec344244b7 to your computer and use it in GitHub Desktop.
Save thomasJang/aec2fd1c30d2e8de911103ec344244b7 to your computer and use it in GitHub Desktop.
AX5Upload JAVA
package com.chequer.ax5.api.demo.entity.file;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.time.LocalDateTime;
import java.util.UUID;
@Data
public class AX5File implements Comparable {
private String id;
private String fileName;
private String ext;
private long fileSize;
private String createdAt;
@JsonIgnore
private File file;
@JsonIgnore
private MultipartFile multipartFile;
private long lastModified;
public static AX5File of(MultipartFile multipartFile) {
AX5File ax5File = new AX5File();
ax5File.setId(UUID.randomUUID().toString());
ax5File.setFileName(FilenameUtils.getName(multipartFile.getOriginalFilename()));
ax5File.setExt(FilenameUtils.getExtension(multipartFile.getOriginalFilename()));
ax5File.setFileSize(multipartFile.getSize());
ax5File.setCreatedAt(LocalDateTime.now().toString());
ax5File.setMultipartFile(multipartFile);
return ax5File;
}
public String getSaveName() {
return String.format("%s.%s", id, ext);
}
public String getThumbnailSaveName() {
return String.format("%s-thumbnail.%s", id, ext);
}
public String getJsonName() {
return String.format("%s.json", id, ext);
}
@Override
public int compareTo(Object o) {
AX5File ax5File = (AX5File) o;
long result = lastModified - ax5File.lastModified;
if (result < 0) {
return -1;
} else if (result > 0) {
return 1;
} else {
return 0;
}
}
@JsonProperty("preview")
public String preview() {
return "/api/v1/ax5uploader/preview?id=" + getId();
}
@JsonProperty("thumbnail")
public String thumbnail() {
return "/api/v1/ax5uploader/thumbnail?id=" + getId();
}
@JsonProperty("download")
public String download() {
return "/api/v1/ax5uploader/download?id=" + getId();
}
}
package com.chequer.ax5.api.demo.controllers;
import com.chequer.ax5.api.demo.entity.file.AX5File;
import com.chequer.ax5.api.demo.entity.file.FileUploadService;
import com.chequer.ax5.api.demo.response.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@RestController
@RequestMapping("/api/v1/ax5uploader")
public class AX5UploaderController extends BaseController {
@Autowired
private FileUploadService fileUploadService;
@PostMapping
public AX5File upload(@RequestParam MultipartFile file) throws IOException {
return fileUploadService.upload(file);
}
@PostMapping(value = "/delete")
public ApiResponse delete(@RequestBody List<AX5File> files) throws IOException {
fileUploadService.delete(files);
return ok();
}
@GetMapping(value = "/download")
@ResponseBody
public ResponseEntity<byte[]> download(HttpServletRequest request, @RequestParam String id) throws IOException {
return fileUploadService.download(request, id);
}
@RequestMapping(value = "/preview", method = RequestMethod.GET)
public void preview(HttpServletResponse response, @RequestParam String id) throws IOException {
fileUploadService.preview(response, id);
}
@RequestMapping(value = "/thumbnail", method = RequestMethod.GET)
public void thumbnail(HttpServletResponse response, @RequestParam String id) throws IOException {
fileUploadService.thumbnail(response, id);
}
@GetMapping
public List<AX5File> files() {
return fileUploadService.files();
}
@GetMapping(value = "/flush")
public ApiResponse flush() {
fileUploadService.flush();
return ok();
}
}
package com.chequer.ax5.api.demo.entity.file;
import com.chequer.ax5.api.demo.entity.Types;
import com.chequer.ax5.api.demo.utils.JsonUtils;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import net.coobird.thumbnailator.name.Rename;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import static java.util.stream.Collectors.toList;
@Service
public class FilePersistService implements InitializingBean {
@Value("${ax5uploader.repository.path}")
private String path;
public void persist(AX5File ax5File) throws IOException {
clean();
File file = new File(path + File.separator + ax5File.getSaveName());
// 파일 로컬시스템에 저장
ax5File.getMultipartFile().transferTo(file);
// JSON 정보 저장
FileUtils.writeStringToFile(new File(path + File.separator + ax5File.getJsonName()), JsonUtils.toJson(ax5File), "UTF-8");
String fileType = getFileType(ax5File.getExt());
if (fileType.equals(Types.FileType.IMAGE)) {
try {
Thumbnails.of(file)
.crop(Positions.CENTER)
.size(320, 320)
.toFiles(new File(path), Rename.SUFFIX_HYPHEN_THUMBNAIL);
} catch (Exception e) {
}
}
}
int maxSaveFileCount = 20;
public void clean() throws IOException {
List<AX5File> ax5Files = listFiles();
if (ax5Files.size() > maxSaveFileCount) {
for (int i = maxSaveFileCount - 1; i < ax5Files.size(); i++) {
delete(ax5Files.get(i));
}
}
}
@Override
public void afterPropertiesSet() throws Exception {
FileUtils.forceMkdir(new File(path));
}
public List<AX5File> listFiles() {
List<AX5File> files = FileUtils.listFiles(new File(path), new String[]{"json"}, false).stream().map(file -> {
try {
return getAx5File(file);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}).collect(toList());
Collections.sort(files);
return files;
}
public AX5File getAx5File(File file) throws IOException {
AX5File ax5File = JsonUtils.fromJson(FileUtils.readFileToString(file, "UTF-8"), AX5File.class);
ax5File.setLastModified(file.lastModified());
ax5File.setFile(new File(path + File.separator + ax5File.getSaveName()));
return ax5File;
}
public AX5File getAx5File(String id) throws IOException {
return getAx5File(new File(path + File.separator + id + ".json"));
}
public void flush() {
FileUtils.deleteQuietly(new File(path));
}
public void delete(AX5File ax5File) throws IOException {
ax5File = getAx5File(ax5File.getId());
FileUtils.deleteQuietly(new File(path + File.separator + ax5File.getSaveName()));
FileUtils.deleteQuietly(new File(path + File.separator + ax5File.getJsonName()));
}
public void preview(HttpServletResponse response, String id, String type) throws IOException {
AX5File ax5File = getAx5File(id);
if (ax5File == null)
return;
MediaType mediaType = null;
String imagePath = "";
switch (ax5File.getExt().toUpperCase()) {
case Types.FileExtensions.JPEG:
case Types.FileExtensions.JPG:
mediaType = MediaType.IMAGE_JPEG;
break;
case Types.FileExtensions.PNG:
mediaType = MediaType.IMAGE_PNG;
break;
case Types.FileExtensions.GIF:
mediaType = MediaType.IMAGE_GIF;
break;
default:
}
switch (type) {
case Types.ImagePreviewType.ORIGIN:
imagePath = ax5File.getSaveName();
break;
case Types.ImagePreviewType.THUMBNAIL:
imagePath = ax5File.getThumbnailSaveName();
break;
}
if (mediaType != null) {
File file = new File(path + File.separator + imagePath);
byte[] bytes = FileUtils.readFileToByteArray(file);
response.setContentType(mediaType.toString());
response.setContentLength(bytes.length);
response.getOutputStream().write(bytes);
}
}
private String getFileType(String extension) {
switch (extension.toUpperCase()) {
case Types.FileExtensions.PNG:
case Types.FileExtensions.JPG:
case Types.FileExtensions.JPEG:
case Types.FileExtensions.GIF:
case Types.FileExtensions.BMP:
case Types.FileExtensions.TIFF:
case Types.FileExtensions.TIF:
return Types.FileType.IMAGE;
case Types.FileExtensions.PDF:
return Types.FileType.PDF;
default:
return Types.FileType.ETC;
}
}
}
package com.chequer.ax5.api.demo.entity.file;
import com.chequer.ax5.api.demo.entity.Types;
import com.chequer.ax5.api.demo.utils.AgentUtils;
import eu.bitwalker.useragentutils.Browser;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
@Service
public class FileUploadService {
@Autowired
private FilePersistService filePersistService;
public AX5File upload(MultipartFile multipartFile) throws IOException {
AX5File file = AX5File.of(multipartFile);
filePersistService.persist(file);
return file;
}
public List<AX5File> files() {
return filePersistService.listFiles();
}
public AX5File getFile(String id) throws IOException {
return filePersistService.getAx5File(id);
}
public void flush() {
filePersistService.flush();
}
public void delete(List<AX5File> files) throws IOException {
for (AX5File ax5File : files) {
filePersistService.delete(ax5File);
}
}
public ResponseEntity<byte[]> download(HttpServletRequest request, String id) throws IOException {
AX5File ax5File = getFile(id);
byte[] bytes = FileUtils.readFileToByteArray(ax5File.getFile());
String fileName = getDisposition(request, ax5File.getFileName());
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
httpHeaders.setContentLength(bytes.length);
httpHeaders.setContentDispositionFormData("attachment", fileName);
return new ResponseEntity<>(bytes, httpHeaders, HttpStatus.OK);
}
public static String getDisposition(HttpServletRequest request, String fileName) {
try {
Browser browser = AgentUtils.getBrowser(request);
switch (browser) {
case IE:
return URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
case CHROME:
StringBuffer sb = new StringBuffer();
for (int i = 0; i < fileName.length(); i++) {
char c = fileName.charAt(i);
if (c > '~') {
sb.append(URLEncoder.encode("" + c, "UTF-8"));
} else {
sb.append(c);
}
}
return sb.toString();
case OPERA:
case FIREFOX:
return new String(fileName.getBytes("UTF-8"), "8859_1");
}
} catch (Exception e) {
// ignore;
}
return fileName;
}
public void preview(HttpServletResponse response, String id) throws IOException {
filePersistService.preview(response, id, Types.ImagePreviewType.ORIGIN);
}
public void thumbnail(HttpServletResponse response, String id) throws IOException {
filePersistService.preview(response, id, Types.ImagePreviewType.THUMBNAIL);
}
}
package com.chequer.ax5.api.demo.entity;
public class Types {
public static class FileExtensions {
public static final String PNG = "PNG";
public static final String JPG = "JPG";
public static final String JPEG = "JPEG";
public static final String GIF = "GIF";
public static final String BMP = "BMP";
public static final String TIFF = "TIFF";
public static final String TIF = "TIF";
public static final String PDF = "PDF";
}
public static class FileType {
public static final String IMAGE = "IMAGE";
public static final String PDF = "PDF";
public static final String ETC = "ETC";
}
public static class ImagePreviewType {
public static final String THUMBNAIL = "THUMBNAIL";
public static final String ORIGIN = "ORIGIN";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment