클라이언트가 파일(사진)을 업로드하는 과정을 구현해야하는데
cos라는 라이브러리를 이용해서 할 것이다.
WEB-INF-lib에 cos.jar 저장
COS 라이브러리 의 MultipartRequest는 업로드를 할때 사용한다.
일단 파일을 받을 upload(폴더)를 만들어둔다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>FileUpload From</title>
<style>
#uploadFromArea{
margin : auto;
width : 350px;
border : 1px solid black;
}
.td_title{
font-size:xx-large;
text-align:center;
}
</style>
</head>
<body>
<section id = "uploadFormArea">
<form action="fileUpload.jsp" method="post" enctype="multipart/form-data">
<table>
<tr>
<td colspan="2" class="td_title">파일 업로드 폼</td>
</tr>
<tr>
<td>
<label for ="name">올린사람 : </label>
</td>
<td>
<input type="text" name="name" id="name">
</td>
</tr>
<tr>
<td>
<label for ="subject">제목 : </label>
</td>
<td>
<input type="text" name="subject" id="subject">
</td>
</tr>
<tr>
<td>
<label for ="fileName1">파일명1 : </label>
</td>
<td>
<input type="file" name="fileName1" id="fileName1">
</td>
</tr>
<tr>
<td>
<label for ="fileName2">파일명2 : </label>
</td>
<td>
<input type="file" name="fileName2" id="fileName2">
</td>
</tr>
<tr>
<td colspan=2 align=center>
<input type="submit" value="전송">
</td>
</tr>
</table>
</form>
</section>
</body>
</html>
HTML으로 입력과 파일을 업로드할 폼을 만든다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="com.oreilly.servlet.MultipartRequest" %>
<%@ page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@ page import="java.util.*" %>
<%
String uploadPath=request.getRealPath("/upload");
int size =10*1024*1024;
String name="";
String subject="";
String filename1="";
String filename2="";
String origfilename1="";
String origfilename2="";
try{
MultipartRequest multi = new MultipartRequest
(
request,
uploadPath,
size,
"UTF-8",
new DefaultFileRenamePolicy()
);
name = multi.getParameter("name");
subject = multi.getParameter("subject");
Enumeration files = multi.getFileNames();
String file1 = (String) files.nextElement();
filename1=multi.getFilesystemName(file1);
origfilename1 = multi.getOriginalFileName(file1);
String file2 = (String) files.nextElement();
filename2=multi.getFilesystemName(file2);
origfilename2 = multi.getOriginalFileName(file2);
}catch(Exception e){
e.printStackTrace();
}
%>
<html>
<body>
<form name="filecheck" action="fileCheck.jsp" method="post">
<input type="hidden" name="name" value="<%=name%>">
<input type="hidden" name="subject" value="<%=subject%>">
<input type="hidden" name="filename1" value="<%=filename1%>">
<input type="hidden" name="filename2" value="<%=filename2%>">
<input type="hidden" name="origfilename1" value="<%=origfilename1%>">
<input type="hidden" name="origfilename2" value="<%=origfilename2%>">
</form>
<a href="#" onclick="javascript:filecheck.submit()">업로드 확인 및 다운로드 페이지 이동</a>
</body>
</html>
Upload.jsp를 만든다.
처음에 만든 HTML 폼에서 전송을하면 아까 만들어둔 서버 경로의 upload에 파일들이 올라간다.
여기서 tmp2는 컴퓨터마다 다르다.
전송을 누르면 이동하는 페이지
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String subject = request.getParameter("subject");
String filename1 = request.getParameter("filename1");
String filename2 = request.getParameter("filename2");
String origfilename1 = request.getParameter("origfilename1");
String origfilename2 = request.getParameter("origfilename2");
%>
<html>
<head>
<title>파일 업로드 확인 및 다운로드</title>
</head>
<body>
올린 사람 : <%=name %><br>
제목 : <%=subject %><br>
파일명1 : <a href="file_down.jsp?file_name=<%=filename1 %>"><%=origfilename1 %></a><br>
파일명2 : <a href="file_down.jsp?file_name=<%=filename2 %>"><%=origfilename2 %></a><p>
</body>
</html>
예제에서는 순서대로 되었지만
현재는 순서가 바뀌어서 거꾸로 꺼내는 모양이다.
<%@page import="java.net.URLEncoder"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.io.File" %>
<%@page import="java.io.*" %>
<%
String fileName = request.getParameter("file_name");
String savePath = "upload";
ServletContext context = getServletContext();
String sDownloadPath = context.getRealPath(savePath);
String sFilePath = sDownloadPath + "\\"+fileName;
byte b[] = new byte[4096];
FileInputStream in = new FileInputStream(sFilePath);
String sMimeType = getServletContext().getMimeType(sFilePath);
System.out.println(sMimeType);
String agent = request.getHeader("User-Agent");
boolean isBrowser = (agent.indexOf("MSIE") > -1) || (agent.indexOf("Trident") > -1);
if(isBrowser){
fileName = URLEncoder.encode(fileName,"UTF-8").replaceAll("\\+","%20");
} else {
fileName = new String(fileName.getBytes("UTF-8"),"iso-8859-1");
}
response.setHeader("Content-Disposition", "attachment; filename="+fileName);
ServletOutputStream out2 = response.getOutputStream();
int numRead;
while((numRead = in.read(b, 0, b.length)) != -1){
out2.write(b,0,numRead);
}
out2.flush();
out2.close();
in.close();
%>
사진(프로필) 업로드 만들기
로그인 하였을때 navbar에 추가될 프로필 기능
principal은 로그인되면 생성된다.
content-between -> 개구리 공부
정렬 방법은 여러개인데 기능은 비슷하므로 한번 알아두면 편하다.
프로필 사진을 누르면 프로필 설정으로 이동한다.
border-radius 값을 크기의 절반으로 하면 둥근이미지가 된다.
0px
10px
20px
오늘 추가된 컨트롤러의 분기들
밑의 jsp로 이동하는 Action
프로필을 누르면 이동하는 화면을 만든다.
d-flex를 주면 안에 포함된 div들은 block에서 inline으로 바뀐다.
enctype을 지정해줘야 한다.
multipart/form-data
onerror는 src가 없거나 오류가 뜨면 기본 이미지로 바꿔준다.
기본 이미지
form이 이 여백을 만들어준다.
전송할때 name은 정확하고 id는 여기에 파일을 올렸을때 미리보기를 위해서 설정한다.
이때 img_preview
img__preview의 차이를 알아야한다.
Proc에서 id값을 쓸것이라 hidden에 숨겨서 전송할때 같이 날린다.
imgPreview.js
바인딩, 비동기
jsp에서 설정되었던 id값을 여기서 사용한다.
해당 id를 가진것이 "change"를 할때까지 리스너처럼 계속 보고 있다.
현재는 파일을 하나만 받기 때문에 for문이 없지만 여러개 받기 시작하면
for문으로 찾는다.
여기 들어온 파일의 type을 확인한다. 방법은 2가지
순서가 제일 중요한 부분이다.
파일의 크기가 얼마나 크고 작은지 모르기때문에 CPU에게 일의 처리를 맡기면
파일이 업로드 되는동안 홈페이지는 멈추게 된다.
그래서 비동기로 처리하게 되는데
reader의 로드(파일 업로드)가 끝나야 result가 만들어진다.
이 완료되는 타이밍을 잡는게 제일 힘들지만
이미 함수가 만들어져 있다.
reader.onload를 이용하면 result가 만들어지는 타이밍을 잡을 수 있다.
즉, img__wrap라는 id를 가진곳에 src 속성을 추가한다.
값은 e.target.result(밑)
그리고 onload를 reader보다 위에 올려놓는 이유는
정말 적은 경우겠지만 파일의 용량이 작아서 빠르게 처리될 경우
위와 같이 순서를 해놨다면
CPU가 다음 라인을 읽기전에 처리가 되면
해당 onload는 실행이 안된다.
그래서 위에 올려놓는게 맞다.
realPath는 서버에 실행되어서 이미지가 저장된곳
contextPath는 프로젝트 위치
request - form에서 전달된 파라미터값을 얻기 위해 객체를 지정해주는 것
realPath - 내서버위치
1024*1024*2 - size : 해당크기를 넘기면 Exception이 발생한다.
"UTF-8" - enc - 파일 이름이 한글일 경우 문제되지 않도록 처리함
new DefaultFileRenamePolicy() - 파일명이 겹칠 수 있어서 알아서 변경 해준다.
-> 비슷한 UUID가 있다.
화살표와 같이 미리보기에 들어있는 사진의 이름을 가져온다.
여기서 받는 id값은 hidden에 숨겨져 온 id값이다.
userProfile은 db에 저장될 값이다.
contextPath = /blog/image/+fileName
사진이 변경이 완료되면
세션의 principal을 갱신하고 index로 이동
실패하면 history.back을 한다.
숙제, 용량 넘어가면 업로드 못하게 하기
UUID - 범용 고유 식별자
36개 문자 32개의 문자와 4개의 하이픈
8-4-4-4-12 5개의 그룹
https://ko.wikipedia.org/wiki/%EB%B2%94%EC%9A%A9_%EA%B3%A0%EC%9C%A0_%EC%8B%9D%EB%B3%84%EC%9E%90
'JSP' 카테고리의 다른 글
stateful과 stateless (0) | 2020.08.07 |
---|---|
SHA256.java (0) | 2020.07.18 |
쇼핑몰 사이트 jsp 모델2 프로젝트 준비 (0) | 2020.06.22 |
hub에서 clone하고 WebContent파일들마다 <@ 부분 오류 (0) | 2020.06.22 |
블로그 카카오 로그인 (0) | 2020.06.17 |