티스토리 뷰
[ 브라우저에서 첨부파일 처리 ]
1. Form 태그를 이용하는 방식
- 브라우저의 제한이 없어야 하는 경우에 사용
- 일반적으로 페이지 이동과 동시에 첨부파일을 업로드하는 방식
- <iframe>을 이용해서 화면의 이동 없이 첨부파일을 처리하는 방식
2. Ajax를 이용하는 방식
- 첨부파일을 별도로 처리하는 방식
- <input type='file'>을 이용하고 Ajax로 처리하는 방식
- HTML5의 Drag And Drop 기능이나 jQuery 라이브러리를 이용해서 처리하는 방식
[ 서버에서 첨부파일 처리 ]
- 서버 상 처리는 대부분 비슷하다. 응답을 HTML 코드로 하는지 JSON 등으로 처리하는지 정도의 구분만 하면 됨.
- 첨부파일의 처리를 위해서 어떤 종류의 라이브러리나 API 등을 활용할 것인지에 주의해야함.
ex) cos.jar : 지원 종료. 사용하지 말 것. commons-fileupload : 일반적으로 많이 활용됨. 서블릿 스펙 3.0 이전에도 사용 가능. 서블릿 3.0 이상은 자체적인 파일 업로드 처리가 API 상에서 지원
[ 설정 ]
- pom.xml 설정 : 서블릿 3.0 이상을 쓰기 위해 변경
<properties>
<java-version>1.8</java-version>
<org.springframework-version>5.0.7.RELEASE</org.springframework-version>
<org.aspectj-version>1.9.0</org.aspectj-version>
<org.slf4j-version>1.7.25</org.slf4j-version>
</properties>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
- web.xml 설정 : XML 네임스페이스 2.5 버전을 3.0으로 변경. web.xml의 설정은 WAS 자체의 설정임.
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
- 서블릿 태그 내에 <multipart-config> 태그 추가
<multipart-config>
<location>/Users/bibidi/upload/tmp</location>
<max-file-size>20971520</max-file-size>
<max-request-size>41943040</max-request-size>
<file-size-threshold>20971520</file-size-threshold>
</multipart-config>
location : specifies the directory where uploaded files will be stored. When not specified, a temporary directory will be used.
max-file-size : specifies the maximum size permitted for uploaded files. The default is 1MB
max-request-size : specifies the maximum size allowed for multipart/form-data requests. The default is 10MB.
file-size-threshold : specifies the size threshold after which files will be written to disk. The default is 0.
- MultipartResolver : 스프링에서 업로드 처리를 하며 객체를 빈으로 등록해야함. Web과 관련된 설정이므로 servlet-context.xml 이용.
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>
[ 브라우저 Form 작성 ]
<form action="uploadFormAction" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile" multiple>
<button>Submit</button>
</form>
- action : 폼 데이터가 도착할 URL을 명시함.
- method : 폼 데이터가 서버로 제출될 때 사용되는 HTTP 메소드를 명시함.
- enctype : 해당 데이터가 인코딩되는 방법을 명시함. (단, <form> 요소의 method 속성값이 “post”인 경우에만 사용할 수 있음)
- enctype 종류
1. application/x-www-form-urlencoded : 기본값으로, 모든 문자들은 서버로 보내기 전에 인코딩됨을 명시함.
2. multipart/form-data : 모든 문자를 인코딩하지 않음을 명시함. 이 방식은 <form> 요소가 파일이나 이미지를 서버로 전송할 때 주로 사용함.
3. text/plain : 공백 문자(space)는 "+" 기호로 변환하지만, 나머지 문자는 모두 인코딩되지 않음을 명시함.
- multiple : <input> 요소에 사용자가 둘 이상의 값을 입력할 수 있음을 명시함.
* form 태그 관련 정보 : tcpschool.com/html-tags/form
[ Spring MultipartFile ]
- String getName() : 파라미터의 이름. <input> 태그의 이름.
- String getOriginalFileName() : 업로드되는 파일의 이름
- boolean isEmpty() : 파일이 존재하지 않으면 true 반환
- long getSize() : 업로드되는 파일의 크기. 단위는 bytes
- byte[] getBytes() : byte[]로 파일 데이터 변환
- inputStream getInputStream() : 파일 데이터와 연결된 inputStream을 반환
- transferTo(File file) : file에 업로드된 파일 저장.
[ Java File Class ]
- An abstract representation of file and directory pathnames.
- 파일을 실제로 그 자리에 생성하는 게 아니라 그냥 그 파일을 가리키는 객체라는 사실을 기억해야함.
- Constructor File(String parent, String child) : Creates a new File instance from a parent abstract pathname and a child pathname string.
- boolean createNewFile() : Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist.
- void mkdirs() : Creates the directory named by this abstract pathname, including any necessary but nonexistent parent directories.
* reference : docs.oracle.com/javase/7/docs/api/java/io/File.html
[ Java Files Class ]
- String probeContentType(Path path) : Files 클래스의 static method. 파일 타입을 MIME type 형식의 String으로 반환. 확장자가 없으면 null을 반환함. null에 대한 처리를 해야할 때가 있음.
* reference : docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#probeContentType(java.nio.file.Path)
* reference : offbyone.tistory.com/330 // MIME type이 없을 때 null을 반환하는 걸 알아낸 곳.
[ MIME type 종류 ]
- 이미지 파일들은 모두 image/~~ 형식의 이름을 가짐. image 파일인지 확인할 땐 String이 image로 시작하는지 체크하면 된다.
* reference : developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
[ Java String Class ]
- Constructor String(byte[] bytes, String charsetName) : Constructs a new String by decoding the specified array of bytes using the specified charset.
- boolean startsWith(String prefix) : String이 prefix로 시작하는지 체크함.
* reference : docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html
[ jQuery 정리 ]
- jQuery cdn : code.jquery.com/
- selector
1. $("p") : element selector
2. $("#id") : id selector
3. $(".class") : class selector
4. $(this) : current HTML element
- selector 특정 단어 포함
1. $("input[name='한국']").css("background", "yellow"); // 일치
2. $("input[name*='한국']").css("background", "silver"); // 포함
3. $("input[name~='한국']").css("background", "cyan"); // 독립
* reference : www.w3schools.com/jquery/jquery_ref_selectors.asp
- method(manipulation)
1. html() : Get the HTML contents of the first element in the set of matched elements or set the HTML contents of every matched element.
2. clone() : Create a deep copy of the set of matched elements.
* reference : api.jquery.com/category/manipulation/
- event methods
1. $(document).ready() : document 객체가 완전히 로드되면 함수 실행을 할 수 있도록 해 줌.
2. click() : 이 HTML element를 클릭하면 함수를 발생시킴.
3. on() : 이 HTML element에 하나 이상의 event handler를 붙일 때 사용
* reference : www.w3schools.com/jquery/jquery_events.asp
* reference : api.jquery.com/category/events/
* jquery quiz : www.w3schools.com/jquery/exercise_jq.asp?filename=exercise_jq_selectors1
[ 브라우저 Ajax ]
$(document).ready(function() {
$('#uploadBtn').on("click", function(e) {
const cloneObj = $(".uploadDiv").clone();
let formData = new FormData();
let inputFile = $("input[name='uploadFile']");
let files = inputFile[0].files;
console.log(files);
for (let i = 0; i < files.length; i++) {
if (!checkExtension(files[i].name, files[i].size)) {
return false;
}
formData.append("uploadFile", files[i]);
}
$.ajax({
url: '/uploadAjaxAction',
processData: false,
contentType: false,
data: formData,
type: 'POST',
dataType: 'json',
success: function(result) {
console.log(result);
showUploadedFile(result);
$(".uploadDiv").html(cloneObj.html());
}
});
});
$(".uploadResult").on("click", "span", function(e) {
const targetFile = $(this).data("file");
const type = $(this).data("type");
console.log(targetFile);
$.ajax({
url: '/deleteFile',
data: {fileName: targetFile, type: type},
dataType: 'text',
type: 'POST',
success: function(result) {
alert(result);
}
});
});
});
- 참고할만한 코드
- functione(e)에서 e의 의미는 이벤트 핸들러로 전달되는 이벤트 객체이다.
* reference : stackoverflow.com/questions/10323392/in-javascript-jquery-what-does-e-mean
- 첨부파일 데이터는 formData에 추가한 뒤에 Ajax를 통해서 formData 자체를 전송함. 이때 processData와 contentType은 반드시 false로 지정해야 전송됨.
- formData 객체
* reference : developer.mozilla.org/en-US/docs/Web/API/FormData/FormData
[ Javascript RegExp ]
- \ : 일반 문자 앞에선 해당 문자가 일반 문자로 해석되면 안 된다는 의미이고 특수 문자 앞에선 해당 문자가 일반 문자로 해석되어야 한다는 의미.
- * : 앞의 표현식이 0회 이상 연속으로 반복되는 부분과 대응됩니다. {0,} 와 같은 의미입니다.
- $ : 입력의 끝 부분과 대응됩니다. 만약 다중행 플래그가 참으로 설정되어 있다면, 줄 바꿈 문자의 바로 앞 부분과도 대응됩니다.
- . : 개행 문자를 제외한 모든 단일 문자와 대응됨.
- x|y : x 또는 y가 대응됨.
- ? : 앞의 문자가 0 또는 1회 등장하는 부분과 대응됨.
* reference : developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Regular_Expressions
[ Java SimpleDateFormat ]
- SimpleDateFormat("yyyy-MM-dd") : y는 year, M은 month, d는 달을 기준으로 day를 나타냄.
- String format(Date date) : Date를 pattern으로 바꾼 문자열을 반환함.
* reference : docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
* reference : tutorials.jenkov.com/java-internationalization/simpledateformat.html
[ Java Date ]
- Date() : 객체가 메모리를 할당받은 시각을 나타냄.
* reference : docs.oracle.com/javase/8/docs/api/java/util/Date.html
[ Java UUID ]
- static UUID randomUUID() : 랜덤 UUID를 만들어서 반환
- String toString() : UUID를 String으로 만들어서 반환
* reference : docs.oracle.com/javase/8/docs/api/java/util/UUID.html
[ Thumbnailator ]
- 썸네일 이미지를 만들어주는 라이브러리
- void createThumbnail(InputStream is, OutputStream os, int width, int height) : InputStream으로 원본 이미지 파일을 읽고 썸네일을 생성해서 OutputStream으로 데이터를 전송함.
* reference : mvnrepository.com/artifact/net.coobird/thumbnailator/0.4.8
* reference : coobird.github.io/thumbnailator/javadoc/0.4.14/
[ Java I/O ]
- InputStream, OutputStream : 바이트 단위 입출력을 위한 클래스. 그 중에서 최상위 클래스이다.
* reference : coding-factory.tistory.com/281
[ HTML Tags, CSS]
- CSS : display: flex 정리. 이 부분은 따로 새 글을 만들어서 정리해야함.
[ JavaScript 요소 조작 팁 ]
- element를 원상태로 되돌리기 : 처음에 element를 clone()으로 복사해두고 필요한 작업이 끝난 뒤에 복사해둔 내용을 다시 붙여넣음.
- 어떤 List 나열해서 보여주기 : div class 정의하고 <ul> 내에 <li>를 추가하도록 조작하면 됨. List 데이터를 json 형식으로 받으면 (index, obj) 형식으로 날아오기 때문에 each(function(index, boj) {}) 형태로 처리해야 함.
[ Spring ResponseEntity ]
- Extension of HttpEntity that adds an HttpStatus status code. Used in RestTemplate as well as in @Controller methods.
- Constructor ResponseEntity(T body, MultiValueMap<String, String> headers, HttpStatus status) : Create a ResponseEntity with a body, headers, and a status code.
* reference : docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/ResponseEntity.html
* reference : a1010100z.tistory.com/106
[ Spring HttpHeaders ]
- A data structure representing HTTP request or response headers, mapping String header names to a list of String values, also offering accessors for common application-level data types.
- Constructor HttpHeaders() : Construct a new, empty instance of the HttpHeaders object.
- void add(String headerName, String headerValue) : Add the given, single header value under the given name.
* reference : docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpHeaders.html
[ Spring FileCopyUtils ]
- Simple utility methods for file and stream copying. All copy methods use a block size of 4096 bytes, and close all affected streams when done. A variation of the copy methods from this class that leave streams open can be found in StreamUtils.
- static byte[] copyToByteArray(File in) : Copy the contents of the given input File into a new byte array.
* reference : docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/util/FileCopyUtils.html
[ JavaScript encodeURIComponent ]
- encodes a URI by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two "surrogate" characters).
* reference : developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
[ 첨부파일 다운로드 구현 ]
- byte[]로 반환하는 방법, Resource를 이용해 반환하는 방법이 있음.
1. 받아온 파일 이름을 이용해 resource에 FileSystemResource를 이용해 resource instance 할당.
2. resource가 존재하는지 체크함. 존재하지 않으면 NOT_FOUND 응답
3. 파일 이름에서 UUID 제거함.
4. User-Agent를 이용해서 사용자가 어떤 브라우저를 사용하는지 파악
5. 각 경우에 따라 다음과 같이 처리
- IE : URLEncode를 이용해서 downloadName을 UTF-8로 인코딩한 뒤. "\\+"을 " "로 바꿔줘야함.
- Edge : URLEncode를 이용해서 downlaodName을 UTF-8로 인코딩
- Chrome : String 생성자를 이용해서 resourceName을 getBytes("UTF-8")로 얻어내고 "ISO-8859-1"인코딩 적용. (ex new String(r.getBytes("UTF-8"), "ISO-8859-1"))
6. responseEntity에 resource, header, HttpStatus.OK 넣고 반환
[ Spring Resource ]
- Interface for a resource descriptor that abstracts from the actual type of underlying resource, such as a file or class path resource. An InputStream can be opened for every resource if it exists in physical form, but a URL or File handle can just be returned for certain resources. The actual behavior is implementation-specific.
* reference : docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/io/Resource.html
* reference : docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/resources.html
[ Spring FileSystemResource ]
- Resource implementation for java.io.File and java.nio.file.Path handles with a file system target. Supports resolution as a File and also as a URL. Implements the extended WritableResource interface.
- Note: As of Spring Framework 5.0, this Resource implementation uses NIO.2 API for read/write interactions. As of 5.1, it may be constructed with a Path handle in which case it will perform all file system interactions via NIO.2, only resorting to File on getFile().
- Constructor FileSystemResource(Path filePath) : Create a new FileSystemResource from a Path handle, performing all file system interactions via NIO.2 instead of File.
* reference : docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/io/FileSystemResource.html
[ IE, Edge 브라우저 사용 시 주의점 ]
- IE에서 파일을 업로드하면 파일 이름 앞에 경로까지 붙는 걸로 기억. 이를 잘 처리해야 함.
- IE, Edge에서 첨부파일 다운로드 시 한글 이름이 깨짐. Content-Disposition 값을 처리하는 방식이 IE의 경우 인코딩 방식이 다르기 때문임. 따라서 IE계열인 경우 HttpServletRequest에 포함된 헤더 정보들을 이용해서 요청이 발생한 브라우저에 따라 처리 방식을 달리 해야 함. Http 헤더 메시지 중에서 디바이스의 정보를 알 수 있는 헤더 User-Agent 값을 활용해야 함.
[ HTTP headers ]
* reference : developer.mozilla.org/ko/docs/Web/HTTP/Headers
[ Browser Error : Resource is interpreted as document but transffered with MIME type ~~]
* reference : stackoverflow.com/questions/6587393/resource-interpreted-as-document-but-transferred-with-mime-type-application-zip
[ Java URLEncoder ]
- Utility class for HTML form encoding. This class contains static methods for converting a String to the application/x-www-form-urlencoded MIME format. For more information about HTML form encoding, consult the HTML specification.
- static String encode(String s, String enc) : Translates a string into application/x-www-form-urlencoded format using a specific encoding scheme.
* reference : docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html
[ Java URLDecoder ]
- Utility class for HTML form decoding. This class contains static methods for decoding a String from the application/x-www-form-urlencoded MIME format.
- static String decode(String s, String enc) : Decodes a application/x-www-form-urlencoded string using a specific encoding scheme.
* reference : docs.oracle.com/javase/7/docs/api/java/net/URLDecoder.html
[ HTML 태그에 JavaScript 함수 넣기 ]
- 책에서 첨부파일 이미지 원본을 보여줄 때 a href="javascript:function" 방식으로 구현하는데, 이 방법이 좋은 방법인지에 대한 토론이 있음. 레퍼런스 참고
* reference : stackoverflow.com/questions/1070760/javascript-function-in-href-vs-onclick
[ RESTful하게 파일 업로드, 다운로드 ]
* reference : wjrmffldrhrl.github.io/REST-API/
'(구)게시판 프로젝트' 카테고리의 다른 글
데이터 모델링 2 (updated 21.05.07) (0) | 2021.04.10 |
---|---|
데이터 모델링 (0) | 2021.04.09 |
Spring Web Security 관련 정리(미완) (0) | 2021.03.26 |
오류 모음 (0) | 2021.01.13 |
오픈 소스 분석법에 대한 사이트 정리 (0) | 2020.08.07 |
- Total
- Today
- Yesterday
- 디지털 비디오 디스크
- 터보소트
- 백준 2243
- boj 3006
- 백준 3006
- boj 1280
- 백준 9345
- 사탕상자
- 백준 10775
- boj 9345
- 백준 2336
- boj 16562
- 백준 14868
- 제로베이스 백엔드 스쿨
- 백준 12713
- 제로베이스 스쿨
- 인간 대포
- boj 10775
- 백준 10473
- boj 1106
- 백준 1106
- 백준 16562
- 부트 캠프
- 백준 1280
- boj 2243
- Ugly Numbers
- boj 14868
- boj 10473
- boj 12713
- boj 2336
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |