servlet

김명준·2023년 10월 25일

Web의 개요

IT(information Technology)
: 데이터의 관리와 처리에 대한 응용 기술
WWW(World Wide Web)
: 인터넷으로 연결된 사용자들이 정보를 공유하는 공간
네트워크
: 컴퓨터와 컴퓨터를 연결해주는 망
프로토콜
: 컴퓨터 간의 데이터 통신을 위한 통신 규약
ex) TCP/IP,HTTP(Hyper Text Transfer Protocol)
IP 주소
: 컴퓨터가 통신하기 위한 고유한 주소
cmd -> ipconfig -> IPv4
포트번호
: 네트워크 서비스나 특정 프로세스 식별하는 논리 단위 ex) :80
도메인
: 컴퓨터의 주소를 문자로 만든 주소, 네트워크 호스트 이름 ex) www.naver.com
DNS (Domain Name System)
: 도메인을 IP주소로 변환해주는 System

Web 통신흐름

Web Browser : Chrome, Safari, whale
Web Server : Chrome, naver
요청 (Request)
응답 (Response)

WAS(Web Application Server)
: 정적인 페이지를 자동으로 만들어 줄 프로그램
Client (로그인 요청)->Server(동적페이지)->WAS (id,pw 일치 하는지 확인->DB
DB (id 보내줌) ->WAS (해당 id의 페이지 생성) -> Server(응답) -> Client
Presentation Tier : Client Serever
Application Tier : WAS
Data Tier : DB

Jsp/Servlet

Servlet 설명

java-> servers-> Browse apatch 설치한 폴더 지정

인코딩 (euc-kr(한국어 팩), utf-8(자음 모음 조합))
: 문자를 코드로 변환
디코딩
: 코드를 문자로 변환

500 error : java 문법에러 -> 코드 수정

URL Mapping : 보안상의 이유, URL이 길어지는것을 방지하기 위해 사용 ※P.K값
URL Pattern

URL vs URI

request, response

1. ip주소 확인하기
String client_ip = request.getRemoteHost();

2. response객체 
응답할 문서에 대한 설정
response.setContentType("text/html; charset=utf-8);

웹에 출력 => PrintWriter 객체
PrintWriter out = response.getWriter();

urlPattern

getContextPath() : server가 프로젝트를 찾아가는 이름
getServletPath() : url mapping값
getRequestURL() : URL 자원의 정확한 위치
getRequestURI() : URI 자원으 ㅣ고유한 식별자

html과 java

보여질 화면을 html에 작성하고 그 작동을 java 파일에서 함

form태그의 3가지 요소
      1. action에는 servlet의 url mapping 값을 작성
	  2. name : 데이터 이름
	  3. submit : 데이터 보낼 시점 value = 해서 submit버튼의 텍스트 내용 변경

요소 가져오기

html의 name의 값을 그대로 가져와야함.
getParameter은 String값을 가져오기 때문에 숫자형으로 바꿔줘야함.
String NAME = request.getParameter("name")
Int AGE = Integer.parseInt(request.getParameter("age"))

방만들기 실습

입력받은 수 만큼 방을 만들어라.
response.setContentType("text/html; charset=utf-8");
		int room = Integer.valueOf(request.getParameter("room"));
		String color = request.getParameter("color");
		PrintWriter out = response.getWriter();
out.print("<table border =1  style =' background-color :  "+color+";' ><tr>");
		for(int i= 1; i <= room; i++) {
			out.print("<td>"+i+"</td>");
		}
		out.print("</tr></table>");

인코딩, 디코딩

<h1> GET방식 </h1>
<ol>
<li> URL에 쿼리스트링 방식으로 데이터 전송 </li>
	<li> 데이터 길이의 제한 (1024byte) </li>
	<li> URL에 데이터가 노출 되기 때문에 보안에 추약 </li>
	<li> 리소스 조회(READ) </li>
	<li> 캐시(임시저장소)에 저장하기 때문에 데이터를 다시 로딩하지 않아도
	      돼서 속도가 빠름</li>
	<li> form태그에 method속성을 통해서 지정하는데,
		따로 작성하지않아도 get방식으로 데이터 전송(기본값으로 지정되어있음)</li> 
</ol>
<ol>
   <li> 패킷(데이터블록)의 body부분에 데이터를 담아서 전송</li>
   <li> 데이터의 길이의 제한이 없음</li>
   <li> 직접 노출이 되지 않아 GET방식보다 보인에 강함</li>
   <li> 데이터 처리 및 등록</li>
   <li> method속성에 POST로 지정</li>
   <li> 데이터의 type을 명시(Content-Type)
      <ol>
         <li> Application/x-www-form-urlencoded(기본값) >> 데이터를 key=value형태로 전송 >> 전송하는 데이터를 url encoding해서 처리</li>
         <li> multipart/form-data >> 파일 업로드와 같은 바이너리 데이터 전송시 사용 >> multipart 이름처럼 다른 종류의 여러 파일을 전송 가능</li>
         <li> application/json >> text, xml, json 데이터 전송 시 사용</li>
         <li> text/plain >> txt 형태로 전송</li>
      </ol>
<h1>POST방식</h1>        
// 0. 디코딩	
// GET방식 인코딩 방법 : form태그가 해당 페이지의 charset으로 인코딩 진행
// GET방식 디코딩 방법 : server.xml파일의 63번째줄 Connector태그에
//						URIEncoding="인코딩방식" 속성 추가
//						-> Tomcat9버전부터는 UTF-8 기본값으로 설정
	
// POST방식 인코딩 방법 : form 태그가 해당 페이지의 charset으로 인코딩
// POST방식 디코딩 방법 : 데이터가 담긴 request객체에 
//					   setCharacterEncoding 메소드를 사용해서 디코딩 방법 설정
	request.setCharacterEncoding("UTF-8");
	
	// 1. 데이터 전송 방식 확인하기	
	String method =request.getMethod();
	System.out.println("방식 : "+ method);
	
	// 2. 데이터 확인
	String data = request.getParameter("data");
	System.out.println("데이터 : " + data);

JSP 필요성

Business Logic / Pregentation Logic
JSP vs Servlet

JSP

Jsp 기본문법


스크립트릿 : <% 실행문 %>, Jps내에서 Java코드를 작성할 때 사용
.java로 변환시_jspService()메소드 내로 이동
표현식 : <%= 실행문 %>, 동적인 데이터를 Web에 출력할 때 사용 (변수 사용할때 사용)
.java로 변환 시 out.print() 메소드로 변환
선언문 : <%! 실행문 %>, 멤버 변수 선언, 메소드 정의 할 때 사용
.java로 변환 시 해당 클래스의 영역에 선언
스크립트릿을 안쓰고 선언문을 쓰는 이유!
스크립트릿은 메소드 내로 이동해서 메소드 내에 메소드를 작성할 수 없기 때문에
지역변수가 되기 때문에 선언문을 사용해서 사용해야 메소드나 변수를 사용할 수 있다.

table만들기 실습

<body> 
<table border =1>
	<tr>
	<% for (int i = 1; i<=10; i++){ %>
		<td> 
			<%= i %> 
		</td>
		<% } %>
	</tr> 
</table>  
</body>

선언문 실습

<%! 
	// 합을 구하는 메소드
	public int addNumber(int num1, int num2){
	return num1 + num2;
}
%>

<% System.out.println(addNumber(1,2)); %>
<%= addNumber(1,2) %>

계산기 실습

<body>

<% 
int num1 = Integer.parseInt(request.getParameter("num1"));
int num2 = Integer.parseInt(request.getParameter("num2"));
%>
	
<%!
public int add (int num1, int num2){
 	return num1+num2;
 	}
 	
public int minus (int num1, int num2){
	 	return num1 - num2;
	 	}

public int mul (int num1, int num2){
 	 	return num1 * num2;
 	 	}

public int div (int num1, int  num2){
 	 	return num1/num2;
 	 	}
%>
                             
<%=num1 %> + <%=num2%> : <%= add(num1,num2) %><br>
<%=num1 %> - <%=num2%> : <%= minus(num1,num2) %><br>
<%=num1 %> * <%=num2%> : <%= mul(num1,num2) %><br>
<%=num1 %> / <%=num2%> : <%= div(num1,num2) %>
 
</body>

지시자

page지시자

page 지시자
error페이지 실습

<makeError.jsp>
<!-- 4. 지시자 : Servlet으로 변환할 때 필요한 정보들을 기술 
	4-1 : page 지시자 : 현재 jsp 페이지에 대한 환경설정
		 - language : 사용될 언어
		 - contentType : 문서의 종류, 인코딩 방식 
		 -> servlet으로 변환 될 때 response.setContentType(매개변수)의 매개변수값 
		 - pageEncoding : 현재 문서의 문자 타입
		 - errorPage : 오류가 났을 때 대체할 페이지 지정
		 - import : java패키지나 클래스를 불러올 때 사용-->

<%@page import="java.util.Random"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page errorPage="./ex07error.jsp" %>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!--  일부러 오류 나는 페이지 만들기 -->
<%= 2/0 %>
<% Random rd = new Random(); %>

</body>
<error.jsp>
<body>
<img alt="" src="./전청조.jpg"><br>
<h2>I am 에러예요.</h2>
</body>

inclue 지시자

: 현재 페이지에 다른 페이지를 삽입할 때 사용
<%@ includ file="Ex07_footer.jsp"%>
주석

<body>

<!--  HTML 주석 : 소스보기 공개 -->
<%-- 스크립트릿 주석 : 소스보기 비공개 --%>
<%
	// Java 주석 : 소스보기 비공개
	/* Java 주석 : 소스보기 비공개 */
	%>
</body>

taglib 지시자

: Jsp를 작성할 때 자주 사용되는 Java 코드를 Web에서 사용할 수 있는 태그로 만들어 놓은것

JSTL

: Jsp에서 사용 가능한 표준 라이브러리

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix ="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- 문자하나를 정해서JSTL을 사용하겠다고 알려주기
	    prefix -> 이제 밑에서 우리가 custom한 태그를 쓸 거에 기호를 정해서 해당 라이브러리를 사용하겠다!  
	-->    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<!-- 화면에 1 ~ 10 출력  -->

<% 
for (int i =1; i<=10; i++){
	out.print(i+"<br>");
}
%>

<!-- 태그라이브러리  -->
<!--  var : 변수 선언, begin : 시작, end :, step : 증가량 -->
<c:forEach var="i" begin="1" end="10" step="1"> 
<!-- EL표기법  (표현식은 java 문법이여서 사용하는 의미가 없음 )
	약간 js랑 비슷함-->
	<c:if test="${i%2==0}">
		 ${i} <br> 
	</c:if>
</c:forEach>

</body>

내장객체

학점확인프로그램

<request.html>
<body>
<fieldset>
   <legend>학점확인프로그램</legend>
   <form action="Ex01_request.jsp" method="post">
   <table align="center">
      <tr>
         <td>이름</td>
         <td><input type="text" name="name"></td>
      </tr>
      <tr>
         <td>JAVA점수</td>
         <td><input type="text" name="java"> </td>
      </tr>
      <tr>
         <td>WEB점수</td>
         <td><input type="text" name="web"></td>
      </tr>
      <tr>
         <td>IOT점수</td>
         <td><input type="text" name="iot"></td>
      </tr>
      <tr>
         <td>ANDROID점수</td>
         <td><input type="text" name="android"></td>
      <tr>
         <td></td>
         <td><input type="submit" value="확인하기"></td>
      </tr>
   </table>
   </form>
</fieldset>
<request.jsp>
<body>
 <!-- 요청객체 : request에서 데이터 받아오기 -->
 <% 
 	request.setCharacterEncoding("UTF-8");
 	String name = request.getParameter("name");
	int java = Integer.valueOf(request.getParameter("java"));
	int web = Integer.valueOf(request.getParameter("web"));
	int iot = Integer.valueOf(request.getParameter("iot"));
	int android = Integer.valueOf(request.getParameter("android"));		
	float avg = (java+web+iot+android)/4 ;
	String grade;
	
	if (avg>= 95){
		grade = "A+";}
	else if (avg>= 90){
		grade = "A";}
	else if (avg>=85){
		grade = "B+";}
	else if (avg>=80){
		grade = "B";}
	else {grade = "F";}	
	
	%>
 
 	<fieldset>
   <legend>학점확인프로그램</legend>
   <table align="center">
      <tr>
         <td>이름</td>
         <td><%= name %></td>
      </tr>
      <tr>
         <td>JAVA점수</td>
         <td><%= java %> </td>
      </tr>
      <tr>
         <td>WEB점수</td>
         <td><%= web %></td>
      </tr>
      <tr>
         <td>IOT점수</td>
         <td><%= iot %></td>
      </tr>
      <tr>
         <td>ANDROID점수</td>
         <td><%= android %></td>
      <tr>
         <td>평균 </td>
         <td><%= avg %></td>
      <tr>
         <td>학점 </td>
         <td><b><%= grade %></b></td>
     
   </table>
   </form>
</fieldset>
</body>

랜덤 실습

<createInput.jsp>
<body align="center">
 	<% int num = Integer.parseInt(request.getParameter("num"));
 	%>
 	
	<form action="Ex02_randomWinner.jsp">
		<fieldset>
		<legend>랜덤당첨작성</legend>	
		주제 : <input type="text" name="topic"><br>
	<% for(int i = 1; i<=num; i++){ 
		out.print("아이템"+i+":"); %>		
		<input type="text" name="item"><br>		
		<%} %>
		<input type="submit" value="시작">
		</fieldset>
	</form>
</body>
<randomWinner>
<body align="center">
<%
	String topic = request.getParameter("topic");
	String [] random = request.getParameterValues("item");
	Random rd = new Random();
	String result = random[rd.nextInt(random.length)];
	
	
%>
<fieldset>
		<legend>랜덤당첨결과</legend>	
		<%= topic %><br>
		<%= result %>
		</fieldset>
</body>

response.sendRedirect()
현재 실행중인 JSP page가 다른 url로 이동하는것
<%response.senRedirect("http://www.naver.com"); %>
url 실습

<moveUrl.html>
<form action="Ex04_url.jsp">
	<select name="url">
		<option value="naver"> 네이버 </option>
		<option value="daum"> 다음 </option>
		<option value="google"> 구글 </option>
	</select>
	<input type="submit">
</form>
<url.jsp>
<% String url = request.getParameter("url"); 
	
	if (url.equals("naver")){
		response.sendRedirect("http://www.naver.com");
	}else if (url.equals("daum")){
		response.sendRedirect("http://www.daum.net");
	}else {
		response.sendRedirect("http://www.google.com");
	}

%>

MVC구성

model : 여기적기 여기적기
Controller : 어플리케이션의 행위를 정의, Logic 결과에 따라 적절한 View를 선택하여 응답
View : Model 데이터를 기반으로 실제 사용자에게 보여지는 페이지
세 영역간의 결합도를 최소화하는 것이 목표
Model :
모델 2를 사용할 예정

DAO (Data Access Object) : DB랑 연동하는 것
DTO (Data Transfer Object) : 묶는 개념

로그인 회원가입 프로세스 만들기

핵심 : row, rs 차이 / forwarding, sendRedirect 차이
row는 executeUpdate쓰는 sql일때, rs는 executeQuery쓰는 select일때
sendRedirect는 value값이 String형태로만 나옴.
forwarding은 object형태로 나와서 더 다양함.

JoinProgram.java

servelt으로 만듬.
request.setCharacterEncoding("UTF-8");

System.out.println("[JoinProgram]");
		
		
String id = request.getParameter("id");
String pw = request.getParameter("pw");
String name = request.getParameter("name");

System.out.println(id);		
System.out.println(pw);		
System.out.println(name);	
		
// DTO(data Transfer object) 묶기
MemberDTO dto =  new MemberDTO (id, pw, name);		
// 회원가입 기능이 있는 join 메소드 호출
int row = new MemberDAO().join(dto);
// MemberDAO dao = new MemberDAO();
// dao.join(dto); 이 두줄을 한줄로 줄인것
	
// 성공 실패 여부 확인
// 성공 -> Login.jsp
// 실패 -> Main.jsp
String moveURL;
if (row >0 ) {
	System.out.println("회원가입 성공");
	moveURL = "./Login.jsp";
    }else {
	System.out.println("회원가입 실패");
	moveURL = "./Main.jsp";
	}
	response.sendRedirect(moveURL);
	}

MemberDAO

Connection conn = null;
PreparedStatement psmt = null;
ResultSet rs = null;
=> 따로 빼는 이유는 메소드 안에 있으면 지역변수라서 다른 메소드에서 사용할 수 없어서
next는 다음줄로 이동 (즉 한줄씩 이동하면서 파악을 한다는 의미)
DB 연결 종료 메소드 (열린 반대 순서로 닫아야한다)
finally를 안쓰면 안 닫히고 catch문으로 가서 문이 안 닫히고 오류로 가버림)

public class MemberDAO {

	// DAO(Data Access Object) : DB에 접근하는 객체
    ↓↓↓↓↓ 하는 이유는 메소드 안에 있으면 지역변수라서 다른 메소드에서 사용할 수 없어서 
	Connection conn = null;
	PreparedStatement psmt = null;
	ResultSet rs = null;
	// DB 연결 메소드
	public void db_conn() {
		try {
			// 1. ojdbc6.jar 라이브러리 불러오기
			// jdbc ->
			// webapp - WEB-INF - lib 폴더에 넣기

			// 2. OracleDriver class 불러오기
			// OracleDriver : Java와 DB 사이에 통로를 만들어주는 역할
			Class.forName("oracle.jdbc.driver.OracleDriver");

			// 3. DB에 접속하기 위한 카드키 설정(주소, 계정, 비번)
			String url = "jdbc:oracle:thin:@localhost:1521:xe";
			String user = "service";
			String pw = "12345";

			// 4. DB에 접속 -> 접속 성공 시 Connection 객체로 반환
			conn = DriverManager.getConnection(url, user, pw);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// DB 연결 종료 메소드 (열린 반대 순서로 닫아야한다)
	public void db_close() {
		try {
			if (psmt != null)
				psmt.close();
			if (conn != null)
				conn.close();
			if (rs != null)
				rs.close();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 회원가입 메소드
	public int join(MemberDTO dto) {
		int row = 0;
		try {
			db_conn();

			// 5. SQL 쿼리 작성 -> ? : 바인드변수 -> 성능향상을 위해서(soft parsing)
			String sql = "insert into Member1 values(?,?,?)";

			// 6. SQL문장을 DB에 전달 -> 전달 성공 시 PrepareStatment
			psmt = conn.prepareStatement(sql);

			// 7. 바인드변수 값 채우기
			// psmt.set자료형(물음표의 순서, 넣을 값)
			psmt.setString(1, dto.getId());
			psmt.setString(2, dto.getPw());
			psmt.setString(3, dto.getName());

			// 8. 실행
			// executeUpdate : DB에 변화가 생겼을 때, select구문을 제외한 모든 구문
			// executeQuery : DB에 질의할 때, select구문
			// int로 return 하는 이유 : 몇개의 행이 변화 되었는지 알려주는 것!

			row = psmt.executeUpdate();

		} catch (Exception e) {
			e.printStackTrace();
		} finally { // 무조건 열려있으면 닫기!!
			// (finally를 안쓰면 안 닫히고 catch문으로 가서 문이 안 닫히고 오류로 가버림)
			db_close();
		}
		return row;
	}
	//
	public MemberDTO login(MemberDTO dto) {
		MemberDTO login_dto = null ; 
		try {
			// 1. DB연결 메소드 호출
			db_conn();

			// 2. 쿼리문 작성 -> 
			String sql = "select * from member1 where id=? and pw =?";

			// 3. SQL문을 DB에 전달 -> 전달 성공 시 PrepareStatment
			psmt = conn.prepareStatement(sql);

			// 4. 받아온 id와 pw를 SQL문에 세팅
			psmt.setString(1, dto.getId());
			psmt.setString(2, dto.getPw());
			
			// 5. 실행 (executeQuery 실행)
			rs = psmt.executeQuery();
			
            // next는 다음줄로 이동 (즉 한줄씩 이동하면서 파악을 한다는 의미)
			if (rs.next()) {
				String id = rs.getString(1);
				String pw = rs.getString("pw");
				String name = rs.getString(3);
				login_dto = new MemberDTO(id, pw, name);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally { // 무조건 열려있으면 닫기!!
			// (finally를 안쓰면 안 닫히고 catch문으로 가서 문이 안 닫히고 오류로 가버림)
			db_close();
		}
		return login_dto;
	}
}

DTO (Data Transfer Object)

// 테이블 형태 그대로 생성
	
	// 필드
	private String id;
	private String pw;
	private String name;
	
	// 메소드
	// 생성자 메소드 : 객체를 초기화 하기 위한 메소드
	// MemberDTO dto = new MemberDTO(id, pw, name);
	
	public MemberDTO (String id, String pw, String name) {
		this.id = id;
		this.pw = pw;
		this.name = name;
	}
	
	// 로그인을 위한 생성자 메소드
	public MemberDTO (String id, String pw) {
		this.id = id;
		this.pw = pw;
	}
	
	// Getter
	
	public String getId() {
		return id;
	}
	public String getPw() {
		return pw;
	}
	public String getName() {
		return name;
	}

	//setter
	
	public void setId(String id) {
		this.id = id;
	}

	public void setPw(String pw) {
		this.pw = pw;
	}

	public void setName(String name) {
		this.name = name;
	}

Main

<fieldset>
	<legend align="center"> Main</legend>
	<a href="./Join.jsp"><button> 회원가입 </button></a>
	<a href="./Login.jsp"><button> 로그인 </button></a>
</fieldset>

LoginProgram

request.setCharacterEncoding("UTF-8"); => 한글로 변환하려고
sendRedirect는 value값이 String값 밖에 못감
Forwarding과 sendRedirect
Forwarding은 RequestDispatcher라는 함수 사용
setAttribute는 Object라는 객체 최상위 클래스로 들어가서 업캐스팅이됨(String, int 다됨)

package Controller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import Model.MemberDAO;
import Model.MemberDTO;

@WebServlet("/LoginProgram")
public class LoginProgram extends HttpServlet {
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		request.setCharacterEncoding("UTF-8");
		System.out.println("[LoginProgram]");

		String id = request.getParameter("id");
		String pw = request.getParameter("pw");

		System.out.println("id : " + id);
		System.out.println("pw : " + pw);

		 MemberDTO dto = new MemberDTO(id, pw);
		 MemberDTO login_dto = new MemberDAO().login(dto);
		 
		 if (login_dto == null) {
			 System.out.println("로그인 실패");
				response.sendRedirect("./loginFail.jsp");
			} //sendRedirect는 value값이 String값 밖에 못감
		 
		 String name = login_dto.getName();
		
		
		//System.out.println(" DB에서 넘어온 name : " + name);
		
		if (login_dto != null) {
//			System.out.println("로그인 성공");
//			sendRedirect 페이지 이동 방식			
//			name = URLEncoder.encode(name, "UTF-8");
//			System.out.println(name);
//			response.sendRedirect("./loginSuccess.jsp?name="+ name);
			
//			forwarding 페이지 이동 방식
			RequestDispatcher rd = request.getRequestDispatcher("./loginSuccess.jsp");
			request.setAttribute("login_dto", login_dto); // setAttribute는 Object라는 객체 최상위 클래스로 들어가서 업캐스팅이됨(String, int 다됨)
			rd.forward(request, response);
		}
			
		

	}

}

loginsuccess

sendredirect로하면 getParameter로 받지만
forwarding으로 받아오면 getAttribute로 받고 이것은 업캐스팅 된것이라고 다운캐스팅을 써준다. (원하는 형태)를 request 앞에 써준다.

<%
	// String name = request.getParameter("name");
	MemberDTO login_dto = (MemberDTO) request.getAttribute("login_dto");
	String name = login_dto.getName();
	%>
	<fieldset>
		<p>로그인 성공!</p>
	<%=name%>
		님 환영합니다~!
	</fieldset>
</body>

loginfail

<style type="text/css">
	fieldset{
	display: inline;
	}
</style>	
</head>
<body>
<fieldset>
<h2 align="center">로그인 실패</h2><br>
	<a href="./Main.jsp"><button> 메인 </button></a>
	<a href="./Login.jsp"><button> 로그인 </button></a>
</fieldset>
</body>

Cookie & Session

: HTTP의 한계때문(비연결형)
Client가 Server로 요청하면 해당 Page를 Client에게 전송(응답)한 후 연결 종료
=> 데이터 유지 불가능
Cookie vs Session

Cookie는 Client PC에 저장 Session Server PC에 저장

: 전달할 데이터를 Web Browser(client)로 보냈다가 Web Server로 되돌려 받는 방법
Web페이지 방문 시 브라우저에서의 정보들이 저장된 텍스트 파일
객체 생성 :
Cookie cookie = new Cookie("name",URLEncoder.encode("김명준", "UTF-8"));
기한 생성 : => cookie.setMaxAge(60*60);
Response객체에 cookie 추가해서 보내기 => response.addCookie(cookie);

Cookie

쿠키 보내기

cookie는 따로 제거가 없어서 setMaxAge(0)을 주면 제거가 된다.

<ol>
		cookie : client의 정보를 유지하기 위해서 사용하는 방법
		<li>저장위치 : CleintPC li</li>
		<li>보안 : 취약</li>
		<li>자원 : Client의 자원을 사용해서 Server에 영향 X</li>
		<li>용량 : 쿠키 1개당 4KB X 300= 1.2MB</li>
		<li>저장형식 : 텍스트만 저장 가능, 영어만 가능(한글은 인코딩 필요)</li>
	</ol>
	<%
	// 1. 쿠키 객체 생성
	// new Cookie("쿠키이름", "쿠키값")
	// 한글이라면 한글 인코딩 -> URLEncoder객체 사용
	Cookie cookie = new Cookie("name",URLEncoder.encode("김명준", "UTF-8"));

	// 2. 쿠키의 기한 설정
	// 양수 : 초 단위로 해당 기한만큼 쿠키를 유지
	// 음수 : 브라우저 종료 시 쿠키가 제거
	// 0 : 제거
	cookie.setMaxAge(3600);

	// 3. 쿠키 전송
	// 쿠키는 응답할 때 clientPC로 전송 -> response객체 사용
	response.addCookie(cookie);
	%>
// 4. 쿠키 조회하기
	// Server가 따로 요청하지 않아도, request객체에서 조회 가능
	 Cookie[] cookies = request.getCookies();

	for( int i = 0; i<cookies.length; i++){
		out.print("쿠키이름 : "+ cookies[i].getName()+"<br>");
		out.print("쿠키값 : " + URLDecoder.decode(cookies[i].getValue(), "UTF-8")+"<hr>");
		}
%>

Session

: 특징
1. 각 클라이언트에게 고유 ID를 부여
2. 보안 면에서 쿠키보다 우수
3. 사용자가 많아질수록 서버 메모리를 많이 차지하게 됨
생성 : setAttribute(name, value(Object))
가져오기 :
String id = (String)session.getAttribute("id");
Integer age = (Integer) session.getAttribute("age");
요소하나만 지우기 : session.removeAttribute("");
모든세션삭제 : session.invalidate();

Session 생성하기

<ol>
		Session : Client의 정보를 유지하기 위해서 사용하는 방법
		<li>저장위치 : ServerPC </li>
		<li>보안 : 우수 </li>
		<li>용량 : 서버가 허용하는만큼 가능</li>
		<li>저장형식 : 객체 저장 가능</li>
	</ol>
	<%
		// 1. 세션 값 설정 setAttribute(name, value(Object))
		session.setAttribute("id", "test");
		session.setAttribute("age", 20);
		
		// 어차피 서버가 알아서 세션 아이디를 부여해줄 거기 때문에 따로 응답X
	%>
	<a href="Ex04_showSession.jsp"> 세션확인</a>

Session 값 가져오기

<%
	// 세션 값 가져오기
	String id = (String)session.getAttribute("id");
	Integer age = (Integer)	session.getAttribute("age");	
	%>
	
	아이디 : <%=id %> <br> 
	나이 : <%=age %> <br>
	
	<a href="Ex05_deleteSession.jsp"> 세션삭제 </a> <br>
	<a href="Ex06_InvalidateSession.jsp"> 모든세션삭제</a>
	기본 세션 유효시간 : <%=session.getMaxInactiveInterval() %> <br>
	세션 아이디 : <%=session.getId()%><br>

Scope

: JSP 페이지에서 사용되는 객체들은 JSP 내장 객체이든 페이지 내에서 만들어졌던 간에
모두 정해진 영역 안에서만 사용 가능
~.setAttribute(네임값(String),실제값(Object))
~.getAttribute(네임값(String))

Page scope

: 실제 선언된 JSP 페이지 내에서만 사용가능 지역변수느낌
pageContext 내장객체로 사용가능
저장된 값은 저장한 페이지 내에서 지역변수로 사용
값 저장 방법
pageContext.setAttribute(네임값(String),실제값(Object))
pageContext.getAttribute(네임값(String))
주 사용 용도
pageScope에 값을 저장한 후 EL 표기법 사용
해당 JSP나 Servlet이 실행되는 동안에만 정보 유지하고자 할 때 사
PageScope1

<%
	// page 영역에 값 저장
	// pageContext
	pageContext.setAttribute("name", "페이지 영역");
	
	// page 영역에서 값 가져오기
	 String name =(String)pageContext.getAttribute("name");	
%>

닉네임 : <%-- <%=name%> --%><br>
닉네임(EL) : ${name}<br>
           
<a href="Ex01_pageScope2.jsp">2페이지로 이동</a>

PageScope2

<%
	String name = (String)pageContext.getAttribute("name");
%>
 이름 : <%=name %>
 이름(EL) : ${name}
 

Request scope

: 클라이언트로부터 요청을 받고 응답할 때까지 사용가능
HttpServletRequest객체로 사용 가능
(jsp에서는 내장객체, servlet에서는 매개변수라서 request로 쓰임)
service() 메소드가 끝날 때 객체가 없어짐
주 사용 용도
클라이언트의 요청을 다룰 때 사용
forward로 데이터 넘겨서 유지하고자 할 때 사용
request에서만 forwarding방식 가능한데, forwarding을 쓰면 주소창에
위치를 요청한 곳이 나와서 requestScope1.jsp가 맨뒤에 나옴.

Session scope

: 세션이 유지되는 동안 사용가능
HttpSession객체로 사용 가능
웹 브라우저 별(Chrome, edge) 변수 관리하는 영역
주 사용 용도
주로 로그인 시 사용자 정보를 저장하고 싶을 때 사용
세션이기 때문에 Jsessionid 가 존재함.

Application scope

: 웹 어플리케이션이 시작되고 종료될 때 까지 사용가능
ServletContext객체로 사용 가능
웹 어플리케이션 당 한 개의 객체 사용
주 사용 용도
모든 클라이언트들이 공통적으로 사용하는 값 저장

Maven

: 장점
협력해서 개발하기 편리
하위 라이브러리까지 자동으로 설치

MyBatis

: SQL Mapping Framework for Java => Java를 위한 SQL문자을 Mapping해주는 FrameWordk
과정 https://mybatis.org/mybatis-3/getting-started.html
mybatis의 독스(Getting Started)에서 실행하는 과정 따라서 하기
단 Building SqlSessionFactory from XML할때 아래꺼(2번) 먼저하고 위에꺼(3번) 하기
1번 설치(Mybatis 라이브러리 추가하기)
porm.xml에 dependencies 사이에 dependency 태그 삽입해서 넣기
가져올때는 mvn에서 검색해서 복사해서 가져오기

2번 mybatis-config.xml만들기 : mybatis의 환경설정 담당(중요한 파일)
3번 db.properties 만들기 : db연결정보들을 가지고 있는 파일 -> 공백주의
4번 SQlSessionManager 만들기 (database패키지)
import할때 ibatis로 하기 (import가 두개이면 창이 나옴)
5번 Mapper 만들기 : SQL 쿼리문을 작성하는 파일

2,3번 database/mybatis-config.xml (new->other->xml검색)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--  2. mybatis-config.xml만들기
		: mybatis의 환경설정 담당(중요한 파일) -->
<!--  3. db.properties 만들기
		: db연결정보들을 가지고 있는 파일 -> 공백 주의할 것 -->
		<properties resource="database/db.properties"></properties>		
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

4번 SqlSessionManager.java

//  SqlSessionFactory를 관리하는 class
	//	SqlSession == Connection
	//	SqlSessionFactory == Connection객체를 여러개 가지고 있는 공장
	// 데이터베이스를 *미리* 연결하는 동작(Connection Pool : CP)
	// why? db연결하는 부분이 성능이 가장 떨어지는 부분이라서 성능 향상을 위해
	// mybatis는 성능 향상을 위해 connection객체를
	// 미리 만들어서 빌려주고 반납하는 형식으로 진행

	// static 블록 : 객체를 호출할 때 무조건 실행되는 부분
	static {
		try {
			// mybatis 환경설정 파일 경로 
			String resource = "database/mybatis-config.xml";
			// xml파일을 읽어내기 위해 inputStream 여는 것!
			InputStream inputStream = Resources.getResourceAsStream(resource);
			// SQlSessionFactory : connection 객체가 여러개인 Connection Pool
			
			SqlSessionFactory sqlSessionFactory =
			  new SqlSessionFactoryBuilder().build(inputStream);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
  1. database/Mapper.xml
<!-- napespace : 현재 Mapper의 id를 그룹화 하는 속성
				sql 태그의 id가 중복 될 수 있기 때문에 id를 잘 찾아갈 수 있도록 그룹화
				주로 현재 Mapper파일의 경로를 작성 -->
				
<mapper namespace="database.Mapper">
	<select id="select" resultType="Blog">
		select * from Blog where id = #{id}
	</select>
</mapper>

Main문 taglib으로 작성하기

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:if test="${!empty result}">
		<c:choose>
			<c:when test="${result eq 'success'}">
				<h3>회원가입성공(JSTL)</h3>
			</c:when>
			<c:otherwise> 
			<h3>회원가입실패</h3>
			</c:otherwise>
		</c:choose>
	</c:if>

Member이름 테이블형태로 뽑기

<%@page import="model.MemberDAO"%>
<%@page import="model.MemberDTO"%>
<%@page import="java.util.List"%>
<%@page import="org.apache.ibatis.reflection.SystemMetaObject"%>
<%@ 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>
</head>
<body>
	<%
	List<MemberDTO> list = new MemberDAO().memberList();
	System.out.print(list.size());
	%>

	<table border="1">
		<h2>회원관리 페이지</h2>
		<tr>
			<td>ID</td>
			<td>PASSWORD</td>
			<td>NAME</td>
		</tr>
		<%
		for (int i = 0; i <list.size(); i++) {%>
		<tr>
			<td><%=list.get(i).getId()%></td>
			<td><%=list.get(i).getPw()%></td>
			<td><%=list.get(i).getName()%></td>
		</tr>
		<%}	%>
	
	<% 
	for(MemberDTO mem : list){%>
		<tr>
			<td><%=mem.getId()%></td>
			<td><%=mem.getPw()%></td>
			<td><%=mem.getName()%></td>
		</tr>	
	<%}%>
	</table>
</body>
</html>

MemberDAO (회원정보 리스트 포함)

package model;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import database.SqlSessionManager;

public class MemberDAO {
	
	// 세션을 생성해 줄 수 있는 Factory
	SqlSessionFactory sqlSessionFactory = SqlSessionManager.getSqlSession();
	// Factory를 사용해서 세션 생성(DB연결, close(), sql실행)
	SqlSession sqlSession = sqlSessionFactory.openSession(true); // (true)적으면  auto commit 
	
	// 회원가입 메소드
	public int join(MemberDTO dto) {
	int cnt = 0;
		try {
			cnt = sqlSession.insert("database.Mapper.join", dto);
			
		}catch (Exception e) {
			
		}finally {
			sqlSession.close();
		}
		return cnt;
		
//	   auto commit 안하면 이거 적어야됨	
//		if(cnt>0) {
//			// 회원가입 성공
//			sqlSession.commit();
//		} else {
//			// 회원가입 실패
//			sqlSession.rollback();
//		}		
	}

	// 로그인 메소드
	public String login(MemberDTO dto) {
		String name = null;
	try {
		name = (String)sqlSession.selectOne("database.Mapper.login",dto);
		
	} catch (Exception e) {
		
	} finally {
		sqlSession.close();
	}
		return name;
	}
	
	// 회원정보 리스트 출력
	public List<MemberDTO> memberList() {
		List<MemberDTO> list = null;
		try {
			list = sqlSession.selectList("database.Mapper.memberList");
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			sqlSession.close();
		}
		return list;
	}
}

Mybatis로 회원가입 및 로그입하기 복습

 <webapp main.jsp>
 1. 버튼생성
 <fieldset>
	<legend align="center"> Main</legend>
	<a href="./Join.jsp"><button> 회원가입 </button></a>
	<a href="./Login.jsp"><button> 로그인 </button></a>
</fieldset>
<%
	
	String result = request.getParameter("result");
	
	if( result != null){
		if(result.equals("success")){
			out.print("회원가입성공");
		}else{
			out.print("회원가입실패");
		}
	}
	%>
2. DAO, DTO생성
DTO(lombok버전)
import lombok.AllArgsConstructor;

// @Data -> 만능
@AllArgsConstructor // 모든 파라미터를 받는 생성자
@NoArgsConstructor // 기본 생성자
@Getter // getter 메소드
@RequiredArgsConstructor
// @Setter
public class MemberDTO {

	@NonNull
	private String id;
	@NonNull
	private String pw; 
	private String name;
}

DAO
package model;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import database.SqlSessionManager;

public class MemberDAO {
	
	// 세션을 생성해 줄 수 있는 Factory
	SqlSessionFactory sqlSessionFactory = SqlSessionManager.getSqlSession();
	// Factory를 사용해서 세션 생성(DB연결, close(), sql실행)
	SqlSession sqlSession = sqlSessionFactory.openSession(true); // (true)적으면  auto commit 
	
	// 회원가입 메소드
	public int join(MemberDTO dto) {
	int cnt = 0;
		try {
			cnt = sqlSession.insert("database.Mapper.join", dto);
			
		}catch (Exception e) {
			
		}finally {
			sqlSession.close();
		}
		return cnt;
		
//	   auto commit 안하면 이거 적어야됨	
//		if(cnt>0) {
//			// 회원가입 성공
//			sqlSession.commit();
//		} else {
//			// 회원가입 실패
//			sqlSession.rollback();
//		}		
	}

	// 로그인 메소드
	public String login(MemberDTO dto) {
		String name = null;
	try {
		name = (String)sqlSession.selectOne("database.Mapper.login",dto);
		
	} catch (Exception e) {
		
	} finally {
		sqlSession.close();
	}
		return name;
	}
	
	// 회원정보 리스트 출력
	public List<MemberDTO> memberList() {
		List<MemberDTO> list = null;
		try {
			list = sqlSession.selectList("database.Mapper.memberList");
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			sqlSession.close();
		}
		return list;
	}
}

3. Join,jsp -> JoinProgram.java로 보내기
// post방식 인코딩
	request.setCharacterEncoding("UTF-8");
	
	// 요청데이터 3개 가져오기
	String id = request.getParameter("id");
	String pw = request.getParameter("pw");
	String name = request.getParameter("name");
	
	MemberDTO dto = new MemberDTO(id, pw, name);
	
	int cnt = new MemberDAO().join(dto);
	
	System.out.println(cnt);
	
	String result = "";
	if(cnt>0) {
		// 회원가입 성공
		result = "success";
	}
	else {
		// 회원가입 실패
		result = "fail";
	}
	response.sendRedirect("Main.jsp?result="+result);
	}
}
 
4. Login.jsp -> LogoinProgram.java로 보내기
public class LoginProgram extends HttpServlet {	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	
	request.setCharacterEncoding("UTF-8");
	
	String id = request.getParameter("id");
	String pw = request.getParameter("pw");
	
	MemberDTO dto = new MemberDTO(id, pw);
	
	String name = new MemberDAO().login(dto);
	System.out.println(name);
	
	if(name != null) {
//		RequestDispatcher rd = request.getRequestDispatcher("loginSuccess.jsp");
//		
//		request.setAttribute("name", name);
//		rd.forward(request, response);		
		HttpSession session =  request.getSession();
		session.setAttribute("name", name);
		response.sendRedirect("loginSuccess.jsp");
	} else {
		response.sendRedirect("loginFail.jsp");
	}
}
}

5-1 LoginSuccess
<%
	//String name = (String) request.getAttribute("name");
	 String name = (String)session.getAttribute("name");
	%>
	
		<p>로그인 성공!</p>
	<%=name %>님 환영합니다~!
    
5-2. LoginFail
<fieldset>
<h2 align="center">로그인 실패</h2><br>
	<a href="./Main.jsp"><button> 메인 </button></a>
	<a href="./Login.jsp"><button> 로그인 </button></a>
</fieldset>

MessageSystem_board 실습

EL문법 안될때는 가장위에 @page isELIgnored="false"적기
mybatis-config 주소값 수정하기
as 만드려면 config에서 typeAliases안에 typeAlias 만들어서 type에 이름적고, alias해서 별명 적기
테이블 생성 및 회원가입 만들기

1. sql.sqld 테이블 생성(Type,Name,DB)
create table web_member(
	email varchar2(100) primary key,
	pw varchar2(100),
	tel varchar2(100),
	address varchar2(100)
);
-- 
insert into web_member values('test', 'test', 'test', 'test');

select * from web_member;

commit

2. 회원가입 만들기
Main.jsp에서
회원가입쪽에서 name값 주기

JoinService.java
1) post방식 인코딩
request.setCharacterEncoding("UTF-8");
2) 요청데이터 받기
String email = request.getParameter("email");
		String pw = request.getParameter("pw");
		String tel = request.getParameter("tel");
		String address = request.getParameter("address");
	
Member vo = new Member(email, pw, tel, address);

=> Member.java 이동해서 생성자 적기
@AllArgsConstructor
@Getter
@NoArgsConstructor
@ToString   
위에 적기.

System.out.println(vo.toString());
insert는 숫자로 반환 되니까 int cnt!!	
		int cnt = new MemberDAO().joinMember(vo);
		
		System.out.println("cnt : " + cnt);

=> MemberDAO로 이동하기
<MemberDAO>
// 세션을 생성해 줄 수 있는 Factory 생성
	SqlSessionFactory sqlSessionFactory = SqlSessionManager.getSqlSession();
	
	// connection, close, sql문 실행...
	SqlSession sqlSession = sqlSessionFactory.openSession(true);
	
	// 회원가입
	public int joinMember(Member vo) {
		int cnt = 0;
		
		try {
			cnt = sqlSession.insert("com.smhrd.database.MemberMapper.joinMember", vo);
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			sqlSession.close();
		}
		
		return cnt;
<MemberMapper> DAO랑 id값만 동일하게 해주면됨
<insert id="joinMember" parameterType="Member">
		insert into web_member values(#{email}, #{pw}, #{tel}, #{address})
	</insert>
    
<JoinService.java>        
		if(cnt>0) {
		// sendredirect방식 
        // response.sendRedirect("JoinSuccess.jsp?email="+email);
			RequestDispatcher rd = request.getRequestDispatcher("JoinSuccess.jsp");
			request.setAttribute("email", email);
			rd.forward(request, response);
		} else {
			response.sendRedirect("Main.jsp");
		}
	}
}

<JoinSuccess.jsp>
받아온 값 email대로 출력
그냥 표현식으로 쓸꺼면
String email = request.getParameter("email");
위에 사용하고 사용
EL표기법으로 쓸꺼면 필요없음
${email}입니다. 이렇게 사용.

로그인 만들기

<LoginService.java>
	request.setCharacterEncoding("UTF-8");
	// 1. email, pw 가져오기(post 인코딩)
		String email = request.getParameter("email");
		String pw = request.getParameter("pw");
		
		// 2. Member 객체 생성하기
		Member vo = new Member(email,pw);
        => 이거하고 Member.java 이동해서
        @requiredArgsConstructor적고 NonNull적기
		// 3. DAO LoginMember() 메소드 호출
		Member loginMember = new MemberDAO().loginMember(vo); 

=> MemberDAO로 이동하기!
public Member loginMember(Member vo) {
		Member loginMember = null;
		try {
			loginMember = sqlSession.selectOne("com.smhrd.database.MemberMapper.loginMember", vo);
		} catch (Exception e) {
		}finally {
			sqlSession.close();
		}
		return loginMember;
	}	
=> <MemberMapper>    
 <select id="loginMember" parameterType="Member" resultType="Member">
	select * from web_member where email=#{email} and pw=#{pw}
	</select>   
<LoginService.java>		
		if(loginMember != null) {
			// 로그인 성공
			HttpSession session = request.getSession();
			session.setAttribute("loginMember", loginMember);
			System.out.println("로그인 성공!");
		}
		response.sendRedirect("Main.jsp");
		
		// 4. DB에 있는 값 가져와서 콘솔창에 tel값만 출력하기
        
<main.jsp>
<body>
// 받아진 session값 가져오기
	<%
	Member loginMember = (Member)session.getAttribute("loginMember");
	
	if(loginMember != null){
	System.out.print(loginMember.getEmail());
	}
	%>
<%	if(loginMember == null){	%>		
<h1>로그인 한 세션아이디를 출력해주세요</h1>
<% }else{ %>
<h1><%=loginMember.getEmail() %>님 환영합니다. </h1>
<%}%>         

중복확인

<main.jsp>
<script type="text/javascript">
				function checkE() {
				var inputE =  $('#inputE').val();
				console.log(inputE)
				
				$.ajax({
					// 어디로 요청할 것인지
					url : 'EmailCheckService',
					// 요청 데이터(json)
					data : {'inputE' : inputE},
					// 요청방식
					type : 'get',
					// 요청 성공시
					success : function(data){
						
						if(data == 'true'){
							$('#resultCheck').text('사용할 수 없는 아이디')
						}else{
							$('#resultCheck').text('사용할 수 있는 아이디')
						}
					} ,
					// 요청 실패시 
					error : function(){
						alert("통신실패")
					}
					
				})
				}
			</script>
            
<EmailCheckService.java>
String inputE = request.getParameter("inputE");
	
	System.out.println(inputE);
	
	new MemberDAO().emailCheck(inputE);
	
	boolean checkE = new MemberDAO().emailCheck(inputE);
	System.out.println(checkE);
	
	PrintWriter out = response.getWriter();
	out.print(checkE);
	}
<MemberMapper>
<select id="emailCheck" parameterType="String" resultType="boolean">
	select case when count(*)>0 then 1
				else 0
			end result
	from web_member where email=#{email}	
	</select>

로그아웃

<LogoutService.java>
HttpSession session = request.getSession();
	// 전체 다 지우기
	//session.invalidate();
	session.removeAttribute("loginMember");	
	response.sendRedirect("Main.jsp");
		

업데이트 멤버

<UpdateMember.jsp>
name수정하고 value값 넣기
<li><input type="text" name="tel" value="<%=loginMember.getTel() %>" placeholder="전화번호를 입력하세요" style="width: 500px; margin: 0 auto;"></li>

<UpdateService.java>
// 1. post방식 인코딩
	request.setCharacterEncoding("UTF-8");
	// 2. 요청데이터 가져오기
	String email = request.getParameter("email");
	String pw = request.getParameter("pw");
	String tel = request.getParameter("tel");
	String address = request.getParameter("address");
	// 3. Member객체 생성
	Member updateMember = new Member(email, pw, tel, address);
	// 4. DAO에 있는 updateMember() 호출 -> 정수데이터 반환
	int cnt = new MemberDAO().updateMember(updateMember);
	
	// 5. 콘솔창에 수정 성공
	if(cnt>0) {
		System.out.println("수정 성공");
		HttpSession session = request.getSession();
		session.setAttribute("loginMember", updateMember);
		response.sendRedirect("Main.jsp");
	}else {
		System.out.println("수정 실패");
		response.sendRedirect("UpdateMember.jsp");
	}
}}
<MemberMapper.xml>
</select>
	<update id="updateMember" parameterType="Member">
	update web_member set pw=#{pw}, tel=#{tel}, address=#{address}
	where email=#{email}	
	</update>
<MemberDAO.java>
public int updateMember(Member updateMember) {
		int cnt = 0;
		try {   
			cnt = sqlSession.update("com.smhrd.database.MemberMapper.updateMember", updateMember);
		} catch (Exception e) {
			
		} finally{
			sqlSession.close();
		} return cnt;
	}

테이블에 저장된 모든 회원 출력하기

<ShowMember.jsp>
Q10. 테이블에 저장된 모든 회원의 이메일(email),전화번호(tel),주소(address)를 출력하시오.
<%
	List<Member> members = new MemberDAO().allMember();
	System.out.print(members.size());%>
<% for(int i=0; i<members.size(); i++){ %>
	<tr>
		<td><%=members.get(i).getEmail() %></td>
		<td><%=members.get(i).getTel() %></td>
		<td><%=members.get(i).getAddress()%> </td>							
	<!--  쿼리 스트링 : url?name=value&name=value-->
	<td><a href="DeleteService?email=<%=members.get(i).getEmail()%>">삭제</a></td>
	</tr>
<%}%>
<MemberMapper.xml>
<select id="allMember" resultType="Member">
	select * from web_member where not(email='admin')
	</select>

<MemberDAO.java>
public List<Member> allMember() {
		List<Member> members = null;
		try {
		members	 = sqlSession.selectList("com.smhrd.database.MemberMapper.allMember");
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			sqlSession.close();
		}
		return members; 
	}  

삭제

<DeleteService.java>
String email = request.getParameter("email");
		
		// 3. Member객체 생성
		// email하나만 하면 돼서 객체 생성 필요 없음
		// 4. DAO에 있는 updateMember() 호출 -> 정수데이터 반환
		int cnt = new MemberDAO().deleteMember(email);
		
		// 5. 콘솔창에 수정 성공
		if(cnt>0) {
			System.out.println("삭제 성공");
		}else {
			System.out.println("삭제 실패");
		}
response.sendRedirect("ShowMember.jsp");
	}
    
<MemberDAO.java>
public int deleteMember(String email) {
		int cnt = 0;
		try {
			cnt = sqlSession.delete("com.smhrd.database.MemberMapper.deleteMember",email);
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			sqlSession.close();
		}
		return cnt;
	}
    
<MemberMapper.xml>
<delete id="deleteMember" parameterType="String">
	delete from web_member where email=#{email}
	</delete>    

Board실습 (전꺼에서 안해본것들만)

새로운 BoardMapper 만들었으니까 config가서 resource 추가해주기, alias도 추가하기
file을 Back_WebStudy .metadata ->server.core 로 쭉 들어가서 wepapp에 파일생성하기

<BoardWrite.jsp>
<!--  enctype
				1) application/x-www-form-urlencoded
					-> form태그 안에서 보내는 요청데이터를 Key값과 Value값을 쌍으로 보냄 
				2) multipart/form-data
					-> 사진파일과 같이 용량이 큰 데이터(파일)을 보낼 때 사용(무조건 post방식으로 보내야 함)  -->
			
			<div id = "board">
				<form action="BoardService" method="post" enctype="multipart/form-data">
file을 Back_WebStudy .metadata ->server.core 로 쭉 들어가서 wepapp에 파일생성하기

<BoardMain.jsp>
// forEach문 연습
<c:forEach var="b" items="${boards}" varStatus="s">
			<tr>
			 	 <td>${s.count}</td>
                 <td><a href="BoardDetail.jsp?num=${b.num}">${b.title}</a></td>
                 <td>${b.writer}</td>
                 <td>${b.b_date}</td>
            </tr>
		</c:forEach>
 		
<%-- 	<%

	List<Board> boards = new BoardDAO().allBoard();

	System.out.print(boards.size());%>
	<% for(int i=0; i<boards.size(); i++){ %>
			<tr>
				<td><%=i+1%>
				<td><%=boards.get(i).getTitle() %></td>
				<td><%=boards.get(i).getWriter() %></td>
				<td><%=boards.get(i).getB_date()%></td>
			</tr>
	<%}%>	
	--%>
    
<BoardService.java>
// 파일 업로드를 위한 변수 설정
	// 1. request 객체
	// 2. 파일을 저장할 경로(String)
	String savePath = request.getServletContext().getRealPath("file");
	System.out.println("savePath :" + savePath);
	// 3. 파일 최대 크기(int)
	int maxSize = 1024 * 1024 * 10;
	
	// 4. 인코딩 방식
	String encoding = "UTF-8";
	
	// 5. 인코딩 방식(String)
	DefaultFileRenamePolicy rename = new DefaultFileRenamePolicy();
	// 6. 파일이름 중복제거
	
	// 파일 업로드 해주는 객체 -> MultipartRequest
	
	MultipartRequest multi = new MultipartRequest(request, savePath, maxSize, encoding, rename);
	
	// 요청 데이터 받아오기
	String title = multi.getParameter("title");
	String writer= multi.getParameter("writer");
	String filename = multi.getFilesystemName("filename");
	String content = multi.getParameter("content");

	Board vo = new Board(title, writer, filename, content);
	System.out.println(vo.toString());

	
	//DB에 넣어주기
	int cnt = new BoardDAO().writeBoard(vo);
	
	if(cnt>0) {
		System.out.println("게시글 작성 성공");	
	} else {
		System.out.println("게시글 작성 실패");
	}
	response.sendRedirect("BoardMain.jsp");
}

<BoardDetail.jsp>
<%
				// num : 게시글을 식별할 수 있는 고유 번호
			int num = Integer.parseInt(request.getParameter("num"));
			Board board = new BoardDAO().detailBoard(num);
			%>	
	<div id = "board">
		<table id="list">
			<tr>
				<td>제목</td>
				<td><%=board.getTitle() %></td>
			</tr>
			<tr>
				<td>작성자</td>
				<td><%=board.getWriter() %></td>
			</tr>
					
			<tr>
					<td>다운로드</td>
					<td><a href="./file/<%board.getFilename();%>" download><%=board.getFilename()%></a></td>
			</tr>
			<tr>
					<td colspan="2">
							<h3><%=board.getContent() %></h3>
							<img alt="" src="./file/<%=board.getFilename()%>">
					</td>
			</tr>

조회는 forward 방식으로 다른거는 sendredirect 방식이 적절

메시지 보내기, 삭제하기

<ul class="actions">
					   	<!--	Q12. 로그인 이메일 출력! -->  
										<c:choose>
                                        <c:when test="${loginMember == null}">
                                        	<li>로그인을 하세요.</li>
                                            </c:when>
											<c:otherwise>
												<li> ${loginMember.email} 님에게 온 메시지</li>
										<!-- Q14. 메시지 전체 삭제 기능 -->
                                        <li><a href="DelMessageAllService?recipient=${loginMember.email}" class="button next scrolly">전체삭제하기</a></li>	
											</c:otherwise>
										</c:choose>
									
									</ul>
									<!-- Q13. table형태로 나한테 온 메시지만 가져와서 보여주기
											 번호, 보낸사람, 내용, 시간 -->
									
									
									<!--  메시지 조회하기 -->	
									<c:if test="${loginMember != null}">
										<c:set var="m_list" value="${MessageDAO.showMessage(loginMember.email)}">
										</c:set>
									</c:if>	 
									<table>
										<tr>
											<th> 번호 </th>
											<th> 보내는 사람 </th>
											<th> 내용 </th>
											<th> 시간 </th>
											<th> 삭제 </th>
										</tr>
										<c:forEach var="m" items="${m_list}" varStatus="s">
											<tr>
												<td> ${s.count}  </td>
												<td> ${m.sender} </td>
												<td> ${m.message}</td>
												<td> ${m.m_date} </td> 
												<td><a href="DelMessageService?num=${m.num}"> 삭제</a> </td> 
											</tr>
										</c:forEach>
										</table>		 

메시지 보내기

<MessageService>
// post방식 디코딩
	request.setCharacterEncoding("UTF-8");
	
	// 받아오기
	String sender = request.getParameter("sender");
	String recipient = request.getParameter("recipient");
	String message = request.getParameter("message");

	System.out.println(sender + recipient + message);
	
	// 객체 생성
	Message vo = new Message(0, sender, recipient, message, null);
	int row = new MessageDAO().insertMessage(vo);

	if(row >0) {
		System.out.println("메시지 전송 성공");
	} else {
		System.out.println("메시지 전송 실패");
	}
	response.sendRedirect("./Main.jsp");
<MessageMapper>
Mapper추가 했으니까 config에 추가하기.
	<insert id="insertMessage" parameterType="Message">
	insert into web_message values(num_message.nextval, #{sender}, #{recipient}, #{message}, sysdate)
	</insert>
	<select id="showMessage" resultType="Message">
	select * from web_message where recipient=#{email} 
	</select>

	<delete id="deleteMessage" parameterType="Message">
	delete from web_message where num=#{num}
	</delete>
	
	<delete id="deleteAllMessage" parameterType="Message">
	delete from web_message where recipient=#{recipient}
	</delete>

<MessageDAO>
// 메시지 보내기 기능
	public int insertMessage(Message vo) {
		SqlSession session = sqlSessionFactory.openSession(true);
		int row = session.insert("insertMessage", vo);
		session.close();

		return row;
	}

	// 나에게 온 메시지 조회 기능
	public static List<Message> showMessage(String email) {
		SqlSession session = sqlSessionFactory.openSession(true);
		List<Message> m_list = session.selectList("showMessage", email);
		session.close();
		return m_list;

삭제하기(개별,전체)

<DelMessageService>
int num = Integer.parseInt(request.getParameter("num"));
	 
	 int cnt = new MessageDAO().deleteMessage(num);
	
		if (cnt>0) {
			System.out.println("삭제성공");
		}else {
			System.out.println("삭제실패");
		}
		response.sendRedirect("Main.jsp");

<DelMessageAllSerivce>
String recipient = request.getParameter("recipient");
		 int cnt = new MessageDAO().deleteAllMessage(recipient);
		
		if (cnt>0) {
			System.out.println("전체삭제성공");
		}else {
			System.out.println("전체삭제실패");
		} 
		response.sendRedirect("Main.jsp");
		
	}
<MessageDAO>
public int deleteMessage(int num) {
		SqlSession session = sqlSessionFactory.openSession(true);
		int row = session.delete("deleteMessage",num);
		session.close();		
		return row;
	}

	public int deleteAllMessage(String email) {
		SqlSession session = sqlSessionFactory.openSession(true);
		int row = session.delete("deleteAllMessage", email);
		session.close();
		return row;
	}
    
<MessageMapper>
<delete id="deleteMessage" parameterType="Message">
	delete from web_message where num=#{num}
	</delete>
	
	<delete id="deleteAllMessage" parameterType="Message">
	delete from web_message where recipient=#{recipient}
	</delete>

frontcontroller 생성하고 java class로 나누기 => 객체 지향적이라서 오류가 나도 오류 아닌 부분 실행가능
<BoardService.java> try문 안에 전부 넣기
<EmailCheckService.java> return값이 null이기 때문에
에서 if(moveURL != null) {response.sendRedirect(moveURL);}를 써줘야
통신실패가 뜨지 않는다.

<frontcontroller.java>
package com.smhrd.frontcontroller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.smhrd.controller.BoardService;
import com.smhrd.controller.DelMessageAllService;
import com.smhrd.controller.DelMessageService;
import com.smhrd.controller.DeleteService;
import com.smhrd.controller.EmailCheckService;
import com.smhrd.controller.JoinService;
import com.smhrd.controller.LoginService;
import com.smhrd.controller.LogoutService;
import com.smhrd.controller.MessageService;
import com.smhrd.controller.UpdateService;

@WebServlet("*.do")
public class frontcontroller extends HttpServlet {
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		System.out.println("[frontcontroller]");

		// 어떤 요청이 들어왔는지 확인
		String requestURI = request.getRequestURI();
		System.out.println("요청이 들어온 주소 : " + requestURI);

		// ContextPath 확인
		String contextPath = request.getContextPath();
		System.out.println("ContextPath : " + contextPath);

		// 문자열 자르기
		// subString(start) : start 위치부터 끝가지 문자열 자르기
		// subString(start,end) : start 위치부터 end 전까지 문자열 자르기

		String result = requestURI.substring(contextPath.length());
		System.out.println("요청 서블릿 : " + result);
		request.setCharacterEncoding("UTF-8");

		String moveURL = null;
		command service = null;

		if (result.equals("/LoginService.do")) {
			service = new LoginService();
		} else if (result.equals("/JoinService.do")) {
			service = new JoinService();
		} else if (result.equals("/LogoutService.do")) {
			service = new LogoutService();
		} else if (result.equals("/MessageService.do")) {
			service = new MessageService();
		} else if (result.equals("/DelMessageAllService.do")) {
			service = new DelMessageAllService();
		} else if (result.equals("/DelMessageService.do")) {
			service = new DelMessageService();
		} else if (result.equals("/UpdateService.do")) {
			service = new UpdateService();
		} else if (result.equals("/BoardService.do")) {
			service = new BoardService();
		} else if (result.equals("/EmailCheckService.do")) {
			service = new EmailCheckService();
		} else if (result.equals("/DeleteService.do")) {
			service = new DeleteService();
		}

		moveURL = service.execute(request, response);
		if(moveURL != null) {
			response.sendRedirect(moveURL);
		}
	}
}

<command.java>
public interface command {

	// 인터페이스 : 틀 
	// 추상메소드 : 값은 없지만 메소드의 기본 값을 설정해주는 역할
	public String execute(HttpServletRequest request, HttpServletResponse response);
}
<BoardService.java> 
public class BoardService implements command {

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) {
		// 파일 업로드를 위한 변수 설정
					// 1. request 객체
					// 2. 파일을 저장할 경로(String)
					String savePath = request.getServletContext().getRealPath("file");
					System.out.println("savePath :" + savePath);
					// 3. 파일 최대 크기(int)
					int maxSize = 1024 * 1024 * 10;

					// 4. 인코딩 방식
					String encoding = "UTF-8";
					// 5. 인코딩 방식(String)
					DefaultFileRenamePolicy rename = new DefaultFileRenamePolicy();
					// 6. 파일이름 중복제거
					// 파일 업로드 해주는 객체 -> MultipartRequest

					MultipartRequest multi;
					try {
						multi = new MultipartRequest(request, savePath, maxSize, encoding, rename);
						String title = multi.getParameter("title");
						String writer = multi.getParameter("writer");
						String filename = multi.getFilesystemName("filename");
						String content = multi.getParameter("content");
						Board vo = new Board(title, writer, filename, content);
						System.out.println(vo.toString());
						
						// DB에 넣어주기
						int cnt = new BoardDAO().writeBoard(vo);
						if (cnt > 0) {
							System.out.println("게시글 작성 성공");
						} else {
							System.out.println("게시글 작성 실패");
						}
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

					// 요청 데이터 받아오기


					return "BoardMain.jsp";
profile
스인개 본점 빅데이터 과정

0개의 댓글