spring mvc 에서 파일 업로드 다운로드 하는 방법!

 

 

1. 파일 업로드

 

1-1 라이브러리 추가 (pom.xml에 추가)

commons-fileupload, commons-io.jar 추가하기 

 

		<!-- 파일업로드용 라이브러리 2개 추가 -->
		<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
		<dependency>
		    <groupId>commons-fileupload</groupId>
		    <artifactId>commons-fileupload</artifactId>
		    <version>1.4</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
		<dependency>
		    <groupId>commons-io</groupId>
		    <artifactId>commons-io</artifactId>
		    <version>2.6</version>
		</dependency>

1-2 MultipartResolver 추가 (root-context.xml)

	<!--  파일 업로드 -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="-1"></property>  <!-- '-1' 은 파일크기 무제한 -->
		<property name="defaultEncoding" value="UTF-8"></property>
	</bean>

 

 

1-3 파일 업로드 view(jsp) 작업 

 

간단하게 파일 uploadForm과  uploadPro 만들고

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>uploadform</title>
</head>
<body>

	<h2> File Upload</h2>  //post!! multipart 로 보내기!!
	<form action="/upload/uploadPro" method="post" enctype="multipart/form-data">
		message : <input type="text" name="msg" /> <br/>
		file 	: <input type="file" name="img" /> <br/>
		message : <input type="submit" value="전송" /> <br/>
	</form>

</body>
</html>



-------------------------------------------------------------------------------
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>upload Pro</title>
</head>
<body>

</body>
</html>

 

 

 

1-4 파일 업로드 컨트롤러 작업 

 

 파일업로드 작업
MultipartHttpServletRequest 인터페이스

* 주요 메서드
Iterator<String>  getFileNames() : 업로드된 파일들의 파라미터 명 리턴
MultipartFile getFile(String name) : 파라미터명이 name인 파일 리턴
List<MultipartFile> getFiles(String name) : 파라미터명이 name인 업로드 파일 정보 목록 리턴

* 작업 순서
- 처리 매핑 메서드에 매개변수 MultipartHttpServletRequest 지정
- request에서 파일 정보 꺼내담기
- 파일 저장 경로 + 새파일명 만들어 File 객체 만들기 (파일 이름 중복 안되게)
- .transferTo() 메서드로 파일 저장

package com.board.controller;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import lombok.extern.log4j.Log4j;

@Controller
@RequestMapping("/upload/*")
@Log4j
public class UploadController {
	
	@GetMapping("uploadForm")
	public void upload() {
		log.info("upload form!!!!!!!!!!!!!!");
	}
	
	@PostMapping("uploadPro")
	public void uploadPro(String msg, MultipartHttpServletRequest request) { // msg(text), img(file) 
		log.info("*********upload pro*************");
		log.info("********* msg : " + msg );
		//log.info("********* img content type : " + request.getContentType());
		//log.info("********* img : " + request.getFile("img")); // 파일 정보 꺼내기
		
		try {
			// 전송한 파일 정보 꺼내기
			MultipartFile mf = request.getFile("img");
			log.info("****************** original file name : " + mf.getOriginalFilename());
			log.info("****************** file size : " + mf.getSize());
			log.info("****************** file contentType: " + mf.getContentType());
			
			
			// 파일 저장 경로
			String path = request.getRealPath("/resources/save");
			log.info(" save path : "+ path);
			// 새파일명 생성
			String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();  // 하이픈 다 빼버림 대문자로
			log.info("***********uuid : " + uuid);
			// 업로드한 파일 확장자만 가져오기 
			String orgName= mf.getOriginalFilename();
			// beach.jpg   -> .jpg만 두고 나머지는 지움
			String ext = orgName.substring(orgName.lastIndexOf("."));
			
			// 저장할 파일명
			String newFileName = uuid + ext;
			log.info("*****new fileName : " + newFileName);
			
			//저장할 파일 전체 경로
			String imgPath = path + "\\" + newFileName;
			log.info("****imgPath : " + imgPath);
			
			
			// 파일저장
			File copyFile = new File(imgPath);
			mf.transferTo(copyFile);
			
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}

'WEB Creator > [Spring]' 카테고리의 다른 글

[Spring] Filter와 Interceptor의 차이점  (0) 2022.09.08
[Spring] @Controller와 @RestController  (0) 2022.08.31
[Spring] File Download  (0) 2022.08.25

1. 라이브러리 연동

 

https://code.jquery.com/jquery-3.6.0.min.js
https://cdnjs.com/libraries/jquery   - cdn 방식의 라이브럴
1- 다운받아 오프라인으로 작업
2- CDN방식으로 script 태그로 배치

 


2. 선택자 Selector


요소 선택 : $() 안에 문자형 데이터로 CSS 선택자 입력
ex. $("선택자").css("스타일속성명","값");
    $("선택자").attr("속성명","값"); align, tag등

기본 작성방법
#1. 문서 객체 먼저 불러와 선택자 사용 * 2번보단 1번 추천 (오류덜남)

<script>
    $(document).ready(function(){
   		 //jquery 작성 영역
   		 $("선택자").css("스타일속성명","값");
    });
</script>



#2. 즉시 함수로 묶기

    $(function(){
        //jquery 영역
    });

 

2 - 1 기본선택자

전체 선택자  $("*")
아이디 $("#아이디값")
클래스 $(".클래스값")
태그 $("태그명")
여러개 $("선택1, 선택2, 선택3....")
종속 $("태그명#아이디값")$("태그명.클래스값")$("h1.test.abc")
부모 $("선택").parent() .parents() 
하위 $("기준선택 요소선택")
자식 $("선택 > 자식")
  $("선택").children("자식")
형/동생 $("선택").prev() 형               .prevAll()
  $("선택").next() 동생          .nextAll()
  $("선택+ 요소")
전체 형제  $("선택").siblings()
가장 가까운 상위 $("선택").closest("요소")

 

 

2 - 2 속성선택자

선택한 요소를 기준으로 일치하는 속성의 포함여부를 따져 요소를 선택

 

$("선택[속성]")  선택요소중 지정한 속성이 포함된 요소 선택
$("선택[속성^=값]")  속성값이 지정한 값으로 시작하는 요소 선택 
$("선택[속성$=값]") 속성값이 지정한 값으로 끝나는 요소 선택
$("선택[속성*=값]") 속성값이 이러한 값으로 포함하는 요소 선택
$(":type 속성값") input태그 중 type 속성값이 일치하는 요소 선택
$("선택:visible") 보이는 상태의 요소만 선택
$("선택:hidden") 숨긴 상태의 요소만 선택
$("선택:selected") 선택된 상태의 요소만 선택
$("선택:checked") 체크된 상태의 요소만 선택

 

 

2 - 3 탐색선택자


$("선택").not(:제외요소)
$("선택").find(:"요소선택") : 기준으로 선택한 요소중 지정한 요소만 선택

DB 쿼리문을 돌려야하므로 테스트 실행불가

 

 

 

<form>
	<input type="text" name="u_id" />
	<input type="button" value="아이디 중복 확인" onclick="openConfirmId(this.form)"/>
 </form>
    
    
  <script>
    function openConfirmId(inputForm) {
	         if(inputForm.u_id.value == ""){
	            alert("아이디를 입력하세요.");
	            return;    // 이 함수 강제종료
	         }
	         // 검사 팝업 열기 
	         let url = "confirmId.jsp?u_id=" + inputForm.u_id.value;         
	         open(url, "confirmId", "width=300, height=200, toolbar=no, location=no, status=no, menubar=no, scrollbars=no, resizable=no"); 
	      }
  </script>

 

 

 

 

// confirmId.jsp



<%@page import="team.user.model.UserDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>아이디 중복확인</title>
</head>
<%
	request.setCharacterEncoding("UTF-8"); 
	// open(url...) : url = confirmId.jsp?u_id=값
	String u_id = request.getParameter("u_id");
	// DB 연결해서 사용자가 작성한 id값이 db테이블에 존재하는지 검사 
	UserDAO dao = new UserDAO(); 
	boolean result = dao.confirmId(u_id); // true 이미존재함, false 존재X -> 사용가능 
%>
<body>
<%
	if(result) { // true -> 이미 존재 -> 사용불가  %>
	<br />
	<table>
		<tr>
			<td><%= u_id%>은/는 이미 사용중인 아이디 입니다.</td>
		</tr>
	</table> <br />
	<form action="confirmId.jsp" method="post">
		<table>
			<tr>
				<td> 다른 아이디를 선택하세요. <br />
					<input type="text" name="u_id" /> 
					<input type="submit" value="아이디 중복확인" />
				</td>
			</tr>		
		</table>
	</form>
		
<%	}else { // false -> 존재 X -> 사용 가능 %>
	
	<br />
	<table>
		<tr>
			<td>입력하신 <%= u_id%>은/는 사용 가능합니다. <br />
				<input type="button" value="닫기" onclick="setU_id()" />
			</td>
		</tr>
	</table>
		
<%	}%>

	<script>
		function setU_id() {
			// 팝업을 열어준 원래 페이지의 id input태그의 value를
			// 최종 사용할 id로 변경. 
			opener.document.inputForm.u_id.value = "<%= u_id%>";
			// 현재 팝업 닫기. 
			self.close(); 
		}
	</script>
</body>
</html>
// DAO 쿼리문 매서드 


public boolean confirmId(String u_id) {
			boolean result = false;
			int u_idCount = 0;
			Connection conn = null; 
			PreparedStatement pstmt = null;
			ResultSet rs = null; 
			
			try {
				conn = getConnection(); 
				String sql = "select count(*) from signup where u_id=?";
				pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, u_id);
				rs = pstmt.executeQuery();
				if(rs.next()) {
					u_idCount = rs.getInt(1);
					System.out.println("u_idCount : " + u_idCount);
					if(u_idCount == 1) {
						result = true;
					}
				}

				
			}catch(Exception e) {
				e.printStackTrace();
			}finally {
				if(rs != null) try { rs.close();} catch(SQLException e) { e.printStackTrace(); }
				if(pstmt != null) try { pstmt.close();} catch(SQLException e) { e.printStackTrace(); }
				if(conn != null) try { conn.close();} catch(SQLException e) { e.printStackTrace(); }
			}
			
			return result;
		}

게시글, 회원가입할때 주로 사용하는 null alert 매서드

 

 

로그인 회원가입
아이디(필수기입)
비밀번호(필수기입)
비밀번호 확인(필수기입)

 

 

 

 

 

 

 <form action="signupPro.jsp" method="post" name="inputForm" enctype="multipart/form-data" onsubmit="return checkField();">
	      <table>
			<tr>
				<td onclick="window.location='loginForm.jsp'"> 로그인 </td>
				<td onclick="window.location='signupForm.jsp'"> <b>회원가입<b></b> </td>
			</tr>	      
	         <tr>
	            <td>아이디(필수기입)</td>
	            <td><input type="text" name="u_id" /> </td>
	         </tr>
	         <tr>
	            <td>비밀번호(필수기입)</td>
	            <td><input type="password" name="u_pw" /></td>
	         </tr>
	         <tr>
	            <td>비밀번호 확인(필수기입)</td>
	            <td><input type="password" name="u_pwck" /></td>
	         </tr>
 			<tr>
	            <td colspan="2">
	               <input type="submit" value="회원가입" /> 
	               <input type="reset" value="재작성" /> 
	               <input type="button" value="취소" onclick="window.location='/team/banner/main.jsp'" />
	            </td>
	         </tr>
	      </table>
   </form>



	<script>
		function checkField(){
			let inputs = document.inputForm;
			if(!inputs.u_id.value){	// name속성이 id인 요소의 value가 없으면 true
				alert("아이디를 입력하세요.");
				return false;	// pro페이지로 이동 금지.
			}
			if(!inputs.u_pw.value){	
				alert("비밀번호를 입력하세요.");
				return false;
			}
			if(!inputs.u_pwch.value){
				alert("비밀번호 확인란을 입력하세요.");
				return false;
			}		
			if(inputs.u_pw.value != inputs.u_pwch.value){
				alert("비밀번호가 일치하지 않습니다.");
				return false;
			}
		}
	</script>

	  
</body>
	</html>

체크박스 선택시 제출버튼 활성화

 

 

 

 

 

 

 

Insert title here
[필수] 체크해야 제출가능

 

 

 


<form action="#" method="#" name="#" enctype="multipart/form-data" onsubmit="#">
	<input type="checkbox" name="agreements" onClick="agreeCheck(this.form)"> [필수] 체크해야 제출가능
	<input type="submit"  name="checkButton" value="등록하기"  disabled/>
</form>

<script>
    function agreeCheck(frm){
               if (frm.checkButton.disabled==true)
                frm.checkButton.disabled=false
               else
                frm.checkButton.disabled=true
     }
</script>

 

 

여러개의 경우

https://codesandbox.io/s/agreement-l5uc6?file=/src/index.js

버튼에다가 alert만 띄우면 파라미터가 넘어가질 않는데

 

submit에 alert 효과 만들기

 

<form action="#">
	<input type="text"/>
	<input type="file"/>
    <input type="submit" value="수정하기" onClick='return confirmSubmit()'/>
</form> 
    
    
    <script>
		function confirmSubmit()
		{
		var agree=confirm("정말 수정하시겠습니까?");
		if (agree)
			return true ;
		else
			return false ;
		}
	</script>

 

 

 

 1. MultipartRequest 객체 생성시, 필요한 인자들
      1. request 내장 객체 (jsp에 이미 있다)
      2. 업로드 될 파일 저장 경로 
      3. 업로드 할 파일 최대 크기
      4. 인코딩 타입 : UTF-8
      5. 업로드된 파일 이름이 같을경우, 덮어씌우기 방지 객체
    

   2. 브라우저에서 보낸 파일 저장할 서버측의 저장 경로
    2-1. PC에 저장(서버쪽X, 서버가 있는 내PC에 저장)
   String path = "C:\\tmp\\"; (pc에 올리면 웹페이지상에서 볼수가없다 )
   
    2-2 서버상에 저장
   String path = request.getRealPath("save"); // 서버상의 save 폴더 실제 경로 찾기
   System.out.println(path);
   3. 업로드 할 파일 최대 크기
   int max = 1024*1024*5;   // 5mb
   4. 인코딩
   String enc = "UTF-8";
   5. 덮어씌우기 방지 객체
   DefaultFileRenamePolicy dp = new DefaultFileRenamePolicy();
   
   6. MultipartRequest 객체 생성
   MultipartRequest mr = new MultipartRequest(request, path, max, enc, dp);
   
   7. 파라미터 받기
   String writer = mr.getParameter("write");
   String sysName = mr.getFilesystemName("upload");   // 업로드 파일 이름
   String orName = mr.getOriginalFileName("upload");   // 파일 원본 이름
   String contentType = mr.getContentType("upload");   // 파일 종류 : 사진, 글....
   
   
   8.DB에 저장
   UploadDAO dao = new UploadDAO();
   dao.insertData(writer,sysName);
   
   
   

<title>image upload</title>
</head>
<body>
   <h1> form page </h1>
      <form action="upload.jsp" method="post" enctype="multipart/form-data">
         작성자 : <input type="text" name="write" /> <br />
         파  일 : <input type="file" name="upload" /> <br />
                <input type="submit" value="전송" />
      
      </form>

</body>
</html>

 

 

 

<title>upload pro</title>
</head>
<%
   request.setCharacterEncoding("UTF-8");
   /*  MultipartRequest 객체 생성시, 필요한 인자들.
   
      1. request 내장 객체 (jsp에 이미 있다)
      2. 업로드 될 파일 저장 경로 
      3. 업로드 할 파일 최대 크기
      4. 인코딩 타입 : UTF-8
      5. 업로드된 파일 이름이 같을경우, 덮어씌우기 방지 객체
      
      */

   // 2. 브라우저에서 보낸 파일 저장할 서버측의 저장 경로
   // 2-1. PC에 저장(서버쪽X, 서버가 있는 내PC에 저장)
   //String path = "C:\\tmp\\"; (pc에 올리면 웹페이지상에서 볼수가없다 )
   
   // 2-2 서버상에 저장
   String path = request.getRealPath("save"); // 서버상의 save 폴더 실제 경로 찾기
   System.out.println(path);
   // 3. 업로드 할 파일 최대 크기
   int max = 1024*1024*5;   // 5mb
   //4. 인코딩
   String enc = "UTF-8";
   // 5. 덮어씌우기 방지 객체
   DefaultFileRenamePolicy dp = new DefaultFileRenamePolicy();
   
   // MultipartRequest 객체 생성
   MultipartRequest mr = new MultipartRequest(request, path, max, enc, dp);
   
   // 파라미터 받기
   String writer = mr.getParameter("write");
   String sysName = mr.getFilesystemName("upload");   // 업로드 파일 이름
   String orName = mr.getOriginalFileName("upload");   // 파일 원본 이름
   String contentType = mr.getContentType("upload");   // 파일 종류 : 사진, 글....
   
   
   // DB에 저장
   UploadDAO dao = new UploadDAO();
   dao.insertData(writer,sysName);
   
   
   
%>
<body>

   <h2>작성자 : <%=writer%> </h2>
   <h2>업로드 파일명 : <%=sysName%></h2>
   <h2>파일 원본이름 : <%=orName%></h2>
   <h2>컨텐트 타입(파일종류) : <%=contentType%></h2>
	
	<img src="/web/save/<%=sysName%>" width="300px"/>
</body>
</html>

https://www.koreascience.or.kr/article/CFKO202133649045974.pdf

 

AI-based incident handling using a black box.pdf
0.65MB

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Insert title here</title>
	<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
	<br />
	<h1 align="center"> 메인 페이지 </h1>
	
	<% 
	if(session.getAttribute("memId") == null){ // 로그인 안했을때 
		
		// 쿠키가 있는지 검사 
		String id = null, pw = null, auto = null; 
		Cookie[] coos = request.getCookies(); 
		if(coos != null){
			for(Cookie c : coos) {
				// 쿠키가 있다면 쿠키에 저장된 값꺼내 변수에 담기
				if(c.getName().equals("autoId")) id = c.getValue();   
				if(c.getName().equals("autoPw")) pw = c.getValue();
				if(c.getName().equals("autoCh")) auto = c.getValue(); 
			}
		}
		
		// 세개 변수에 값이 들어있을 경우 (쿠키 제대로 생성되서 다 갖고 있다.)
		if(auto != null && id != null && pw != null){
			// 로그인 처리되도록 loginPro.jsp 처리 페이지로 이동시키기 
			response.sendRedirect("loginPro.jsp");
		}
		
		// 위 코드 다 지나치면, 
		// session에 memId속성도 없고, 쿠키도 없으니 로그인 버튼 보여주기
	%>
	<table>
		<tr>
			<td> 로그인을 원하시면 버튼을 누르세요 <br />
				<button onclick="window.location='loginForm.jsp'"> 로그인 </button>
			</td>
		</tr>
		<tr>
			<td> 
				<a href="signupForm.jsp"> 회원 가입 </a>
			</td>
		</tr>
	</table>
	<%}else{ // 로그인 했을때  %>
	<table>
		<tr>
			<td> <%=session.getAttribute("memId") %> 님 환영합니다. <br />
				<button onclick="window.location='mypage.jsp'"> 마이페이지 </button>
				<button onclick="window.location='logout.jsp'"> 로그아웃 </button>
			</td>
		</tr>
	</table>
	<%} %>
	
	
	<br /><br />
	<div align="center">
		<img src="img/ham.jpg" width="400px" />
	</div>

</body>
</html>
<%@page import="web.jsp07.model.MemberDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>loginPro</title>
</head>
<%
	// loginForm -> Pro (파라미터 들고옴)
	// main -> pro 쿠키들고 (파라미터 X)

	request.setCharacterEncoding("UTF-8"); // 한글깨짐 방지
	// 넘어온 파라미터 꺼내기 (main에서 바로 왔으면 아래 변수 null)
	String id = request.getParameter("id");
	String pw = request.getParameter("pw");
	String auto = request.getParameter("auto");
	
	// 쿠키를 꺼내서 정보가 나오면 위 변수에 저장 
	Cookie[] coos = request.getCookies(); 
	if(coos != null){
		for(Cookie c : coos){
			if(c.getName().equals("autoId")) id = c.getValue();
			if(c.getName().equals("autoPw")) pw = c.getValue();
			if(c.getName().equals("autoCh")) auto = c.getValue();
			System.out.println(c.getName() + c.getValue());
		}
	}

	MemberDAO dao = new MemberDAO(); 
	boolean result = dao.idPwCheck(id, pw); 
	
	if(result){ // id, pw 일치 : 로그인 상태로 만들기 
		// 자동로그인이면 쿠키도 생성 
		if(auto != null){ // 자동로그인 체크했다.
			Cookie c1 = new Cookie("autoId", id);
			Cookie c2 = new Cookie("autoPw", pw);
			Cookie c3 = new Cookie("autoCh", auto);
			c1.setMaxAge(60*60*24); // 24시간
			c2.setMaxAge(60*60*24); // 24시간
			c3.setMaxAge(60*60*24); // 24시간
			response.addCookie(c1);
			response.addCookie(c2);
			response.addCookie(c3);
		}
	
		session.setAttribute("memId", id); 
		response.sendRedirect("main.jsp"); // 메인으로 이동 
	}else{ %>
		<script>
			alert("아이디 또는 비밀번호가 맞지 않습니다..."); 
			history.go(-1);
		</script>
	<%} %>

<body>

</body>
</html>
<%@page import="web.jsp07.model.MemberDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>signupPro</title>
</head>
<%  request.setCharacterEncoding("UTF-8"); // post방식 인코딩 처리  %>
<jsp:useBean id="dto" class="web.jsp07.model.MemberDTO" /> <%-- dto 객체 생성 --%>
<jsp:setProperty property="*" name="dto"/> <%-- 넘어온파라미터 dto에 담기 --%>
<%
	MemberDAO dao = new MemberDAO(); 
	dao.addMember(dto); // 회원 가입 처리 메서드 호출 

	// 메인으로 이동 
	response.sendRedirect("main.jsp"); 
	
%>

<body>

</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>signupForm.jsp</title>
	<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
	<br />
	<h1 align="center"> 회원가입 </h1>
	<form action="signupPro.jsp" method="post">
		<table>
			<tr>
				<td>아이디 *</td>
				<td><input type="text" name="id" /></td>
			</tr>
			<tr>
				<td>비밀번호 *</td>
				<td><input type="password" name="pw" /></td>
			</tr>
			<tr>
				<td>비밀번호 확인 *</td>
				<td><input type="password" name="pwch" /></td>
			</tr>
			<tr>
				<td>이름 *</td>
				<td><input type="text" name="name" /></td>
			</tr>
			<tr>
				<td>성별 </td>
				<td>
					남 <input type="radio" name="gender" value="male" checked />
					여 <input type="radio" name="gender" value="female" />
				</td>
			</tr>
			<tr>
				<td>email</td>
				<td>
					<input type="text" name="email" />
				</td>
			</tr>
			<tr>
				<td colspan="2">
					<input type="submit" value="회원 가입" />
					<input type="reset" value="재작성" />
					<input type="button" value="취소" onclick="window.location='main.jsp'" />
				</td>
			</tr>
		</table>
	</form>


</body>
</html>

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> loginForm.jsp </title>
  <link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
   <br />
   <form action="loginPro.jsp" method="post">
   <h2 align="center"> 로그인 </h2>
   <table>
      <tr>
         <td>아이디</td>
         <td><input type="text" name="id"></td>
      </tr>
      <tr>
         <td>비밀번호</td>
         <td><input type="password" name="pw"></td>
      </tr>
      <tr>
         <td colspan="2"><input type="checkbox" name="auto" value="1" /> 자동로그인</td>
      </tr>
      <tr>
         <td colspan="2">
         <input type="submit" value="로그인" />
         <input type="button" value="회원가입"  onclick="window.location='signupForm.jsp'"/>
         </td>
      </tr>
   
   </table>
   </form>

</body>
</html>

- 자바

 

package web.jsp07.model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class MemberDAO {

	   	// 커넥션 메서드 
		private Connection getConnection() throws NamingException, SQLException {
			Context ctx = new InitialContext(); 
			Context env = (Context)ctx.lookup("java:comp/env");
			DataSource ds = (DataSource)env.lookup("jdbc/orcl"); 
			return ds.getConnection(); 
		}
		//회원가입 처리
		public void addMember (MemberDTO dto) {
			Connection conn = null; 
			PreparedStatement pstmt = null; 
			ResultSet rs = null; 
			
			try {
				conn = getConnection(); // Naming/SQLException 발생가능 
				String sql = "insert into member values(?,?,?,?,?,sysdate)";
				// 커넥션으로 준비한 쿼리문 주고 실행기능 갖는 pstmt 리턴받기 (쿼리문 준비)
				pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, dto.getId());
				pstmt.setString(2, dto.getPw());
				pstmt.setString(3, dto.getName());
				pstmt.setString(4, dto.getGender());
				pstmt.setString(5, dto.getEmail());
			
			
				int result  = pstmt.executeUpdate(); 
				System.out.println("insert result : " + result);
			
			
				
			}catch(Exception e) { // Naming/SQLException 발생했을때 둘다 받아줄 부모로 처리 
				e.printStackTrace();
			}finally {
				
				if(pstmt != null) try { pstmt.close(); } catch(SQLException e) { e.printStackTrace(); }
				if(conn != null) try { conn.close(); } catch(SQLException e) { e.printStackTrace(); }
			}
			
		}
			
		// 로그인 : id, pw 맞는지 체크해서 결과 돌려주는 메서드
		//			id,pw 맞으면 true, 둘중하나라도 틀리거나 없으면 false
		public boolean idPwCheck(String id, String pw) {
			System.out.println("idPwCheck 호출!");
			boolean result = false; // 최종 결과 리턴해줄 변수 미리 선언
			Connection conn = null; 
			PreparedStatement pstmt = null; 
			ResultSet rs = null; 
			
			try {
				conn = getConnection(); // Naming/SQLException 발생가능 
				String sql = "select * from member where id =? and pw =?";
				pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, id);
				pstmt.setString(2, pw);
				
				rs = pstmt.executeQuery(); 
				// rs에 돌려받은 결과에 따라 result 변수값 변경 
				if(rs.next()) {
					System.out.println("rs.next() -> true");
					result = true;
				}
				
			}catch(Exception e) { // Naming/SQLException 발생했을때 둘다 받아줄 부모로 처리 
				e.printStackTrace();
			}finally {
				if(rs != null) try { rs.close(); } catch(SQLException e) { e.printStackTrace(); }
				if(pstmt != null) try { pstmt.close(); } catch(SQLException e) { e.printStackTrace(); }
				if(conn != null) try { conn.close(); } catch(SQLException e) { e.printStackTrace(); }
			}
			return result; // result변수에 들어있는 결과 리턴 
		}
	}

- 자바

package web.jsp07.model;

import java.sql.Timestamp;

public class MemberDTO {
				private String id;
				private String pw;
				private String name;
				private String gender;
				private String email;
				private Timestamp reg;
			
				
				public String getId() {
					return id;
				}
				public void setId(String id) {
					this.id = id;
				}
				public String getPw() {
					return pw;
				}
				public void setPw(String pw) {
					this.pw = pw;
				}
				public String getName() {
					return name;
				}
				public void setName(String name) {
					this.name = name;
				}
				public String getGender() {
					return gender;
				}
				public void setGender(String gender) {
					this.gender = gender;
				}
				public String getEmail() {
					return email;
				}
				public void setEmail(String email) {
					this.email = email;
				}
				public Timestamp getReg() {
					return reg;
				}
				public void setReg(Timestamp reg) {
					this.reg = reg;
				}
			
}

 

create table member( --테이블 만들기
    id varchar2(50) primary key,
    pw varchar2(50) not null,
    name varchar2(20) not null,
    gender varchar2(20),
    email varchar2(50),
    reg date default sysdate
);
desc member;  -- 테이블(맴버)참조
commit; -- 커밋
select * from member;  -- 출력용

진행 순서 
1) 회원가입에 필요한 항목을 DB 테이블 만들기

2) Member DTO로 변수와 get/set메서드 만들기  

 3) Member DAO 만들기 

 

1 - DB와 연결하는 메서드

2 - 회원가입에 필요한 메서드
받은값들을 연결된 DB에 차례대로 넣어주는 메서드

3 - 로그인에 필요한 메서드 생성 
Id 와 PW가 db값과 같은지 체크하는 메서드


 4) loginForm 만들기 

 

1 - 폼, 액션태그와 input에 변수들 넣어주기
2 - 폰트, 이미지등 CSS스타일 관리 
3 - 로그인, 회원가입 관리 
<form action="태그.jsp" method="post"> 또는 onclick을 이용하여 페이지 이동 만들기
로그인 -> login Pro로 이동
회원가입 -> signupForm 으로이동

 

 

 


   4) -  1 <회원가입 폼 (signup Form)>      

    4)에서 회원가입을 눌렀을때 실행 

 

1 - loginForm 과 유사함
2  -<form action="태그.jsp" method="post"> 
또는 onclick을 이용하여 페이지 이동 만들기
회원가입 -> signup Pro로 이동
취소버튼 -> main 으로이동(로그아웃상태)

 

 

 


     4) -  1  - 1  회원가입 처리폼 (Signup Pro)

 

 1-  DTO 객체 생성후 넘어온 파리미터를 DTO에 담아줌
 2-  DAO 객체 생성후 회원가입 메서드 작동
 3-  main 으로 이동(로그인상태)

 

 

 


4) - 2 로그인 처리폼(login Pro)

 

login Pro에 오자마자 파라미터꺼냄 
쿠키있으면 변수생성     

DAO 객체 생성하여 3) -1 에 로그인에 필요한 메서드 실행

 

 

 <1- 메서드가 실행되어 ip/ pw가 일치하는 경우>

                      ●a -  auto가 null이 아니다! (자동로그인체크)
                                -> 쿠키 객체 생성하고 유효시간과 쿠키값주고 세션 속성값 주고
                                       main으로 보냄(로그인 상태)
 

                      ●b -  auto 가 null 이면
                                     -> 세션 속성값만 주고 바로 
                                           main으로 보냄(로그인 상태) 


** 세션 속성값 -> 난 로그인처리를 했어!

 <2 - 메서드가 실행되었는데 ip/ pw가 일치하는 않는 경우>
 경고창 띄우고 
한칸 뒤로 (history.go(-1) 실행

 


   5 메인 폼 (Main Form)   만들기 

 

 <1 -   세션 속성값이 없을때> (login Pro를 통해 온게 아님-> 로그인으로 온게아님) 
             
              a  -         쿠키가 있다 ->  login pro로 보내줌 (자동로그인 체크한 경우이니 로그인 처리가 되도록)
                             login pro에서 
                                       유효시간, 쿠키값, 세션 속성값 주면서
                                       main으로 보냄
 
              b  -         쿠키가 없다 -> login Form으로 보냄 



< 2 -   세션 속성값이 있다> (login pro에서 들어온거임)(자동로그인x 로그인)

 

COOKIE 세션SESSION 필요성은 

 

 HTTP의 특징이자 약점을 보완하기 위해서이다.

그렇다면 이 HTTP의 특징은 무엇이고, 그로 인한 약점은 무엇일까?

 

HTTP 프로토콜

HTTP(Hypertext Transfer Protocol)는 인터넷 상에서 데이터를 주고받기 위해 서버 · 클라이언트 모델을 따르는 통신 규약이다. 이 HTTP 프로토콜의 특징은 비연결성(Connectionless)과 비상태성(Stateless)이다.

  1. 비연결성(Connectionless) : HTTP는 클라이언트가 서버에 요청을 보내면, 서버는 클라이언트에게 요청에 맞는 응답을 해 준 뒤 접속을 끊는다. 이에 대해서는 논란이 되는 부분이 있으나 여전히 접속을 끊음으로써 연결 비용을 줄이는 것이 HTTP의 장점이기 때문에 비연결성을 가지고 있다고 말한다.
  2. 비상태성(Stateless) : 상태 정보를 유지하지 않고. 연결을 끊는 순간 클라이언트와 서버의 통신이 끝나게 되며, 상태 정보는 유지하지 않는다.

https://sunrise-new-world.tistory.com/21

 

1. 쿠키 Cookie  


상태가 없는 프로토콜을 위해 상태를 지속시키기 위한방법
웹 브라우저( 클라이언트) 의 정보를 웹 브라우저에 저장하므로,
이후 서버로 전송되는 요청에는 쿠키가 가지고 있는 정보가 같이 포함되서 전송된다.

 

ex) 자동로그인, 로그인 상태 유지
비번, 아이디 저장 팝업

 

* 쿠키의 2가지 방식
- 파일 쿠키 : 실제 파일로 남겨서 저장하는 방식

- 웹 쿠키 : 브라우저가 관리

 

 

 

1) 쿠키 동작 방식

 

 

2) 쿠키의 구성

       * 이름       : 각 쿠키를 구별하는데 사용되는 이름. (알파벳, 숫자 이용)
       * 값       : 쿠키의 이름과 같이 저장할 데이터.
       * 유효시간    : 쿠키가 유지되는 시간.
       * 도메인    : 쿠키를 전송할 도메인.
       * 경로       : 쿠키를 전송할 요청 경로.

      - 하나의 브라우저는 여러 개의 쿠키를 가질 수 있고 구분할 때, 이름을 사용.
       - 각 쿠키는 값을 가지며 서버는 이 값을 사용해 작업 수행.

3) 쿠키 생성
       쿠키를 사용하려면 Cookie 클래스를 사용하여 쿠키 객체를 생성해야함
       쿠키에는 각 웹 브라우저를 판별할 수 있는 정보 포함되어있음
       서버가 응답할때, response 객체에 실려 사용자 브라우저에 저장됨.
       정보 전달 방식은 Map(key, value) 형태이다.

       [ 쿠키 객체 생성 ]
Cookie cookie = new Cookie(String name, String value);

       [ 쿠키 유효기간 설정 ] ([ 도메인, path 도 설정])
cookie.setMaxAge(60);

       [ response 객체에 쿠키 추가]
reponse.addCookie(cookie);

name : 쿠키이름
value : 쿠키값

* 쿠키 생성후, 반드시 reponse 객체에 쿠키를 추가해야한다.
* value에 아스키코드가 아닌 값이 들어가야할때는 알맞은 방식으로 인코딩한다.

 

쿠키 클래스 메서드
String  getName() 쿠키 이름 가져오기
String getValue() 쿠키값 가져오기
void setValue(String value) 쿠키값 지정
void setDomain(String pattern) 이 쿠기가 전송될 서버 도메인 지정
String getDomain() 지정된 도메인 리턴
void setPath(String url) 이 쿠키를 전송할 경로 지정
String getPath() 지정된 경로 리턴
void getMaxAge() 쿠키 유효시간을 초단위로 지정.
음수로 입력할 경우 웹브라우저 닫을때 쿠키가 함께 삭제된다.
int getMaxAge() 쿠키 유효시간을 구함.

 

 

 쿠키 읽어오기

 

#1 쿠키 목록 얻기
존재하는 모든 쿠키 객체를 가져오려면
내장객체 request의 getCookies() 메서드를 사용해야함.

Cookie[] cookies =  request.getCookies();

#2. 쿠키 객체 정보 얻기
getName(), getValue() 이용해서 정보얻어야함.

 

 

 

쿠키 삭제

 setMaxAge(0)

 

 

쿠키는 삭제하는 기능을 별도로 제공하지 않고, 
쿠키 유효시간을 만료하면 삭제됨.
즉, setMaxAge(0) 으로 만들어 다시 저장되도록 응답으로 보내기

 

 

2. 세션 Session  
: 클라이언트와 웹 서버간의 상태를 지속적으로 유지하는 방법

 

 

 

세션 내부 객체
*Object getAttribute(String name) 세션에 저장된 속성명이 name인 값을 Object로 리턴
*void setAttribute(String name, Object value) 세션에 name 속성명으로 값 저장 (어떤 값이든 저장가능)
-> 브라우저가 종료되거나, 삭제할때까지 데이터 유지
*void  removeAttribute(String name)  //로그아웃 툴 1
속성명이 name인 속성셋을 삭제
*void  invalidate() //로그아웃툴 2
현재 세션에 저장된 모든 속성 제거
java.util.Enumeration getAttributeNames() 세션 속성명들을 Enumeration으로 리턴
long getCreationTime() 세션이 생성된 시간 리턴
long getLastAccessedTime() 웹 브라우저가 해당 세션에 마지막으로 접근한 시간 리턴
int getMaxInactiveInterval() 해당 세션을 유지하기 위한 세션 유지시간 리턴.
void setMaxInactiveInterval (int interval) 해당 세션을 유지하기 위한 세션 유지시간 초단위로 설정
default 1800초 (30분) 동안 로그인 유지됨

 

 

 

 

 

 

  쿠키(Cookie) 세션(Session)
저장 위치 방문자(클라이언트) 서버
용량 제한 도메인당 20개, 쿠키당 4KB이하 용량 제한 없음
저장 형식 text Object
만료 시점 쿠키 저장 시 설정 가능. 따로 설정하지 않을 경우, 브라우저가 종료될 때 만료 정확한 시점을 알 수 없음
보안 보안 취약

보안우수

 

 

 

 

 

 

 

1712.00080.pdf
11.75MB

나스를 활용하여 개인 서버만들기

- docker에서 tomcat 활용편

 

1. 패키지 센터에서 Docker 설치

먼저 아래 사이트에 접속하여 자신의 나스가 Docker를 지원하는지 확인하기 바랍니다.

https://www.synology.com/ko-kr/dsm/app_packages/Docker

현재 지원 모델 리스트

 

 

2. Docker 실행 후 톰캣 설치

  • Docker – 레지스트리 – “tomcat” 검색 후 “tomcat” 다운로드
  • Docker – 이미지 – tomcat 선택 – 실행 – 마법사로 실행

받은 파일은 이미지에서 설정 가능하다

*혹시 이미 설치가 되어있는사람이라면

컨테이너에서 실행을 멈추면 편집탭이 활성화된다.

 

볼륩탭에서 폴더추가를 누르고 

나스에  하드안에서 서버관련 폴더를 만들고 

webapps을 만든다... 반드시 webapps로 해야함

그 다음 마운트 경로를 /usr/localtomcat/webapps로 지정한다

-> 해당폴더를 톰캣의 저 마운트로 지정하겠단 소리임

 

 

다음으론 포트설명

로컬포트는 내가 타고들어올 포트이다.

아마 자동으로 설정되어있을텐데

8080로 수동설정하겠다

 

*8080 포트를 뚫어두어야한다

** 포트포워딩필요 ** 

 

 3. 톰캣 실행

 

자 이제 이클립스나 다른 툴에서 작업한 파일을 export 해서 war파일로 만든다

그 다음 나스에 webapps 에 war 파일을 두면 알아서 구동된다.

 

http://나스IP:8080/web/jsp01/test01.jsp

입력하면 해당 test01 파일이 실행이 된다.

 

잘안되면 해당 링크참고

https://youtu.be/VF9ilum0cck

+ Recent posts