23.05.01

이준영·2023년 5월 1일
0
웹페이지

하드코딩 : .jsp
    
(mvc = model view controller)model1
	.jsp + class(java)
    client ---> jsp ---> model(요청 데아터 처리, DAO/TO) ---> 데이터(db/file/다른 어떤 것)
    controller(요청제어)
  	view(보여줌)

(mvc = model view controller)model2

프로젝트( 프로토 타입으로 하드코딩부터 시작하여 점차 모델2까지 나아가기 )



파일 업로드 기초

  1. 라이브러리
  2. 업로드 경로
  • 파일명 / 경로 등.. -> 데이터베이스 입력(이모티콘 처럼 파일 자체가 들어가는 것이 아님)



파일 업로드 과정


1. 프로젝트 생성 후 servlets에서 library 다운 -> cos.jar 파일 lib에 넣기


2. webapp에 폴더 하나 생성


3. .jsp 생성하여 form 만들어주기

ex>
<form action="./upload_ok.jsp" method="post" enctype="multipart/form-data">

파일 규정 기본 - 메서드는 포스트로 / enctype 해주기


파일 업로드를 위한 기본 형태(틀)


현재 파일 선택하면 파일 명 뜨기만 가능!


4. upload1_ok.jsp 작업하기

3가지 미리 정해야 함
1. 업로드 경로 - 절대경로
2. 업로드 제한 용량 정하기
3. 인코딩 정보 (보통 utf-8)
4. 전부 MultipartRequest 타입 변수 생성해서 넣어주기

*파일 경로 찾기

upload1_ok.jsp 코드

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy" %>
<%@ page import="com.oreilly.servlet.MultipartRequest" %>

<%
	// 3가지 미리 정해야 함
	// 1. 업로드 경로 - 절대경로
	// 2. 업로드 제한 용량 - byte 단위
	// 3. 인코딩 정보
	
	// /로 바꿔주기
	String uploadPath = "C:/Java/jsp-workspace/UploadEx1/src/main/webapp/upload";
	int maxFileSize = 4 * 1024 * 1024; // 2MB
	String encType = "utf-8";
	
	MultipartRequest multi = new MultipartRequest(request, uploadPath, maxFileSize, encType,
    new DefaultFileRenamePolicy());
	
	out.println("전송 완료");
%>

각 요소 확인

maxFileSize - 파일 경로 넘어가면 에러

new DefaultFileRenamePolicy() - 파일 업로드시 중복되지 않게 처리하게 하기 위하여 써주는 것


중복시 숫자가 하나씩 늘어나서 중복 방지하는 모습!


5. 확인

파일 선택 후 업로드 버튼 누르면 전송완료가 뜨고, 이클립스 가서 폴더 새로고침하면 안에 들어가져있는 모습 확인
(새로고침은 이클립스에서만 그렇고 실제 보여지는 곳에서는 바로바로 들어가진다)




파일명 구하기 : fileSystemName / OriginalFileName

fileSystemName = 올라간 파일명(현재 업로드되어 지어진 파일명을 의미)
OriginalFileName = 원래 올렸던 파일명

// upload.jsp의 input type="file"의 name이 인자로 들어감)
	out.println("파일명 : " + multi.getFilesystemName("upload1") + "<br>");
	out.println("파일명 : " + multi.getOriginalFileName("upload1"));


File 객체 사용하여 크기 구하기

	// File 객체를 사용하여 크기 구하기
	java.io.File file = multi.getFile("upload1");
	// byte단위로 보여줌(long으로 return)
	out.println("사이즈 : " + file.length() + "<br>");


여러 개 업로드하기

기존과 다른 건 없고 하나씩 더 써주면 된다.

upload.jsp

<form action="./upload1_ok2.jsp" method="post" enctype="multipart/form-data">
파일 <input type="file" name="upload1" /><br><br>
파일 <input type="file" name="upload2" /><br><br>
<input type="submit" value="파일업로드" />
</form>

upload1_ok2.jsp

<%@ page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy" %>
<%@ page import="com.oreilly.servlet.MultipartRequest" %>

<%
	
	// /로 바꿔주기
	String uploadPath = "C:/Java/jsp-workspace/UploadEx1/src/main/webapp/upload";
	int maxFileSize = 2 * 1024 * 1024; // 2MB
	String encType = "utf-8";
	
	MultipartRequest multi = new MultipartRequest(request, uploadPath, maxFileSize, encType, new DefaultFileRenamePolicy());
	
	out.println("전송 완료<br>");
	// upload.jsp의 input type="file"의 name이 인자로 들어감)
	out.println("파일명 : " + multi.getFilesystemName("upload1") + "<br>");
	out.println("파일명 : " + multi.getOriginalFileName("upload1") + "<br>");
	
	out.println("파일명 : " + multi.getFilesystemName("upload2") + "<br>");
	out.println("파일명 : " + multi.getOriginalFileName("upload2") + "<br>");
%>


텍스트와 같이 업로드

upload.jsp


<form action="./upload1_ok3.jsp" method="post" enctype="multipart/form-data">
파일 <input type="file" name="upload1" /><br><br>
아이디 <input type="text" name="id" /><br><br>
비밀번호 <input type="password" name="password" /><br><br>
<input type="submit" value="파일업로드" />
</form>

upload1_ok3.jsp

	MultipartRequest multi = new MultipartRequest(request, uploadPath, maxFileSize, encType,
    new DefaultFileRenamePolicy());

out.println("전송 완료<br>");
	// upload.jsp의 input type="file"의 name이 인자로 들어감)
	out.println("파일명 : " + multi.getFilesystemName("upload1") + "<br>");
	out.println("파일명 : " + multi.getOriginalFileName("upload1") + "<br>");
	
    //request가 아닌 multi로
	out.println("아이디 : " + multi.getParameter("id") + "<br>");
	out.println("비밀번호 : " + multi.getParameter("password") + "<br>");

MultipartRequest에서 request를 받았기 때문에 request가 의미가 없어짐.
request -> multi로 바꿔줘야 함
또한 한글 변환도 multi안에 다 넣었기 때문에(encType) 따로 써줄 필요가 없다.



자료 첨부 가능한 게시판 만들기

1. 테이블 구성

기존 것에서 파일명 / 파일크기 컬럼 추가

create table pds_board ( 
seq int not null primary key auto_increment,
subject varchar(150) not null,
writer varchar(12) not null,
mail varchar(50),
password varchar(12) not null,
content varchar(2000),
filename varchar(50),
filesize int,
hit int not null,
wip varchar(15) not null,
wdate datetime not null); 


insert문 하나 준비
insert into pds_board values (0, '제목', '이름', 'test@test.com', '1234', '내용', 'test.txt', '0', '0', '000.000.000.000', now());

2. write 작업

write1.jsp

form에 enctype="multipart/form-data" 써주기

외 이전과 동일

write1_ok.jsp

request -> multi로 바꿔서 사용하기, 기존 sql에서 filename / filesize 추가하고 변수도 추가해주기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>

<%@ page import="javax.sql.DataSource" %>

<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.SQLException" %>

<%@ page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy" %>
<%@ page import="com.oreilly.servlet.MultipartRequest" %>
<%@ page import="java.io.File" %>

<%
	//
	String uploadPath = "C:/Java/jsp-workspace/Model1Ex2/src/main/webapp/upload";
	int maxFileSize = 2 * 1024 * 1024;
	String encType = "utf-8";
	
	MultipartRequest multi
	= new MultipartRequest(request, uploadPath, maxFileSize, encType, new DefaultFileRenamePolicy());
	
	//
	String subject = multi.getParameter("subject");
	String writer = multi.getParameter("writer");
	String mail = "";
	if(!multi.getParameter("mail1").equals("") && !multi.getParameter("mail2").equals("")) {
		mail = multi.getParameter("mail1") + "@" + multi.getParameter("mail2");
	}
	String password = multi.getParameter("password");
	String content = multi.getParameter("content");
	
	String wip = request.getRemoteAddr();

	//input type에 적혀있는 name 가져오는 것!, 오리지널 이름 필요하면 추가하면 됨
	String filename = multi.getFilesystemName("upload");
	
	long filesize = 0;
	
	// 업로드 되었다면
	if(multi.getFile("upload") != null) {
		//해당 파일 사이즈 얻음
		filesize = multi.getFile("upload").length();
	}
	
	//
	Connection conn = null;
	PreparedStatement pstmt = null;
	
	int flag = 1;
	
	try { 
		Context initCtx = new InitialContext();
		Context envCtx = (Context)initCtx.lookup("java:comp/env");
		
		DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb3");
		
		conn = dataSource.getConnection();
		
		String sql = "insert into pds_board values (0, ?, ?, ?, ?, ?, ?, ?, 0, ?, now())";
		
		pstmt = conn.prepareStatement(sql);
		
		pstmt.setString(1, subject);
		pstmt.setString(2, writer);
		pstmt.setString(3, mail);
		pstmt.setString(4, password);
		pstmt.setString(5, content);
		pstmt.setString(6, filename);
		pstmt.setLong(7, filesize); // long 타입이기 떄문
		pstmt.setString(8, wip);
		
		int result = pstmt.executeUpdate();
		
		if(result == 1) {
			flag = 0;
		}
		
	} catch(NamingException e) {
		System.out.println("[에러] : " + e.getMessage());		
	} catch(SQLException e) {
		System.out.println("[에러] : " + e.getMessage());
	} finally {
		if(pstmt != null) try { pstmt.close(); } catch(SQLException e) {} 
		if(conn != null) try { conn.close(); } catch(SQLException e) {} 			
}
	out.println("<script type=text/javascript>");
	if(flag == 0) {
		out.println("alert('글 쓰기 성공!')");
		out.println("location.href='board_list1.jsp'");
	}
	else {
		out.println("alert('글쓰기 실패')");		
		out.println("history.back()");	
	}
	out.println("</script>");


%>


3. list 작업

sql에 filesize or filename 추가(둘 중 하나만, 아이콘 추가 용도)

(여기선 filesize로 비교, 문자열비교냐 정수냐 차이임)

sql에 filesize 추가하고

long filesize = rs.getLong("filesize");

디자인 부분 

sbHtml.append("<td>");
			if(filesize != 0) {
				sbHtml.append("<img src='../../images/icon_file.gif' />");
			}
			sbHtml.append("</td>");

써주기, 그 외 동일


4. view 작업

기존과 다른 것은 없고 filename과 filesize만 추가

  • file이 없을 때 null이 나오는 것을 방지하기 위해 file 변수 하나를 생성해서 조건문
    ( + 링크 누르면 다운받게 하는 거 까지)
1. 선언
	String filename = "";
	long filesize = 0;
	String file = "";
    
    
2. if(rs.next()) 쪽 선언
filename = rs.getString("filename");
			 filesize = rs.getLong("filesize");
			 
			 //파일이 없으면 안 나오고 있으면 나옴
			 if(filesize != 0) {
				 //링크를 걸어 클릭시 다운로드 할 수 있게 만들어줌(이때 경로는 상대경로)
				 file = "<a href='../../upload/" + 
                 filename + "'>" + filename + "</a>(" + filesize + " byte)";
			 }


여기선 filname + filesize가 아닌 file을 넣어준다! ( 파일이 첨부되어 있으면 file에 다 들어가므로)


파일이 없을 때 공백


누르면 다운로드 됨 (항상 글쓰기 성공하면 이클립스에선 새로고침 해야함!! 그래야 다운로드 가능)

tip : 이미지는 다운로드가 아닌 그냥 보여짐
* 다운로드 : 브라우저가 해석 가능한 파일이면 브라우저가 viewer가 된다.
--> 이것도 강제로 해서 다운로드 받기 가능

			해석 불가능한 파일은 다운로드됨
            
            일반적으로 텍스트 파일이나 이미지는 브라우저가 보여줌
        

4. delete 작업

delete1.jsp는 기존과 동일

delete1_ok.jsp

기존과 변동점

1. 파일 경로 지정
2. 파일 이름 얻기 위해 select구문 사용(resultset import)
3. 비밀번호가 정상인 경우에 -> 파일 경로, 이름을 파일 객체에 넣어서 파일 삭제
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>

<%@ page import="javax.sql.DataSource" %>

<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>

<%@ page import="java.io.File" %>

<%
	request.setCharacterEncoding("utf-8");
	
	String seq = request.getParameter("seq");
	String password = request.getParameter("password");
	
	String uploadPath = "C:/Java/jsp-workspace/Model1Ex2/src/main/webapp/upload";
	
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	
	int flag = 2;
	
	try {
		Context initCtx = new InitialContext();
		Context envCtx = (Context)initCtx.lookup("java:comp/env");
		DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb3");
		
		conn = dataSource.getConnection();
		
		
		//파일이름 얻기
		String sql = "select filename from pds_board where seq = ? ";
		
		pstmt = conn.prepareStatement(sql);
		
		pstmt.setString(1, seq);
		
		rs = pstmt.executeQuery();
		
		String filename = null;
		if(rs.next()) {
			//반드시 비밀번호가 맞을 경우에 지워야 함! flag = 0 일 때
			filename =rs.getString("filename");
		}
		
		sql = "delete from pds_board where seq = ? and password = ?";
		
		pstmt = conn.prepareStatement(sql);
		
		pstmt.setString(1, seq);
		pstmt.setString(2, password);
		
		int result = pstmt.executeUpdate();
		
		if(result == 1) {
			flag = 0;
			
			//비밀번호가 정상인 경우 삭제
			if(filename != null) {
				//해당 경로의 이름을 받아서 지움
				File file = new File(uploadPath, filename);
				file.delete();
			}
		}
		else if(result ==0) {
			flag = 1;
		}
		
	} catch(NamingException e) {
		System.out.println("[에러] : " + e.getMessage());		
	} catch(SQLException e) {
		System.out.println("[에러] : " + e.getMessage());
	} finally {
		if(rs != null) try { rs.close(); } catch(SQLException e) {} 
		if(pstmt != null) try { pstmt.close(); } catch(SQLException e) {} 
		if(conn != null) try { conn.close(); } catch(SQLException e) {} 			
}

	
	out.println("<script type=text/javascript>");
	if(flag == 0) {
		out.println("alert('삭제 성공!')");
		out.println("location.href='board_list1.jsp'");
	}
	else if(flag == 1) {
		out.println("alert('비밀번호 오류')");		
		out.println("history.back()");	
	} else {
		out.println("alert('삭제 실패')");		
		out.println("history.back()");	
	}
	out.println("</script>");
%>

5. modify 작업

modify1.jsp

기존과 다른 점은 기존의 filename명을 띄워야 한다는 점과 file 첨부되지 않았을 때 null로 나오지 않게끔 해주는 것이다.

modify1_ok.jsp

1. 새로운 첨부파일이 있는 경우
	- 기존 첨부 파일이 있는 경우 : 첨부 파일 삭제
    - 기존 첨부 파일이 없는 경우 : X
    
 -->   update 테이블명 set ... filename = ?, filesize = ? <- where을 통해 업데이트 시켜야 
    
2. 새로운 첨부파일이 없는 경우 : X

 -->   update 테이블명 set ... where ... (위랑 같이 쓰면 공백이 되어버림)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context"  %>
<%@ page import="javax.naming.InitialContext"  %>
<%@ page import="javax.naming.NamingException"  %>

<%@ page import="javax.sql.DataSource" %>

<%@ page import="java.sql.Connection"  %>
<%@ page import="java.sql.PreparedStatement"  %>
<%@ page import="java.sql.ResultSet"  %>
<%@ page import="java.sql.SQLException" %>

<%@ page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy" %>
<%@ page import="com.oreilly.servlet.MultipartRequest" %>
<%@ page import="java.io.File" %>

<%
	//파일 업로드 준비
	String uploadPath = "C:/Java/jsp-workspace/Model1Ex2/src/main/webapp/upload";
	int maxFileSize = 8 * 1024 * 1024;
	String encType = "utf-8";
	
	MultipartRequest multi = new MultipartRequest(request, uploadPath, maxFileSize, encType, new DefaultFileRenamePolicy());

	//
	String seq = multi.getParameter("seq");
	
	String subject = multi.getParameter("subject");
	
	String mail = "";
	if(!multi.getParameter("mail1").equals("") && !multi.getParameter("mail2").equals("")) { 
		mail = multi.getParameter("mail1") + "@" + multi.getParameter("mail2");
	}
	
	String password = multi.getParameter("password");
	
	String content = multi.getParameter("content");
	
	String filename = multi.getFilesystemName("upload");
	
	long filesize = 0;
	
	// 업로드 되었다면
	if(multi.getFile("upload") != null) {
		//해당 파일 사이즈 얻음
		filesize = multi.getFile("upload").length();
	}
	
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	
	int flag = 2;
	
	try {
		Context initCtx = new InitialContext();
		Context envCtx = (Context)initCtx.lookup("java:comp/env");
		
		DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb3");
		
		conn = dataSource.getConnection();
		
        //파일 이름 얻기
		String sql = "select filename from pds_board where seq = ?";
		
		pstmt = conn.prepareStatement(sql);
		
		pstmt.setString(1, seq);
		
		rs = pstmt.executeQuery();
		
        
		String oldFilename = null;
		
		//기존 파일명 가지고 오기
		if(rs.next()) {
			oldFilename = rs.getString("filename");
		}
		
		if(filename != null) {
			sql = "update pds_board set subject = ?, mail = ?, content = ?, filename = ?, filesize =? where seq = ? and password = ?";
			
			pstmt = conn.prepareStatement(sql);
		
		
			pstmt.setString(1, subject);
			pstmt.setString(2, mail);
			pstmt.setString(3, content);
			pstmt.setString(4, filename);
			pstmt.setLong(5, filesize);
			pstmt.setString(6, seq);
			pstmt.setString(7, password);
		}
		else {
			sql = "update pds_board set subject = ?, mail = ?, content = ? where seq = ? and password = ?";
		
			pstmt = conn.prepareStatement(sql);
		
		
			pstmt.setString(1, subject);
			pstmt.setString(2, mail);
			pstmt.setString(3, content);
			pstmt.setString(4, seq);
			pstmt.setString(5, password);
		}
		
		int result = pstmt.executeUpdate();
		
		if(result == 0) {
			flag = 1;
			
			if(filename != null) {
				//비밀번호가 잘못되었을때 올릴 새 파일 삭제
				File file = new File(uploadPath, filename);
					file.delete();
			}
		}
		else if(result == 1) {
			flag = 0;
			
			if(filename != null && oldFilename != null) {
				//성공시 기존 파일 삭제
				File file = new File(uploadPath, oldFilename);
					file.delete();
			}
		}
		
	} catch(NamingException e) {
		System.out.println("[에러] : " + e.getMessage());		
	} catch(SQLException e) {
		System.out.println("[에러] : " + e.getMessage());
	} finally {
		if(rs != null) try { rs.close(); } catch(SQLException e) {} 
		if(pstmt != null) try { pstmt.close(); } catch(SQLException e) {} 
		if(conn != null) try { conn.close(); } catch(SQLException e) {} 			
	}
	
	//jsp코드로 자바스크립트로 만들기 위함
			out.println("<script type='text/javascript'>");
			if(flag == 0) {
				out.println("alert('수정 성공')");
				//modify 창으로 가기
				out.println("location.href='board_view1.jsp?seq=" + seq + "';");
			}
			else if(flag ==1) {
				out.println("alert('비밀번호 오류')");		
				out.println("history.back()");
			}
			else {
				out.println("alert('글 수정 실패')");		
				out.println("history.back()");		
			}
			out.println("</script>");
%>
첨부 파일 있는 상태에서 수정할 경우 -> 
	첨부 파일 있을 때 첨부 파일을 수정한 경우 : 기존 파일 삭제되고 수정한 파일이 첨부됨
	첨부 파일 있을 때 텍스트만 수정한 경우 :  텍스트만 수정
    첨부 파일 있을 때 둘 다 수정한 경우 : 둘 다 수정
    
첨부 파일 없는 상태에서 수정할 경우 ->
	첨부 파일 추가한 경우 -> 추가
    텍스트만 -> 텍스트만 추가
    둘 다 - > 둘 다 추가
profile
끄적끄적

0개의 댓글