Created
May 28, 2017 10:48
-
-
Save thomasJang/aec2fd1c30d2e8de911103ec344244b7 to your computer and use it in GitHub Desktop.
AX5Upload JAVA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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