이번 예는 간단한 JSP 기능들을 이용한 페이지들을 사용해보자.


테이블 구조는 다음과 같다.







총 4가지의 페이지를 볼 수 있는데 01_sum은 연산의 결과가 오류일 때 정해진 오류 페이지를 보여준다.


페이지를 열 때 브라우저에 400번대 에러와 500번대 에러는 흔히 볼 수 있는데


500번대 에러는 서버측의 에러이기 때문에 해커가 현재 서버가 어떤 문제가 있는지 코드에 어떤 오류가 있는지


알 수 있기 때문에 500번 오류는 노출하지 않는걸 권장한다.




두번째로 02_date인데 웹브라우저에서 자주 사용하는 날짜 함수를 JSP에서 어떻게 사용하는지 확인해보자.



세번째로 03_fortune은 다른 페이지(jsp 파일)를 불러와 현재 페이지에 포함(include)하는 방법을 확인해보자



네번째 04_menu는 간단하게 get방식으로 값을 넘겨서 연산처리를 하여 결과를 확인해보자.






index.jsp



<%@ 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>
    <h1>JSP 테스트</h1>
    <h3><a href="views/01_sum.jsp">테스트1</a></h3>
    <h3><a href="views/02_date.jsp">테스트2</a></h3>
    <h3><a href="views/03_fortune.jsp">테스트3</a></h3>
    <h3><a href="views/04_menu.jsp">테스트4</a></h3>
</body>
</html>










01_sum.jsp




<%-- directive page : 페이지 지시자 태그'<%@' --%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%--
        아래의 코드(System.out.println)를 보면 에러가 발생하는 구문이다.
        실행하면 에러페이지에 아래 코드가 출력이 되는데 코드가 그대로 노출되기 때문에 보안에 매우 취약하다.
        따라서 에러 페이지를 따로 지정하면 된다.
    --%>
    <%@ page errorPage="errorPage.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<%-- JSP는 동적 컴파일을 지원하기 때문에 변경사항이 있어도 서버를 껏다 킬 필요가 없다. --%>
<body>
    <%-- JSP 주석 '<%--' --%>
    <!-- HTML 주석 -->
   
   
   
    <%-- Scripting Element 1 : scriptlet --%>
    <%-- <%로 시작해서 %>로 끝나는 것을 스크립틀릿이라고 부른다. --%>
    <%
        int total = 0;
       
        for(int i = 1; i <= 10; i++){
            total += i;
        }
       
        // 아래의 코드를 보면 에러가 발생하는 구문이다.
        // 실행하면 에러페이지에 아래 코드가 출력이 되는데
        String s = null;
        System.out.println(s.charAt(0));
    %>
   
   
   
    <%-- Scripting element 2 : expression 기능은 자바 코드에서 작성한 결과값을 출력한다. --%>
    <%-- expression 태그는 세미콜론이 있으면 에러가 난다. --%>
    <h4>1부터 10까지의 합은 : <span style="color: red; font-size: 16pt; "><%= total %></span></h4>
    <h4>1부터 10까지의 합은 : <span style="color: red; font-size: 16pt; "><% out.println(total); %></span></h4>
    <%-- out은 선언하지 않았는데 사용할 수 있음 - 내장객체이므로 가능 --%>
</body>
</html>





errorPage.jsp



<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1>에러페이지</h1>
    <h3>에러 종류 : <%= exception.getClass().getName() %></h3>
</body>
</html>











02_date.jsp




<%@page import="java.util.Date"%>
<%@ 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>
    <%
        Date now = new Date();
       
        String date = String.format("%tF", now);
        String time = String.format("%tp %tT", now, now);
        String today = String.format("%tY년 %tm월, %td일, %tA", now, now, now, now);
       
        /*
        날짜 타입           설명
        ------------------------------------------
        %tF          날짜를 yyyy-mm-dd 형식으로 포맷
        %tT          날짜의 시각을 HH:MM:SS 형식으로 포맷
        ------------------------------------------
        %tY          4자리 년도만 출력
        %ty          2자리 년도만 출력
        %tB          월의 이름 영문(January, Febuary, ....)
        %tm          월을 숫자로 (01, 02, 03 ~ 12)
        %td          일수를 1 ~ 31로 표현
        %te          %td와 같다.
        %tA          요일명 출력
        ------------------------------------------
        %tp          오전, 오후 출력
        %tk          시간을 0 ~ 23 으로 출력
        %tl          시간을 1 ~ 12로 출력
        %tM          분을 00 ~ 59로 출력
        %tS          초를 00 ~ 59로 출력
        ------------------------------------------
        */
    %>
   
    <ul style="list-style: decimal;">
        <li>오늘의 날짜 : <%= date %></li>
        <li>현재 시간 : <%= time %></li>
        <li>오늘은 <span style="color: red;"><%= today %></span>입니다.</li>
       
    </ul>
</body>
</html>










03_fortune.jsp



<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%--
<%
    Date now = new Date();
    String today = String.format("%tY년 %tm월 %td일 %tA", now, now, now, now);
%>
--%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <%-- <h2>오늘의 운세<sub style="color:lightgray"><%= today %></sub></h2> --%>
    <h2>오늘의 운세<%@ include file="today.jsp" %></h2>
    <%-- 위의 date 때문에 오류가 나기 때문에 주석으로 감싼다. --%>
    <select>
        <option>쥐띠</option>
        <option>소띠</option>
        <option>호랑이띠</option>
        <option>토끼띠</option>
        <option>용띠</option>
        <option>뱀띠</option>
        <option>말띠</option>
        <option>양띠</option>
        <option>원숭이띠</option>
        <option>닭띠</option>
        <option>개띠</option>
        <option>돼지띠</option>
    </select>
   
</body>
</html>






today.jsp




<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    Date now = new Date();
    String today = String.format("%tY년 %tm월 %td일 %tA", now, now, now, now);
%>
<%-- include 전용 파일에 HTML 코드들이 있으면 다같이 딸려가기 때문에 지워둔다. iframe과 유사 --%>
<sub style="color: lightgray;"><%= today %></sub>











04_menu.jsp




<%@ 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>
    <h2>오늘의 메뉴<%@ include file="today.jsp" %></h2>
   
    <!--  13번째 줄과 14번째 줄은 같은 의미 -->
    <!-- <form action="/w4/menu.Order.do" method="get" name="menuFrm"></form> -->
    <form action="<%= request.getContextPath() %>/menuOrder" method="get" name="menuFrm">
        <select id="menu" name="menu">
            <option value="햄버거">햄버거</option>
            <option value="짜장면">짜장면</option>
            <option value="짬뽕">짬뽕</option>
            <option value="순대국">순대국</option>
        </select>
        <input type="submit" value="선택완료">
    </form>
   
</body>
</html>











MenuOrderServlet.java




package com.kh.servletTest.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;

@WebServlet("/menuOrder")
public class MenuOrderServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
      
    public MenuOrderServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 전송값에 한글이 있을 경우 인코딩 처리 해야 함, 그냥 항상 하자
        request.setCharacterEncoding("utf-8");
       
        // 2. 전송갑 꺼내서 변수에 기록하기
        String menu = request.getParameter("menu");
       
        // 3. 비지니스 로직
        int price = 0;
        switch (menu) {
        case "햄버거":
            price = 5000;
            break;
        case "짬뽕":
            price = 4000;
            break;
        case "짜장면":
            price = 4500;
            break;
        case "순대국":
            price = 6000;
            break;
        }
       
        // 4. 실행 결과 처리 및 전송 (박싱이 자동으로 처리됨, 오토 박싱)
        request.setAttribute("menu", menu);
        request.setAttribute("price", price);
       
        RequestDispatcher view = request.getRequestDispatcher("views/04_menuResult.jsp");
       
        view.forward(request, response);
       
       
       
       
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}










04_menuResult.jsp





<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    String menu = (String)request.getAttribute("menu");
    int price = (int)request.getAttribute("price");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>감사합니다.</h2>
    주문하신 <%= menu %>의 결제 금액은 <%= price %>원 입니다.
</body>
</html>















번호별로 주목할 점은 위에서 설명한거와 같이 넘버별로 하나씩



01_sum <%@ page errorPage="errorPage.jsp" %>을 통해서 임의의 에러 페이지를 지정하고


errorPage.jsp에서는 <%= exception.getClass().getName() %>을 통해서 에러 코드(널포인터 익셉션)를 표시해준다






02_date는 <%%> 구문안에 Date를 사용하고 사용하기 위해서 상단에 import해야 하는것을 확인하자.


그 외 실제로 확인하는 방법은 주석문에 정리해두었다.






03_fortune은 <%@ include file="today.jsp" %>을 통해서 적절한 부분에 해당 jsp 파일을 불러온다.


불러올 파일의 내용을 전부 가져오기 때문에 HTML 태그라던가 head body 등 쓸모없는 부분은 지워서 작성한다.






네번째 04_menu는 JSP -> Servlet -> JSP 순으로 데이터의 흐름이 어떻게 움직이는지 확인해보자.





1. Tomcat이 페이지의 default 값 파일이 저장되어 있는 위치



톰캣을 이클립스 Server에 연동 시키면 프로젝트 구조에 다음과 같은 Servers라는게 생긴다




이 파일들이 전부 default 값으로 설정 해 둔 정보들이 담겨있는 파일이다.


예를 들어 페이지의 맨 첫번째 페이지를 지금까지 index.html으로 사용했는데


이것은 어디서 결정되는지 궁금했을거다.


이것은 위의 파일들에 담겨있는 정보들에 지정이 전부 되어있다.


또한 프로젝트에서 이 기본 정보들을 변경 할 수 있다.


이 파일들을 복사해서 프로젝트에 붙여넣고 내용을 바꾼다.(파일 이름은 절대 바꾸면 안된다.)


프로젝트에 동일한 이름의 파일이 있다면 톰캣은 default 파일들을 기준으로 잡지 않고


프로젝트에 있는 파일들의 설정을 따른다.





2. java 파일이 서버에 적용되는 원리


위의 사진에서 네모친 web.xml에 java 파일을 서버에 올리는 작업 대상이 될 폴더가 명시되어 있다.






다음과 같이 <context> 부분의 속성에 workDir="원하는 경로"를 입력하면


그 쪽에 java파일들이 컴파일러에 의해 처리가 되어 class 파일로 저장된다.










이번 예제는 get과 post의 차이를 확인해보자.


코드를 복사 붙여넣기를 하면 무조건 오류난다.


왜냐하면 코드에 경로 관련해서 정보를 많이 입력하기 때문에


한 줄 한 줄 복사 붙여넣기 하거나 읽으면서 해보길 권장.


폴더 구조는 다음과 같다.




프로그램 흐름과 작성 순서는


index.html - testPerson1.html


TestPersonServlet.java - result.jsp


testPerson2.html - TestPersonServlet2.java








index.html



<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1>서블릿 테스트</h1>
    <h2><a href="views/testPerson1.html">1. 개인 취향 테스트(get)</a></h2>
    <h2><a href="views/testPerson1.html">2. 개인 취향 테스트(post)</a></h2>
   
   
   
</body>
</html>





testPerson1.html



<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>개인 취향 테스트(GET)</h2>
    당신의 취향을 테스트 합니다.<br>
    데이터를 입력 후 확인 버튼을 누르세요<br>
   
    <form action="/w3/testPerson" name="personFrm" method="get">   
        <ul style="list-style: none; line-height: 200%">
            <li>이름은?
                <input type="text" name="name" size="10">
            </li>
            <li>좋아하는 색?
                <input type="radio" name="color" value="빨강" id="red">
                <label for="red">빨강</label>
                <input type="radio" name="color" value="파랑" id="blue">
                <label for="blue">파랑</label>
                <input type="radio" name="color" value="노랑" id="yellow">
                <label for="yellow">노랑</label>
                <input type="radio" name="color" value="초록" id="green">
                <label for="green">초록</label>
            </li>
            <li>좋아하는 동물은?
                <select name="animal">
                    <option value="강아지">강아지</option>
                    <option value="고양이">고양이</option>
                    <option value="병아리">병아리</option>
                </select>
            </li>
            <li>좋아하는 음식?(모두 고르세요)
                <input type="checkbox" name="food" id="food1" value="짜장면">
                <label for="food1">짜장면</label>
                <input type="checkbox" name="food" id="food2" value="짬뽐">
                <label for="food1">짬뽐</label>
                <input type="checkbox" name="food" id="food3" value="탕수육">
                <label for="food1">탕수육</label>
                <input type="checkbox" name="food" id="food4" value="양장피">
                <label for="food1">양장피</label>
                <input type="checkbox" name="food" id="food5" value="팔보채">
                <label for="food1">팔보채</label>
            </li>
            <li>
                <br>
                <input type="submit" name="btnOk" id="btnOk" value="확인">
                &nbsp; &nbsp;
                <input type="reset" value="취소">
            </li>
           
       
        </ul>
    </form>
</body>
</html>






TestPersonServlet.java




package controller;

import java.io.IOException;
import java.io.PrintWriter;

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


@WebServlet("/testPerson")
public class TestPersonServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
      
    public TestPersonServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 첫 번째 파라미터인 HttpServletRequest는
        // 웹 브라우저에서 사용자가 요청한 내용을 받아주는 용도로 쓰인다.
        // 두 번째 파라미터인 HttpServletResponse는
        // 첫 번째 파라미터에서 처리한 결과를 웹 브라우저를 통해 사용자에게 보여주기 위한 용도로 쓰인다.
       
        String name = request.getParameter("name");
        String color = request.getParameter("color");
        String animal = request.getParameter("animal");
       
        String[] foodArr = request.getParameterValues("food");
       
        System.out.println("name : " + name + "\r\n" +
                            "color : " + color + "\r\n" +
                            "animal : "+ animal);
       
        for (int i = 0; i < foodArr.length; i++) {
            System.out.println("foodArr [" + i + "] : " + foodArr[i]);
        }
       
        // Response 핸들링 : 화면출력
        response.setContentType("text/html; charset=UTF-8");
       
        PrintWriter out = response.getWriter();
       
        out.println("<html>"
                + "<head>"
                + "<title>개인 취향 테스트 결과 화면</title>"
                + "</head>"
                + "<body>"
                + "<h2 style='color: red;'>개인 취향 테스트 결과(GET)</h2>");
        out.printf("<span style='color: lightblue;'>%s</span>님의 개인 취향은 <br><br>", name);
        out.printf("<span style='color: lightgreen; font-weight: bold;'>%s</span>, <span style='color: lightred; font-weight: bold;'>%s</span>를 좋아합니다<br><br>", color, animal);
        out.println("좋아하는 음식은 ");
        for (int i = 0; i < foodArr.length; i++) {
            if (i == 0) {
                out.printf("%s", foodArr[i]);
            } else {
                out.printf(", %s", foodArr[i]);
            }
        }
        out.println("입니다."
                + "</body>"
                + "</html>");
       
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}



result.jsp




<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    String name = (String)request.getAttribute("name");
    String color = (String)request.getAttribute("color");
    String animal = (String)request.getAttribute("animal");
    String foods = (String)request.getAttribute("foods");
    String recommendation = (String)request.getAttribute("recommendation");
%>

<!DOCTYPE html>
<!-- 꺽쇠 + % 키워드로 자바 코드를 입력할 수 있다. -->
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>개인 취향 테스트 결과(POST) - jsp</h2>
    <span style="color: lightblue; font-weight: bold;"><%= name %></span>님의 개인 취향은
    <br><br>
    <span style="color: lightgreen; font-weight: bold;"><%= color %></span>색을 좋아하고
    <span style="color: lightred; font-weight: bold;"><%= animal %></span>를 좋아합니다.
    <br><br>
    좋아하는 음식은 <%= foods %>입니다.
    <br>
    <h3>둘리의 추천!</h3>
    <p><%= recommendation %> 어떠세요?</p>

</body>
</html>





testPerson2.html




<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>개인 취향 테스트(POST)</h2>
    당신의 취향을 테스트 합니다.<br>
    데이터를 입력 후 확인 버튼을 누르세요<br>
   
    <form action="/w3/testPerson2" name="personFrm" method="post">   
        <ul style="list-style: none; line-height: 200%">
            <li>이름은?
                <input type="text" name="name" size="10">
            </li>
            <li>좋아하는 색?
                <input type="radio" name="color" value="빨강" id="red">
                <label for="red">빨강</label>
                <input type="radio" name="color" value="파랑" id="blue">
                <label for="blue">파랑</label>
                <input type="radio" name="color" value="노랑" id="yellow">
                <label for="yellow">노랑</label>
                <input type="radio" name="color" value="초록" id="green">
                <label for="green">초록</label>
            </li>
            <li>좋아하는 동물은?
                <select name="animal">
                    <option value="강아지">강아지</option>
                    <option value="고양이">고양이</option>
                    <option value="병아리">병아리</option>
                </select>
            </li>
            <li>좋아하는 음식?(모두 고르세요)
                <input type="checkbox" name="food" id="food1" value="짜장면">
                <label for="food1">짜장면</label>
                <input type="checkbox" name="food" id="food2" value="짬뽐">
                <label for="food1">짬뽐</label>
                <input type="checkbox" name="food" id="food3" value="탕수육">
                <label for="food1">탕수육</label>
                <input type="checkbox" name="food" id="food4" value="양장피">
                <label for="food1">양장피</label>
                <input type="checkbox" name="food" id="food5" value="팔보채">
                <label for="food1">팔보채</label>
            </li>
            <li>
                <br>
                <input type="submit" name="btnOk" id="btnOk" value="확인">
                &nbsp; &nbsp;
                <input type="reset" value="취소">
            </li>
           
       
        </ul>
    </form>
</body>
</html>





TestPersonServlet2.java




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;

@WebServlet("/testPerson2")
public class TestPersonServlet2 extends HttpServlet {
    private static final long serialVersionUID = 1L;
      
    public TestPersonServlet2() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // request 문자셋 변경
        // 넘겨받은 데이터가 한글일 경우(영어가 아닐 경우) 인코딩 처리를 해야 한다.
        // [중요] request.getParameter()보다 먼저 기술해야 한다.
        request.setCharacterEncoding("UTF-8");
       
        String name = request.getParameter("name");
        String color = request.getParameter("color");
        String animal = request.getParameter("animal");
       
        String[] foodArr = request.getParameterValues("food");
       
        String foods = "";
       
        for (int i = 0; i < foodArr.length; i++) {
            if (i == 0) {
                foods += foodArr[i];
            } else {
                foods += ", " + foodArr[i];
            }
        }
       
       
        // 사용자가 좋아하는 색을 기준으로 상품을 추천해 줌
        String recommendation = "";
        switch (color) {
        case "빨강":
            recommendation = "빨간 페라리";
            break;
        case "노랑":
            recommendation = "노란 카레";
            break;
        case "초록":
            recommendation = "초록 붕어빵";
            break;
        case "파랑":
            recommendation = "파란 캔디바";
            break;
        }
       
        response.setContentType("text/html; charset=UTF-8");
       
        request.setAttribute("name", name);
        request.setAttribute("color", color);
        request.setAttribute("animal", animal);
        request.setAttribute("foods", foods);
        request.setAttribute("recommendation", recommendation);
       
        RequestDispatcher view
                = request.getRequestDispatcher("views/result.jsp");
        view.forward(request, response);
       
       
       
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}



특별히 어려운 부분은 없다.

JSP는 간단하게 이해하면 HTML + CSS + JS + JQ + java 문서이다.


그냥 html 부분은 모든 기능을 쓸 수 있는 방법이 있다고 이해하면 된다.


먼저 아래 표부터 보자



강사님께서 주신 자료에서 따온 표인데 형태가 정말 잘 표현되었다고 생각해서 가져왔다.


Servlet은 java 파일로 자바에서 HTML을 컨트롤 할 수 있다.


JSP의 경우는 HTML에서 JAVA를 컨트롤 한다.


Java에서 할 경우 HTML 코드를 컨트롤 할 수 있지만 매우 귀찮고 번거로운 노가다 작업이 된다.


JSP에선 좀 더 편하게 할 수 있다.


핵심 키워드는 <%%> 이다.


<%%> 키워드도 여러 종류가 있다.





<%-- 내용 --%> : 주석


<%@ 내용 %> : 다양한 페이지 설정들을 명시할 때 사용


<%! 내용 %> : JSP에서 선언시 사용


<% 내용 %> : java 코드들을 입력하는 부분


<%= 내용 %> : 표현식, 예로 설명 ------- <h1><%= 변수 %><h1>은 <h1>변수의 값<h1>과 같다.



아래 설명되는 객체, 메소드들은 Servlet의 내장 객체이다.




- get / post 방식 -


get방식은 쉽게 말해 주소줄에 입력하는 url에 데이터를 써서 다른 페이지에 전송한다.


값은 key=value형태로 전달된다.


주소줄을 보면 데이터가 바로 보이므로 보안에 취약하다.



post방식은 HTML 헤더와 함께 전송한다.


데이터가 가시적으로 보이지 않기 때문에 get 방식보다 보안에 좋다고 한다.


하지만 공부 좀 한다면 이 데이터를 보는 일은 쉽다고 하여 별 의미는 없는 것 같다.





- doGet / doPost -


doGet - doGet은 Servlet에서 get방식으로 전달 받았을 때 실행되는 메소드이다.


doPost - doPost는 Servlet에서 post방식으로 전달 받았을 때 실행되는 메소드이다.


하지만 하는 기능이 거의 유사해 블로그에서는 doPost로 받는 request와 response를 doGet(request, response)로 넘겨서


Get에서 기능을 통일한다.





- HttpServletRequest 메소드 -


HttpServletRequest는 요청정보를 제공한다. 즉, 페이지에서 전달 받은 여러 값들 같은게 들어있다.



getParameter(String) - 클라이언트가 보낸 값 중 매개변수 같은 명칭에 저장된 값을 골라서 반환


getParameterNames() - 클라이언트가 보낸 값 중 매개변수 같은 명칭들을 불러온다.


getParameterValues(String) - 불러온 값이 여러개일 경우 그 값을 배열로 반환


getParameterMap() - 불러올 매개변수들을 전부 Map으로 담아준다.


setAttribute(String, object) - request 객체에 전달하고 싶은 값을 String / Object 형태로 저장해준다.


getAttribute(String) - 매개변수와 동일한 객체 속성을 불러와준다.


removeAttribute(String) - String에 해당 되는 값을 삭제함


setCharacterEncoding(String) - request의 값들의 문자 타입을 설정(UTF-8, 왠만하면 이것을 쓰자.)


getRequestDispatcher(String) - request와 response 관련 메소드를 통해 전부 작업하고 전송할 데이터를 컴포넌트(.jsp 파일 등)를 불러오는 메소드


                                         forward() 메소드와 함께 쓰인다.





- HttpServletResponse 메소드 -


HttpServletResponse는 요청정보에 대한 처리결과를 작성하기 위해 사용하는 객체이다.



setContentType() - 문자 타입을 설정(UTF-8, 왠만하면 이것을 쓰자.)


setCharacterEncoding() - 문자 타입을 설정(UTF-8, 왠만하면 이것을 쓰자.), content와 무슨 차이인지 잘 모르겠다.


getWriter() - 문자를 페이지에 전송하기 위한 Stream을 가져온다. (PrintWriter와 함께 쓰인다. getWriter는 interface이기 때문에 혼자 생성될 수 없다.)


getOutputStream() - byte 단위로 페이지에 전송하는 stream


sendResdirect() - client가 매개변수 데이터들을 다시 서버에 요청하게 하는 메소드





- sendRedirect / encodeRedirectURLRequest -



encodeRedirectURLRequest는 매개변수에 대한 정보를 추가재요청 처리,


client가 별도의 다른 페이지 요청을 안해도 url이 변경된다.





- Dispatcher() ~ forward() -



요청 받은 데이터를 자기가 직접 다른 페이지에 전송 처리한다.


프로젝트 설명 전 서블릿과 jsp 템플릿 설명.











Servlet을 작성 할 때 오버라이드 할 메소드들이 정말 길었다.


하지만 위와 같이 메소드들을 골라서 한번에 추가 할 수있다.


생성된 java 파일(servlet 기능들이 임포트 된)은 정말 복잡해 보이는데


주석을 전부 지워버리면 보기 쉬워진다.


JSP에 대한 정보는 https://qdgbjsdnb.tistory.com/205?category=727563 에 설명







다음은 jsp 생성







위와 같이 생성되는데 필요없는 문구는 설정에서 다음과 같이 바꾸면 템플릿을 바꿀 수 있다.











JSP는 서블릿의 단점을 보안하기 위해 나왔다.


예제 1, 2를 보면 out.println와 같이 전부 "" 를 쓰면서 HTML 구문을 입력하여 페이지에 띄워 줬다


간단한 프로그램임에도 불구하고 정말 귀찮은 작업이다.


하지만 JSP는 HTML 문서에 자바 코드들을 직접 입력해서 구현할 수 있다.


testPerson1 은 get 방식을 이용한 정보 전달과 기존의 방법으로 servlet을 구현한다.


testPerson2의 경우는 JSP 방식으로 맵핑된 testPerson2 파일에서 result.jsp를 연결시킨다.


폴더구조는 다음과 같다.




index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>서블릿 테스트</h1>
	<h2><a href="views/testPerson1.html">1. 개인 취향 테스트(get)</a></h2>
	<h2><a href="views/testPerson1.html">2. 개인 취향 테스트(post)</a></h2>
	
	
	
</body>
</html>


testPerson1.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h2>개인 취향 테스트(GET)</h2>
	당신의 취향을 테스트 합니다.<br>
	데이터를 입력 후 확인 버튼을 누르세요<br>
	
	<form action="/w3/testPerson" name="personFrm" method="get">	
		<ul style="list-style: none; line-height: 200%">
			<li>이름은?
				<input type="text" name="name" size="10">
			</li>
			<li>좋아하는 색?
				<input type="radio" name="color" value="빨강" id="red">
				<label for="red">빨강</label>
				<input type="radio" name="color" value="파랑" id="blue">
				<label for="blue">파랑</label>
				<input type="radio" name="color" value="노랑" id="yellow">
				<label for="yellow">노랑</label>
				<input type="radio" name="color" value="초록" id="green">
				<label for="green">초록</label>
			</li>
			<li>좋아하는 동물은?
				<select name="animal">
					<option value="강아지">강아지</option>
					<option value="고양이">고양이</option>
					<option value="병아리">병아리</option>
				</select>
			</li>
			<li>좋아하는 음식?(모두 고르세요)
				<input type="checkbox" name="food" id="food1" value="짜장면">
				<label for="food1">짜장면</label>
				<input type="checkbox" name="food" id="food2" value="짬뽐">
				<label for="food1">짬뽐</label>
				<input type="checkbox" name="food" id="food3" value="탕수육">
				<label for="food1">탕수육</label>
				<input type="checkbox" name="food" id="food4" value="양장피">
				<label for="food1">양장피</label>
				<input type="checkbox" name="food" id="food5" value="팔보채">
				<label for="food1">팔보채</label>
			</li>
			<li>
				<br>
				<input type="submit" name="btnOk" id="btnOk" value="확인">
				&nbsp; &nbsp;
				<input type="reset" value="취소">
			</li>
			
		
		</ul>
	</form>
</body>
</html>


TestPersonServlet.java




package controller;

import java.io.IOException;
import java.io.PrintWriter;

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


@WebServlet("/testPerson")
public class TestPersonServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
      
    public TestPersonServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 첫 번째 파라미터인 HttpServletRequest는
        // 웹 브라우저에서 사용자가 요청한 내용을 받아주는 용도로 쓰인다.
        // 두 번째 파라미터인 HttpServletResponse는
        // 첫 번째 파라미터에서 처리한 결과를 웹 브라우저를 통해 사용자에게 보여주기 위한 용도로 쓰인다.
       
        String name = request.getParameter("name");
        String color = request.getParameter("color");
        String animal = request.getParameter("animal");
       
        String[] foodArr = request.getParameterValues("food");
       
        System.out.println("name : " + name + "\r\n" +
                            "color : " + color + "\r\n" +
                            "animal : "+ animal);
       
        for (int i = 0; i < foodArr.length; i++) {
            System.out.println("foodArr [" + i + "] : " + foodArr[i]);
        }
       
        // Response 핸들링 : 화면출력
        response.setContentType("text/html; charset=UTF-8");
       
        PrintWriter out = response.getWriter();
       
        out.println("<html>"
                + "<head>"
                + "<title>개인 취향 테스트 결과 화면</title>"
                + "</head>"
                + "<body>"
                + "<h2 style='color: red;'>개인 취향 테스트 결과(GET)</h2>");
        out.printf("<span style='color: lightblue;'>%s</span>님의 개인 취향은 <br><br>", name);
        out.printf("<span style='color: lightgreen; font-weight: bold;'>%s</span>, <span style='color: lightred; font-weight: bold;'>%s</span>를 좋아합니다<br><br>", color, animal);
        out.println("좋아하는 음식은 ");
        for (int i = 0; i < foodArr.length; i++) {
            if (i == 0) {
                out.printf("%s", foodArr[i]);
            } else {
                out.printf(", %s", foodArr[i]);
            }
        }
        out.println("입니다."
                + "</body>"
                + "</html>");
       
       
       
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}




위와 같이 입력하면 힘들지만 결과는 잘 나오긴 한다.


하지만 간단한 페이지에도 불구하고 고된 작업이 요구된다.


JSP를 사용하면 해결된다.










testPerson2.html


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>개인 취향 테스트(POST)</h2>
    당신의 취향을 테스트 합니다.<br>
    데이터를 입력 후 확인 버튼을 누르세요<br>
   
    <form action="/w3/testPerson2" name="personFrm" method="post">   
        <ul style="list-style: none; line-height: 200%">
            <li>이름은?
                <input type="text" name="name" size="10">
            </li>
            <li>좋아하는 색?
                <input type="radio" name="color" value="빨강" id="red">
                <label for="red">빨강</label>
                <input type="radio" name="color" value="파랑" id="blue">
                <label for="blue">파랑</label>
                <input type="radio" name="color" value="노랑" id="yellow">
                <label for="yellow">노랑</label>
                <input type="radio" name="color" value="초록" id="green">
                <label for="green">초록</label>
            </li>
            <li>좋아하는 동물은?
                <select name="animal">
                    <option value="강아지">강아지</option>
                    <option value="고양이">고양이</option>
                    <option value="병아리">병아리</option>
                </select>
            </li>
            <li>좋아하는 음식?(모두 고르세요)
                <input type="checkbox" name="food" id="food1" value="짜장면">
                <label for="food1">짜장면</label>
                <input type="checkbox" name="food" id="food2" value="짬뽐">
                <label for="food1">짬뽐</label>
                <input type="checkbox" name="food" id="food3" value="탕수육">
                <label for="food1">탕수육</label>
                <input type="checkbox" name="food" id="food4" value="양장피">
                <label for="food1">양장피</label>
                <input type="checkbox" name="food" id="food5" value="팔보채">
                <label for="food1">팔보채</label>
            </li>
            <li>
                <br>
                <input type="submit" name="btnOk" id="btnOk" value="확인">
                &nbsp; &nbsp;
                <input type="reset" value="취소">
            </li>
           
           
        </ul>
    </form>
</body>
</html>





TestPersonServlet2.java

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;

@WebServlet("/testPerson2")
public class TestPersonServlet2 extends HttpServlet {
    private static final long serialVersionUID = 1L;
      
    public TestPersonServlet2() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // request 문자셋 변경
        // 넘겨받은 데이터가 한글일 경우(영어가 아닐 경우) 인코딩 처리를 해야 한다.
        // [중요] request.getParameter()보다 먼저 기술해야 한다.
        request.setCharacterEncoding("UTF-8");
       
        String name = request.getParameter("name");
        String color = request.getParameter("color");
        String animal = request.getParameter("animal");
       
        String[] foodArr = request.getParameterValues("food");
       
        String foods = "";
       
        for (int i = 0; i < foodArr.length; i++) {
            if (i == 0) {
                foods += foodArr[i];
            } else {
                foods += ", " + foodArr[i];
            }
        }
       
       
        // 사용자가 좋아하는 색을 기준으로 상품을 추천해 줌
        String recommendation = "";
        switch (color) {
        case "빨강":
            recommendation = "빨간 페라리";
            break;
        case "노랑":
            recommendation = "노란 카레";
            break;
        case "초록":
            recommendation = "초록 붕어빵";
            break;
        case "파랑":
            recommendation = "파란 캔디바";
            break;
        }
       
        response.setContentType("text/html; charset=UTF-8");
       
        request.setAttribute("name", name);
        request.setAttribute("color", color);
        request.setAttribute("animal", animal);
        request.setAttribute("foods", foods);
        request.setAttribute("recommendation", recommendation);
       
        RequestDispatcher view
                = request.getRequestDispatcher("views/result.jsp");
        view.forward(request, response);
       
       
       
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}






result.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    String name = (String)request.getAttribute("name");
    String color = (String)request.getAttribute("color");
    String animal = (String)request.getAttribute("animal");
    String foods = (String)request.getAttribute("foods");
    String recommendation = (String)request.getAttribute("recommendation");
%>

<!DOCTYPE html>
<!-- 꺽쇠 + % 키워드로 자바 코드를 입력할 수 있다. -->
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>개인 취향 테스트 결과(POST) - jsp</h2>
    <span style="color: lightblue; font-weight: bold;"><%= name %></span>님의 개인 취향은
    <br><br>
    <span style="color: lightgreen; font-weight: bold;"><%= color %></span>색을 좋아하고
    <span style="color: lightred; font-weight: bold;"><%= animal %></span>를 좋아합니다.
    <br><br>
    좋아하는 음식은 <%= foods %>입니다.
    <br>
    <h3>둘리의 추천!</h3>
    <p><%= recommendation %> 어떠세요?</p>

</body>
</html>













TestPersonServlet2.java 서블릿 파일을 보면 아래의 부분이 있다.


        request.setAttribute("name", name);
        request.setAttribute("color", color);
        request.setAttribute("animal", animal);
        request.setAttribute("foods", foods);
        request.setAttribute("recommendation", recommendation);
       
        RequestDispatcher view
                = request.getRequestDispatcher("views/result.jsp");
        view.forward(request, response);




이 부분에서 JSP 파일로 전송할 변수들, 그리고 JSP의 위치를 지정해서 연결하게 된다.


JSP에서는 <% %> 키워드를 이용해서 기본 선언이나 속성 불러오기, 함수 사용등을 한다.


















JSP의 실행 코드는 클라이언트에서 볼 수 없다는 특징을 가진다. 주석 또한 마찬가지이다.






이 예에서 나온 <%%> 키워드는 다른 게시글에서 설명한다.












어노테이션을 이용한 방법


간단하지만 그만큼 파일이 많아지고 유지보수를 하기 위해서 찾기가 힘들어 질 수 있다.










xml에 mapping하는 방법은 xml파일에 전부 모아서 볼 수 있기 때문에 한눈에 들어오지만


코드가 길어 번거롭다.




이번에는 form 태그에 action 속성을 주어 method의 GET POST 방식이 어떤 차이가 있나 확인하고


화면에 결과를 띄우는 예이다.


구조는 다음과 같다.








--------- index.html


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1 align="center">My First Web Project</h1>
   
    <!-- action에는 서블릿 주소를 -->
    <!-- method get은 정보를 url로 넘긴다. -->
    <!-- post의 경우는 한글이 깨지므로 따로 처리를 해야 한다. -->
    <form action="/w2/test" method="post">
        <table align="center">
            <tr>
                <td>아이디</td>
                <td><input type="text" name="userId"></td>
                <td rowspan="2"><button type="submit" style="height: 50px;">로그인</button></td>
            </tr>
            <tr>
                <!-- password 타입은 한글을 지원하지 않는다, 자동으로 영문으로 변경 -->
                <td>비밀번호</td>
                <td><input type="password" name="password"></td>
            </tr>
           
       
       
        </table>
    </form>
</body>
</html>



post 부분을 get으로 바꿔가며 직접 실행해보자.




--------- TestServlet.java


package controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

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

public class TestServlet extends HttpServlet{

    public TestServlet() {}
   
   
   
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 한글이 깨지는 경우
        /*
        System.out.println("잘 왔다");
        String userId = request.getParameter("userId");
        String password = request.getParameter("password");
       
        System.out.println("ID : " + userId);
        System.out.println("Password : " + password);
        */
       
        // 한글 깨짐 방지(throw 필요)
        // 1. 전송 값에 한글이 있을 경우 처리할 수 있도록 인코딩 처리를 함
        request.setCharacterEncoding("utf-8");
        // 보내는 페이지의 <meta charset="UTF-8"> 형식과 같아야함
        // 새로 열릴 페이지 역시 utf 8 설정을 위해 아래와 같은 문구를 사용
        response.setContentType("text/html; charset=UTF-8");
        // 반드시 값을 꺼내오기 전에 명시를 해야함
       
        // 2. view 에서 보낸 전송값을 꺼내서 변수에 저장하기
        String userId = request.getParameter("userId");
        String password = request.getParameter("password");
       
        System.out.println("ID : " + userId);
        System.out.println("Password : " + password);
       
        // 3. 웹페이지에 스트림 연결(throw 필요)
        PrintWriter out = response.getWriter();
       
        // 4. 스트림을 통해 출력
        out.println("<html>"
                + "<head>"
                + "</head>"
                + "<body>"
                + "아이디 : " + userId + "<br>"
                + "패스워드 : " + password
                + "</body>"
                + "</html>");
        out.close();
    }
   
   
   
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        doGet(request, response);
    }
   
}



이번에는 어노테이션을 사용하지 않고 xml을 통해서 mapping을 진행한다.


또한 html 문서를 작성할 때 입력하는 charset utf-8을


java에서는 어떻게 입력하는지 Set Character Encoding 을 찾아 확인해보자.


--------- web.xml



<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>web-02</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
 
 
  <servlet>
    <servlet-name>test</servlet-name>
    <servlet-class>controller.TestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>test</servlet-name>
    <url-pattern>/test</url-pattern>
  </servlet-mapping>
 
 
</web-app>




  <servlet>
    <servlet-name>test</servlet-name>
    <servlet-class>controller.TestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>test</servlet-name>
    <url-pattern>/test</url-pattern>
  </servlet-mapping>


이 부분이 java와 html이 mapping되는 부분이다. 폴더 구조를 확인하면서 어떻게 쓰였는지 확인해보자.










Servlet은 웹페이지를 자바를 이용해 동적으로 동작하기 위한 기술이라고 이해하면 된다.


html 문서만 본다면 Servlet 사용전은 사용자 - html 문서의 관계가 되고


Servlet을 적용하면 사용자 - html 문서 - 서버의 java 프로그램이 된다.


예전에 환경할 때 사용했던 Tomcat 버전에 따라 지원하는 Servlet 버전이 다르기 때문에 호환이 되는지 알 필요가 있다.


Tomcat 홈페이지에 가면 알 수 있다.





블로그에서 사용한 톰캣은 8.5.35버전이다.


다음으로는 환경설정이다.


예전 Java Script 설정과 거의 비슷하나 조금 다른부분만 추가로 설명한다. JS 설정 -> https://qdgbjsdnb.tistory.com/162




설정을 쭉 따라하다가 아래와 같은 부분에서 체크박스 체크를 하는 부분이 있다.





이번에는 Java 파일도 사용하므로 Java도 체크한다.


첫번째 예제 Dynamic web Project는 다음과 같이 생성했다.





프로젝트 구성은 다음과 같이 만들었다.






index는 시작페이지


controller는 java 파일이 들어가 Servlet 역할을 할 파일이 된다.


예제의 내용은 처음 페이지에서 링크를 누르면 이클립스의 콘솔창에 첫번째 방문 시 문구가 출력이 되고


반복적으로 새로고침을 하면 출력되는 숫자가 점점 올라간다.







코드는 다음과 같다.


아래에서 사용될 메소드들은 (https://qdgbjsdnb.tistory.com/204?category=727563)에서 정리해놓았다.


index.html



<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<a href="/w1/cycle">라이프사이클 테스트하기</a>
</body>
</html>


LifeCycleServlet.java



package controller;

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

// 서블릿을 조금이라도 수정한다면 톰캣을 종료했다가 다시 작동시켜야 한다.

// 아래의 어노테이션을 입력하면 web.xml에 입력했던 연결과 같은 기능을 함.
@WebServlet("/cycle")
public class LifeCycleServlet extends HttpServlet{
	private int initCount = 1;
	private int doGetCount = 1;
	private int destroyCount = 1;
	
	public LifeCycleServlet() {}
	
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 메소드는 첫 요청시 한 번만 호출됨 : " + initCount++);
	}
	
	public void destroy() {
		System.out.println("destroy 메소드는 톰캣 종료시 호출됨 : " + destroyCount++);
	}
	
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException{
		System.out.println("doGet 메소드는 요청시마다 호출됨 : " + doGetCount++);
	}
	
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException{
		doGet(request, response);
	}
}



여기서 주목해야 할 점은 Servlet을 수정 즉, java 파일을 수정하면 서버는 껏다 키는걸 권장한다.


두번째는 Servlet api를 사용하는데 오버라이딩 된 init, destroy, doGet 등이 있다.


오버라이드 할 수 있는 함수는 나중에 설명한다.


마지막으로 @WebServlet("/cycle") 부분으로 어노테이션을 통해 Servlet과 HTML 문서 페이지를 연결해주는 키워드이다.


두 가지의 기술을 연결, mapping 시켜주는 키워드이다.


여기서 쓰인 init, destroy, doGet을 설명하면


init은 페이지 호출 시 한번만 실행될 함수


destroy는 톰캣 종료시 실행될 함수


doGet은 새로고침 될 때 올라가는 카운트, 호출 시 계속 실행될 함수이다.




저번에 사용하였던 Statement 구문은 보안에 취약한 방법이다.


SQL Injection이라는 취약점을 가지고 있어 사용하길 권장하지 않는다.


따라서 이 대안으로 PreparedStatement을 사용하면 된다.


PreparedStatement pstmt = null 과 같이 선언하여 사용하고


기존과 같이 선언한 conn을


pstmt = conn.preparedStatement(query문); 과 같이 대입하여 사용한다.


쿼리문을 바로 넣으며


쿼리문은 ? 키워드를 사용하게 된다.


예를들어 SELECT * FROM student WHERE mun = ? AND num = ? 라고 하고 pstmt에 집어넣고


pstmt.set[자료형](?표 순서, 들어갈 값으로 앞의 자료형과 같아야 함);


위와 같은 형식으로 입력한다고 칠 때


pstmt.setString(1, "ABC");

pstmt.setInt(2, 3);


이라고 입력하면 1번 ?에 ABC가 들어가고 2번 ?에 3이라는 값이 들어가


SELECT * FROM student WHERE mun = 'ABC' AND num = 3 이라는 쿼리문이 완성된다.


setString의 경우는 작은 따옴표 '' 키워드는 자동으로 입력된다.





예제를 확인해보자



Employee.java

package model.vo;

import java.sql.Date;

public class Employee implements java.io.Serializable{
	private int empId;
	private String empName;
	private String empNo;
	private String email;
	private String phone;
	private Date hireDate;
	private String jobId;
	private int salary;
	private double bonus;
	private String marriage;
	private int mgrId;
	private String deptId;
	
	public Employee() {}
	
	public Employee(int empId, String empName, String empNo, String email, String phone, Date hireDate, String jobId,
			int salary, double bonus, String marriage, int mgrId, String deptId) {
		super();
		this.empId = empId;
		this.empName = empName;
		this.empNo = empNo;
		this.email = email;
		this.phone = phone;
		this.hireDate = hireDate;
		this.jobId = jobId;
		this.salary = salary;
		this.bonus = bonus;
		this.marriage = marriage;
		this.mgrId = mgrId;
		this.deptId = deptId;
	}

	public Employee(int empId, String empName, String empNo, String email, String phone, String jobId, int salary,
			double bonus, String marriage, int mgrId, String deptId) {
		super();
		this.empId = empId;
		this.empName = empName;
		this.empNo = empNo;
		this.email = email;
		this.phone = phone;
		this.jobId = jobId;
		this.salary = salary;
		this.bonus = bonus;
		this.marriage = marriage;
		this.mgrId = mgrId;
		this.deptId = deptId;
	}

	public Employee(int empId, String jobId, int salary, double bonus, String deptId) {
		super();
		this.empId = empId;
		this.jobId = jobId;
		this.salary = salary;
		this.bonus = bonus;
		this.deptId = deptId;
	}

	public int getEmpId() {
		return empId;
	}

	public void setEmpId(int empId) {
		this.empId = empId;
	}

	public String getEmpName() {
		return empName;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}

	public String getEmpNo() {
		return empNo;
	}

	public void setEmpNo(String empNo) {
		this.empNo = empNo;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public Date getHireDate() {
		return hireDate;
	}

	public void setHireDate(Date hireDate) {
		this.hireDate = hireDate;
	}

	public String getJobId() {
		return jobId;
	}

	public void setJobId(String jobId) {
		this.jobId = jobId;
	}

	public int getSalary() {
		return salary;
	}

	public void setSalary(int salary) {
		this.salary = salary;
	}

	public double getBonus() {
		return bonus;
	}

	public void setBonus(double bonus) {
		this.bonus = bonus;
	}

	public String getMarriage() {
		return marriage;
	}

	public void setMarriage(String marriage) {
		this.marriage = marriage;
	}

	public int getMgrId() {
		return mgrId;
	}

	public void setMgrId(int mgrId) {
		this.mgrId = mgrId;
	}

	public String getDeptId() {
		return deptId;
	}

	public void setDeptId(String deptId) {
		this.deptId = deptId;
	}
	
	
}



TestMain.java

package controller;

import java.util.Scanner;

import model.dao.EmployeeModel;
import model.vo.Employee;

public class TestJDBC {

	public static void main(String[] args) {
		EmployeeModel model = new EmployeeModel();
		Scanner sc = new Scanner(System.in);
		
		// 모든 직원 조회
		// model.selectAll();
		
		
		
		
		
		
		// 키보드로 사번을 입력받아 사원 조회
		// System.out.print("사번을 입력하세요 : ");
		// model.selectOne(sc.nextInt());
		
		
		
		
		
		/*
		// 새 직원 정보를 키보드로 입력 받아 실행
		// 데이터 입력 시 제약조건 확인해서 잘 넣어야 함
		
		// 키보드 입력하여 변수에 저장
		
		Employee emp = new Employee();
		
		System.out.print("사번을 입력하세요 : ");
		emp.setEmpId(sc.nextInt());
		sc.nextLine();
		System.out.print("이름을 입력하세요 : ");
		emp.setEmpName(sc.nextLine());
		System.out.print("주민번호를 입력하세요 : ");
		emp.setEmpNo(sc.nextLine());
		System.out.print("이메일을 입력하세요 : ");
		emp.setEmail(sc.nextLine());
		System.out.print("전화번호를 입력하세요 : ");
		emp.setPhone(sc.nextLine());
		System.out.print("직급을 입력하세요 : ");
		emp.setJobId(sc.nextLine());
		System.out.print("봉급을 입력하세요 : ");
		emp.setSalary(sc.nextInt());
		sc.nextLine();
		System.out.print("보너스를 입력하세요 : ");
		emp.setBonus(sc.nextDouble());
		sc.nextLine();
		System.out.print("결혼 여부를 입력하세요 : ");
		emp.setMarriage(sc.nextLine());
		System.out.print("사수의 사번을 입력하세요 : ");
		emp.setMgrId(sc.nextInt());
		sc.nextLine();
		System.out.print("Dept ID를 입력하세요 : ");
		emp.setDeptId(sc.nextLine());
		
		model.insertEmployee(emp);
		
		// 사번으로 조회
		model.selectOne(emp.getEmpId());
		
		*/
		
		
		
		
		/*
		// 수정 할 항목의 값을 키보드로 입력 받아 실행
		Employee em = new Employee();
		
		System.out.print("사번을 입력하세요 : ");
		em.setEmpId(sc.nextInt());
		sc.nextLine();
		System.out.print("직급을 입력하세요 : ");
		em.setJobId(sc.nextLine());
		System.out.print("봉급을 입력하세요 : ");
		em.setSalary(sc.nextInt());
		sc.nextLine();
		System.out.print("보너스를 입력하세요 : ");
		em.setBonus(sc.nextDouble());
		sc.nextLine();
		System.out.print("Dept ID를 입력하세요 : ");
		em.setDeptId(sc.nextLine());
		
		// update
		model.updateEmployee(em);
		
		// 사번 입력받아 조회
		model.selectOne(em.getEmpId());
		*/
		
		
		
		
		
		// 키보드로 사번을 입력받아 삭제
		System.out.print("사번을 입력하세요 : ");
		int tempNum = sc.nextInt();
		model.deleteEmployee(tempNum);
		
		// 사번 입력받아 조회
		model.selectOne(tempNum);
		
	}

}



JDBCModel.java

package model.dao;

import java.sql.*;
/*import java.sql.Connection;
import java.sql.ResultSet;*/

import model.vo.Employee;

public class EmployeeModel {
	Connection conn = null;
	Statement stmt = null;
	ResultSet rset = null;
	PreparedStatement pstmt = null;
	String query = "";
	int result = 0;
	
	// 모든 직원 정보 조회용 메소드
	public void selectAll() {
		
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "student", "student");
			
			query = "SELECT * FROM EMPLOYEE";
			
			stmt = conn.createStatement();
			
			rset = stmt.executeQuery(query);
			
			while(rset.next()) {
				System.out.println(rset.getInt("EMP_ID") + ", "
						        + rset.getString("EMP_NAME") + ", "
						        + rset.getString("EMP_NO") + ", "
						        + rset.getString("EMAIL") + ", "
						        + rset.getString("PHONE") + ", "
						        + rset.getDate("HIRE_DATE") + ", "
						        + rset.getString("JOB_ID") + ", "
						        + rset.getInt("SALARY") + ", "
						        + rset.getDouble("BONUS_PCT") + ", "
						        + rset.getString("MARRIAGE") + ", "
						        + rset.getInt("MGR_ID") + ", "
						        + rset.getString("DEPT_ID"));
			}
			
			
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			try {
				rset.close();
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		
	}
	
	// 사번을 이용해서 직원 한 명의 정보 조회
	public void selectOne(int empId) {

		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "student", "student");
			
			// Statement 사용시
			
			/*String query = "SELECT * FROM EMPLOYEE WHERE EMP_ID = " + empId;
			// Statement는 query만 조작하면 바로 db 공격이 가능하여 보안에 취약
			stmt = conn.createStatement();
			
			rset = stmt.executeQuery(query);*/
			
			// PreparedStatement 사용시
			// PreParedStatement는 위의 보안 이슈를 해결하여 만들어짐
			query = "SELECT * FROM EMPLOYEE WHERE EMP_ID = ?";
			
			pstmt = conn.prepareStatement(query);
			
			pstmt.setInt(1, empId);
			
			rset = pstmt.executeQuery();
			
			if(rset.next()) {
				System.out.println(rset.getInt("EMP_ID") + ", "
				        + rset.getString("EMP_NAME") + ", "
				        + rset.getString("EMP_NO") + ", "
				        + rset.getString("EMAIL") + ", "
				        + rset.getString("PHONE") + ", "
				        + rset.getDate("HIRE_DATE") + ", "
				        + rset.getString("JOB_ID") + ", "
				        + rset.getInt("SALARY") + ", "
				        + rset.getDouble("BONUS_PCT") + ", "
				        + rset.getString("MARRIAGE") + ", "
				        + rset.getInt("MGR_ID") + ", "
				        + rset.getString("DEPT_ID"));
			}
		
		
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			try {
				rset.close();
				pstmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		
		
	}

	public void insertEmployee(Employee emp) {
		try {
			
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "student", "student");
			
			/*
			query = "INSERT INTO employee(emp_Id, emp_Name, emp_No, email, phone, job_Id, salary, bonus_pct, marriage, mgr_Id, dept_Id) " + 
					"VALUES(" + 
					emp.getEmpId() + ", '" +
					emp.getEmpName() + "', '" +
					emp.getEmpNo() + "', '" +
					emp.getEmail() + "', '" +
					emp.getPhone() + "', '" +
					emp.getJobId() + "', " +
					emp.getSalary() + ", " +
					emp.getBonus() + ", '" +
					emp.getMarriage() + "', " +
					emp.getMgrId() + ", " +
					emp.getDeptId() + ")";
			
			stmt = conn.createStatement();
			
			result = stmt.executeUpdate(query);
			*/
			
			query = "INSERT INTO employee(emp_Id, emp_Name, emp_No, email, phone, job_Id, salary, bonus_pct, marriage, mgr_Id, dept_Id) " + 
					"VALUES(" + 
					"?" + ", " +
					"?" + ", " +
					"?" + ", " +
					"?" + ", " +
					"?" + ", " +
					"?" + ", " +
					"?" + ", " +
					"?" + ", " +
					"?" + ", " +
					"?" + ", " +
					"?" + ")";
			
			pstmt = conn.prepareStatement(query);
		
			pstmt.setInt(1, emp.getEmpId());
			pstmt.setString(2, emp.getEmpName());
			pstmt.setString(3, emp.getEmpNo());
			pstmt.setString(4, emp.getEmail());
			pstmt.setString(5, emp.getPhone());
			pstmt.setString(6, emp.getJobId());
			pstmt.setInt(7, emp.getSalary());
			pstmt.setDouble(8, emp.getBonus());
			pstmt.setString(9, emp.getMarriage());
			pstmt.setInt(10, emp.getMgrId());
			pstmt.setString(11, emp.getDeptId());
			
			result = pstmt.executeUpdate();
		
			if(result > 0) {
				System.out.println(result + "개의 행이 추가되었습니다.");
				conn.commit();
			}else {
				System.out.println("실패");
				conn.rollback();
			}
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				conn.close();
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
	}

	public void updateEmployee(Employee em) {
try {
			
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "student", "student");
			
			
			/*
			stmt = conn.createStatement();		
			
			query = "UPDATE employee SET job_id = '" + em.getJobId() +
					"' WHERE emp_id = " + em.getEmpId();
			System.out.println(query);
			
			
			result = stmt.executeUpdate(query);
			System.out.println(result + "행이 수정되었습니다.");
			
			
			
			query = "UPDATE employee SET salary = " + em.getSalary() +
					" WHERE emp_id = " + em.getEmpId();
			System.out.println(query);
			
			result = stmt.executeUpdate(query);
			System.out.println(result + "행이 수정되었습니다.");
			
			
			
			query = "UPDATE employee SET bonus_pct = " + em.getBonus() +
					" WHERE emp_id = " + em.getEmpId();
			System.out.println(query);
			
			result = stmt.executeUpdate(query);
			System.out.println(result + "행이 수정되었습니다.");
			
			
			
			query = "UPDATE employee SET dept_id = '" + em.getDeptId() +
					"' WHERE emp_id = " + em.getEmpId();
			System.out.println(query);
			
			result = stmt.executeUpdate(query);
			System.out.println(result + "행이 수정되었습니다.");
			*/
			
			
			query = "UPDATE employee SET job_id = ?" +
					"WHERE emp_id = ?";
			System.out.println(query);
			
			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, em.getJobId());
			pstmt.setInt(2, em.getEmpId());
			result = pstmt.executeUpdate();
			System.out.println(result + "행이 수정되었습니다.");
			
			
			
			query = "UPDATE employee SET salary = ?" +
					" WHERE emp_id = ?";
			System.out.println(query);

			pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, em.getSalary());
			pstmt.setInt(2, em.getEmpId());
			result = pstmt.executeUpdate();
			System.out.println(result + "행이 수정되었습니다.");
			
			
			
			query = "UPDATE employee SET bonus_pct = ?" +
					" WHERE emp_id = ?";
			System.out.println(query);

			pstmt = conn.prepareStatement(query);
			pstmt.setDouble(1, em.getBonus());
			pstmt.setInt(2, em.getEmpId());
			result = pstmt.executeUpdate();
			System.out.println(result + "행이 수정되었습니다.");
			
			
			
			query = "UPDATE employee SET dept_id = ?" +
					" WHERE emp_id = ?";
			System.out.println(query);

			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, em.getDeptId());
			pstmt.setInt(2, em.getEmpId());
			result = pstmt.executeUpdate();
			System.out.println(result + "행이 수정되었습니다.");
			
			
			
			conn.commit();
			
			
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				conn.close();
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public void deleteEmployee(int empNo) {
		try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
             
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "student", "student");
             
            
            /*
            stmt = conn.createStatement();
             
            query = "DELETE FROM employee WHERE emp_id = " + empNo;
            System.out.println(query);
             
            result = stmt.executeUpdate(query);
             */
            
            query = "DELETE FROM employee WHERE emp_id = ?";
            pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, empNo);
			result = pstmt.executeUpdate();
            
            if (result > 0) {
                System.out.println(result + "개의 행이 수정되었습니다.");
                conn.commit();
            }else {
                System.out.println("실패했습니다.");
                conn.rollback();
            }
             
            
             
        } catch (ClassNotFoundException e1) {
            e1.printStackTrace();
        } catch (SQLException e1) {
            e1.printStackTrace();
        } finally {
            try {
                pstmt.close();
                conn.close();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }
	}

}








+ Recent posts