JSP_이미지_게시판
보드 안에 여러개 파일이 들어가면
보드(부모) 파일(자식)fk외부키: boardId ->boardId가 pk로 들어갈 필요없음.
**사진저장 원리**
: 사진->DB에 저장한다면 ->사진에 대한 경로가 들어간다.
: 파일이 DB자체에 들어가는게 아니라 파일저장소의 경로(+파일이름)가 들어간다.
: 파일을 받으면 파일 저장소(서버/폴더)에 원본파일 복사가 이루어진다.
: 파일저장소에 변경된 이름으로 들어간다.
ex)
사진을 카톡으로 보내면 다른사람들도 다 다운받을 수 있다.
카톡에 사진보내고 내폰에 있는 이미지 지운경우 카톡방에 있는 사진을 다시 필요하면 다시 다운받는다.
<이미지 게시판 폼을 뷰로 전달한다>
@WebServlet("/writerThumForm.th")
public class WriterThumbForm extends HttpServlet {
private static final long serialVersionUID = 1L;
public WriterThumbForm(){
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOEception {
request.getRequestDispatcher("WEB-INF/views/thumbnail/thumbnailWriteForm.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
<뷰에 보여줄 폼을 작성>
thumbnailWriteForm.jsp 작성
<form action="<%= request.getContextPath() %>/insert.th" method="post" edType="multipart/form-data">
encType = "multipart/form-data" : 파일을 보낼 때 필수적으로 인코딩 타입지정이 필요하다.
파일 전송을 위한 코드
<폼의 스트립트>
<script>
// 내용 작성 부분의 공간을 클릭할 때 파일 첨부 창이 뜨도록 설정하는 함수
$(function(){
$("#fileArea").hide();
$("#titleImgArea").click(function(){
$("#thumbnailImg1").click();
});
$("#contentImgArea1").click(function(){
$("#thumbnailImg2").click();
});
$("#contentImgArea2").click(function(){
$("#thumbnailImg3").click();
});
$("#contentImgArea3").click(function(){
$("#thumbnailImg4").click();
});
});
// 각각의 영역에 파일을 첨부 했을 경우 미리 보기가 가능하도록 하는 함수
function LoadImg(value, num){
if(value.files && value.files[0]){//파일이 존재한다면 실행해라->여러개 선택해도 그중에 첫번째 사진만 들어간다.
var reader = new FileReader();
reader.onload = function(e){
switch(num){
case 1:
$("#titleImg").attr("src", e.target.result);
break;
case 2:
$("#contentImg1").attr("src", e.target.result);
break;
case 3:
$("#contentImg2").attr("src", e.target.result);//이미지에 대한 사진을 보여줌(경로X)
break;
case 4:
$("#contentImg3").attr("src", e.target.result);
break;
}
}
reader.readAsDataURL(value.files[0]);//가장 앞에 있는 사진 경로 데이터url로 읽어준다.
}
}
</script>
: 내용 작성 부분의 공간을 클릭할 때 파일 첨부 창이 뜨도록 설정하는 함수가 필요하다!
: 파일이 존재한다면 실행하라 -> 여러 개 선택해도 그 중 첫번째 사진만 들어간다.
<파일 이름을 오늘날짜시간으로 변경해서 가져오기>
package common;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.oreilly.servlet.multipart.FileRenamePolicy;
public class MyFileRenamePolicy implements FileRenamePolicy{
@Override
public File rename(File originFile) { //MyFileRenamePolicy를 오버라이딩 해준다. //implements
long currentTime = System.currentTimeMillis();
int ranNum = (int)(Math.random() * 10000);
String name = originFile.getName();//파일 이름
String ext = null;//확장자
int dot = name.lastIndexOf(".");//가장 마지막에 있는 .에 대한 인덱스를 가지고 와라
if(dot == -1) {
ext = "";
} else {
ext = name.substring(dot);//.PNG라고 나온다.(확장자)
}
SimpleDateFormat sdf = new SimpleDateFoemat("yyyyMMddHHmmssSSS");
String fileName = sdf.format(new Date(currentTime)) + ranNum + ext;
File newFile = new File(originFile.getParent(), fileName);
//파일이 만들어지면 바꿔준 이름으로 fileName만들어 줘서 그 상태로 return newFile에 저장
return newFile;
}
}
1. originFile.getName을 통해 파일 이름을 가져와서 name변수에 넣어준다.
2. name.lastIndexOf(".")를 통해 가져온 파일의 .에 대한 인덱스를 가지고 와서
인덱스 -1가 아니면, substring(.에 대한 인덱스)를 넣어서 파일 확장자를 가져온다.
3. new SimpleDateFormat()을 통해 오늘 날짜로 파일명을 설정한다.
4. 3번에서 담은 sdf를 .format(new Date(currentTime)) + ranNum + ext;를 fileName에 담아서
파일이 생성 되는 동시에 바뀐 이름으로 fileName을 만들어줘서 그 상태가 바로 return newFile에 저장반환한다.
@WebServlet("/insert.th")
public class InsertThumbnailServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public InsertThumbnailServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
// String title = request.getParameter("title");
// System.out.println(title);
// encType="multipart/form-data" 인코딩지정때문에 getParameter("title"); title 값을 가져올 수 없다.
// ==> MultipartRequest
if(ServletFileUpload.isMultipartContent(request)) {// multipart/form-data로 전송되었는지 확인
// MultipartRequest 객체 사용법
// MultipartRequest multiRequest = new MultipartRequest(HttpServletRequest, 파일저장소 경로, 파일 최대 크기, 인코딩 타입, 파일 명 변환 규칙);
// 파일 명 변환 규칙에 사용되는 기본 클래스 : DefaultFileRenamePolicy
// 같은 이름의 파일이 존재하면 파일 명 뒤에 숫자 붙임 ex) aaa.png, aaa1.png, aaa2.png
int maxSize = 1024*1024*10; //10Mbyte
String root = request.getSession().getServletContext().getRealPath("/");// /:WebContent아래를 말하는것
String savePath = root + "thumbnail_uploadFiles/";
File f = new File(savePath);
if(!f.exists()) {
f.mkdirs();
}
// System.out.println(savePath); //C:\5_Servlet_workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp2\wtpwebapps\3_JSPServlet\thumbnail_uploadFiles/
// cos.jar 라이브러리 필요
MultipartRequest multiRequest = new MultipartRequest(request, savePath, maxSize, "UTF-8", new MyFileRenamePolicy());
//따로 규약을 넣지 않으면 new DefaultFileRenamePolicy()를 가져와서 쓰면된다. import 확인해보면 cos.jar를 사용햇는지 알 수 있다
//파일저장소에 저장이 되는 것 이다.
String title = multiRequest.getParameter("title");
String content = multiRequest.getParameter("content");
String writer = ((Member)request.getSession().getAttribute("loginUser")).getUserId();
ArrayList<String> saveFiles = new ArrayList<String>(); //파일의 바뀐 이름을 저장할 ArrayList
ArrayList<String> originFiles = new ArrayList<String>(); //파일의 원래 이름을 저장할 ArrayList
Enumeration<String> files = multiRequest.getFileNames();// input type="file"의 name값 반환값 Enumaratioin
while(files.hasMoreElements()) {
// System.out.println(files.nextElement());//name속성값의 Parameter명 나옴 thumbnailImg4/thumbnailImg3/thumbnailImg2/thumbnailImg1
String name = files.nextElement(); //전송 순서 역순
if(multiRequest.getFilesystemName(name) != null) {
saveFiles.add(multiRequest.getFilesystemName(name));//바뀐이름의 파일명
originFiles.add(multiRequest.getOriginalFileName(name));//원래 이름의 파일명
}
}
Board b = new Board();
b.setBoardContent(content);
b.setBoardTitle(title);
b.setBoardWriter(writer);
b.setBoardType(2);
b.setCategory("10");//카테고리 인설트보드 그대로 활용할 것이다(쿼리) 임의로 10을 넣어줌
ArrayList<Attachment> fileList = new ArrayList<>();
for(int i = originFiles.size() -1; i >= 0; i--) {//파일이 역순이어서 for문도 역순으로 씀.
Attachment a = new Attachment();
a.setFilePath(savePath);
a.setOriginName(originFiles.get(i));
a.setChangeName(saveFiles.get(i));
if(i == originFiles.size() -1) {//썸네일 /역순으로 들어오니까 -1을 해서
a.setFileLevel(0);
} else {
a.setFileLevel(1);
}
fileList.add(a);
}
int result = new BoardService().insertFile(b, fileList);
if(result == fileList.size() +1) {//잘들어갔다는 전제하에 +1과 같다면 진행
response.sendRedirect("list.th");
}else {
request.setAttribute("msg", "사진게시판 등록에 실패하였습니다.");
request.getRequestDispatcher("WEB-INF/views/common/errorPage.jsp").forward(request, response);
for(int i = 0; i < saveFiles.size(); i++) {
File failFile = new File(savePath + saveFiles.get(i));
failFile.delete();
}
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
MultipartRequest multiRequest = new MultipartRequest(HttpServletRequest, 파일저장소 경로, 파일 최대 크기, 인코딩 타입, 파일 명 변환 규칙);
: 파일 명 변환 규칙에 사용되는 기본 클래스 : DefaultFileRenamePolicy
: 같은 이름의 파일이 존재하면 파일 명 뒤에 숫자 붙임 ex) aaa.png, aaa1.png, aaa2.png