클라우드 융합 Full-stack 웹 개발자 양성과정/Servlet, JSP

Servlet/JSP - apache tomcat설치, 1_Servlet

thesunset 2022. 11. 4. 09:09

0. apache tomcat설치 & 사전작업


 

1) 구글에 apache tomcat 검색 

2) 다운로드 탭 > tomcat 8 > 8.5.83 > Core > zip 다운로드 

3) dev폴더에 옮긴 뒤 압축풀기 

--------------------------------------------------------------------------------------------------------------------------------

1) 새로 워크스페이스를 만들어서 이클립스로 열기 -  C:드라이브에 web-workspace 폴더 생성

2) 워크스페이스 설정 (워크스페이스 : 작업환경)
2_1) 웹 애플리케이션 작업을 하기 위해 Java EE환경으로 설정

2_2) 보여질 UI탭들 셋팅 [Window]-[Show View]
(Navigator, Console, Problems, Servers)

좌 - 쇼뷰에 없는 것은 other에 들어가면 있음

2_3) 인코딩 설정 및 서버 Runtime Environments [Window]-[Preference]
    2_3_1) 인코딩 설정 : 영어, 숫자, 한글 등 모든 문자셋을 사용할 수 있도록 UTF-8로 설정
            (General - Workspace)
            (General - Editors - Text Editors - Spelling)
            (Web - CSS Files, HTML Files, JSP Files)
            (XML - XML Files)
            (JSON - JSON Files)

   2_3_2) 서버 RunTime 잡기 : 이클립스에서 서버를 실행할 수 있도록 연동하는 과정 
(Server - Runtime Environments)
- Add 클릭 : 설치한 아파치톰캣과 동일한 버전 선택 - Next
- Name 수정가능(안하면 기본값) Browser클릭 - 설치한 아파치 톰캣 폴더 선택 - Finish

3) 서버 생성하기 
3_1) [New] - [Server]

3_2) 창에 기본적으로 2_3_2번 과정에서 세팅해놓은 Runtime이 잡혀있을 것
(Server Name 변경 가능)

3_3) Finish

좌 - 만들기 전 / 우 - 만든 후 

 

3_4) 생성된 서버 수정하기 (만들어진 서버 더블클릭)
3_4_1) 포트번호 재설정(기본값으로 잡힌 8080포트와 오라클 리스너 포트가 동일하므로 충돌발생)
8080 -> 8888
3_4_2) 왼쪽 하단 Server Option에 Server modules without publishing 체크
=> 다음 단계에서 지정할 output folder / file upload/download 경로 지정이 안될 때가 있음 마치고 나면 반드시 저장

* 서버번호도 고려해서 써야 함 

: 체크박스 체크하기 

==> 반드시 저장 ****

4) Dynamic web Project 만들기 (동적인 웹 어플리케이션) 
4_1) 프로젝트명 신중하게 작성할 것 - Next

 

여기에 컴파일된 class파일이 들어감

* next를 누르면, 

webcontent폴더가 배포됨

4_2) default output folder 경로 재설정 : WebContent/WEB-INF/classes-Next
=> outputfolder로 지정된 classes폴더에는 컴파일된 .class파일들이 들어가는 폴더이다.
실제로 프로젝트 배포 시 WebContent폴더가 배포된다.(즉, 이 안에 .class파일들이 존재해야 함)
기본경로(build/classes)로 지정해놓으면 이 폴더가 WebContent안에 만들어지지 않는다. 주의***

4_3) Context root : 이 어플리케이션의 고유한 이름으로 지어줄 것 (기본값으로는 프로젝트 명/보통은 재정의해서 씀)
=> 하나의 서버로 여러개의 어플리케이션을 구동할 수 있음.
고유한 이름을 통해 해당 어플리케이션에 접근하는 경로로 사용 가능하고 각 어플리케이션을 구분할 수 있음

Content directory : 실제로 배포되는 폴더 (즉, 서버에 올라가는 폴더)의 최상위 폴더명을 지정하는 것
=> 변경 시 default output folder로 돌아가서 그 쪽도 변경해 줄 것

Generate web.xml deployment descriptor : 무조건 체크할 것(기본적으로 체크 X)
=> web.xml 문서에 기본적인 어플리케이션에 대한 전체 정보가 들어 있음(서버실행과 동시에 메인페이지를 지정해줌)
굳이 파일을 수정할 일이 없다면 안 만들어도 무방하나 (내부적으로 server가 가지고 있는 web.xml파일이 있음)
그래도 혹시나 수정을 한다거나 작업할 일이 있을 경우를 대비해서 무조건 생성하자 

 

4_4) Finish

 

5) 새로 만들어진 Project확인해보기 
5_1) [Project] - [WebContent] - [WEB-INF] - classes 폴더가 잘 만들어졌는지 확인하기
5_2) [Project] - [WebContent] - [WEB-INF] - web.xml 문서 잘 만들어졌는지 확인하기
5_3) index.html(welcome-file)파일 만들기

 

 

welcome-file생성

New other > html file > 이름 변경 > 경고창OK

서버 키기

6) 생성해놓은 서버에 애플리케이션 올리기
=> Server 우클릭 : Add and Remove - 올리고자 하는 어플리케이션을 선택 후 오른쪽으로 옮기고 Finish

재요청 시 , 

서버 우클릭 후 Add해주기

재요청 시, 작성한 welcome-file이 나타남

7) 서버 start후 URL요청을 통해 index파일이 잘 응답해주는 지 확인해보기

 

 

get방식테스트 

폴더생성
설정변경
HTML파일 생성

 

 

http://localhost:8888/1_Servlet/view/requestTest_Get.html => web content폴더

 

* 404오류의 경우 경로에 오타, 파일명에 오타 중 하나 

 

 

 

GET방식의 쿼리스트링

서블릿 만들기

1_Servlet


< WebContent / WEB-INF - index.html > 

서블릿이란? 


: 웹 서비스를 위한 "자바클래스"를 말하며 
자바를 이용해서 웹을 만들기 위해 필요한 기술이다. 

- 사용자의 요청을 받아서 처리하고 그에 해당하는 응답페이지를 만들어 
    다시 사용자에게 전송해주는 역할을 하는 자바 클래스(controller의 역할) 
- 즉, 웹에서 동적인 페이지를 JAVA로 구현할 수 있게 해주는 서버측 프로그램(WAS에서 구동됨)

=> JAVA클래스에서 웹페이지 구현을 위해서 HTML이 들어갈 수 있음

<h3><a href="view/requestTest_Get.html">GET 방식 테스트</a></h3>
<h3><a href="view/requestTest_Post.html">POST 방식 테스트</a></h3>

1) GET방식으로 요청 후 응답페이지 받아보기

< view/requestTest_Get.html >

   특징1. GET방식으로 요청하는 건 URL의 Header영역에 데이터들을 포함시켜서 요청함
   => 사용자가 입력한 값(데이터)들이 URL에 노출됨 
   => 보안에 취약함 <br>
   => 즉, 로그인이나 회원가입같은 경우 GET방식이 부적합하다. 
  
   특징2. Header영역은 전송하는 데이터의 길이에 제한이 있음
   => 방대한 데이터를 담았을 경우 초과된 데이터는 절단돼서 넘어감 
   => 즉, 게시글 작성 같은 경우 GET방식이 부적합하다. 
  
   특징3. 장점이라고 한다면 URL에 데이터가 노출 
   - ex) 즐겨찾기-url주소 저장
   즐겨찾기(북마크)가능 (즐겨찾기에 등록해놨다가 해당 URL을 재요청 가능) 
   => 검색 기능 같은  경우 GET방식이 가장 적합

 

(예제) 개인정보 입력 - GET

개인정보를 입력해주세요. 입력 확인 후 버튼을 눌러주세요.

<form action="/1_Servlet/test2.do" method="get">
    <ul>
        <li>
            이름 : <input type="text" name="name">
        </li>
        <li>
            성별 : 
            남자 <input type="radio" name="gender" value="M">
            여자 <input type="radio" name="gender" value="F">
        </li>
        <li>
            나이 : <input type="number" name="age">
        </li>
        <li>
            사는 도시 : 
            <select name="city">
                <option>서울시</option>
                <option>경기도</option>
                <option>강원도</option>
                <option>충청도</option>
                <option>전라도</option>
                <option>경상도</option>
                <option>제주도</option>
            </select>
        </li>
        <li>
            키 : <input type="range" min="140" max="200" name="height">
        </li>
        <li>
            좋아하는 음식(모두 고르시오):
            한식 <input type="checkbox" value="한식" name="food">
            중식 <input type="checkbox" value="중식" name="food">
            일식 <input type="checkbox" value="일식" name="food">
            양식 <input type="checkbox" value="양식" name="food">
            간식 <input type="checkbox" value="간식" name="food">
            후식 <input type="checkbox" value="후식" name="food">
            분식 <input type="checkbox" value="분식" name="food">
            야식 <input type="checkbox" value="야식" name="food">
        </li>
        <li>
            <input type="submit">
            <input type="reset">
        </li>
    </ul>	
</form>

form태그 내에 제출버튼(submit) 클릭 시 
form태그 속성 중 action에 작성된 url로 요청됨(제출)
즉, controller(Servlet를 호출한다고 생각하면 됨)

Servlet요청의 경우 반드시 그 요청값이 현재 웹 어플리케이션의 context path == /context Root/ 경로 
형식으로 지정해줘야 함

=> http://localhost:8888/1_Servlet/test1.do(서블릿 매핑값)

 

controller의 역할을 하는 Servlet만들기 

 Get방식으로 요청하면 doGet메소드가 호출됨

=> doGet메소드를 수정해 사용할 예정 
 
  첫 번째 매개변수인 HttpServletRequest request에는 요청 시 전달된 내용들이 담김
  => 사용자가 입력한 값, 요청 전송방식, 요청한 사용자의 ip주소 등..
   
  두 번째 매개변수인 HttpServerResponse response에는 요청 처리 후 응답할 때 사용하는 객체

request의 parameter영역으로부터 전달된 데이터를 뽑는 메소드

 - request.getParameter('키값') : String(그에 해당하는 value값)
 => 무조건 문자열형태로 반환되기 때문에 
  * 다른 자료형으로 변경하려면 파싱해야 함

- request.getParameterValues('키값') : String[] (그에 해당하는 value값)
=> 하나의 key값으로 여러 개의 value들을 받는 경우 (checkbox)
  String 배열형으로 반환가능


 요청 처리 STEP   

<src/com/kh/controller/RequestGetServlet>

 1. 우선, 요청을 처리하기 위해 요청 시 전달된 값(사용자가 입력한 값)들을 뽑는다. get
 => request의 parameter라는 영역에 값이 존재 
 => key-value세트로 담겨있음 (name속성값=value속성값)

//1단계
String name = request.getParameter("name");
//"홍길동" / ""(텍스트 상자가 빈 경우 빈 문자열이 넘어온다)

String gender = request.getParameter("gender");
//"M" / "F" / null (라디오 버튼의 경우 체크된 것이 없을 경우 null이 넘어온다. 

int age = Integer.parseInt(request.getParameter("age")); //String
//"15"/ ""
//"15" -> 15
//Wrapper클래스로 파싱
//"": NumberFormatException 발생


String city = request.getParameter("city");
//"서울시" 기본적으로 선택되어있기 때문에 빈 문자열이 들어올 수 X

double height = Double.parseDouble(request.getParameter("height"));  //170.0
// max와 min의 중간값이 기본 => 빈문자열이 들어올 수 X

String[] foods = request.getParameterValues("food");
//["한식", "일식"] / null(체크박스의 경우 체크된 것이 하나도 없으면 null이 넘어옴)

* 이 때 값이 경우의 수를 알아두기!

* String으로 넘어오기때문에 파싱해주기!


2. 뽑아낸 값들을 가지고 요청처리해줌(Service -> DAO -> DB)

보통의 흐름 : Controller단에서 Service단의 메소드를 호출값을 전달 - DAO호출 - DB SQL문 실행 - 결과 반환 
(아직 배우지 않아서 생략)


 3. 처리 결과에 따른 성공/실패 페이지 응답(자바를 통한 방법)

 장점 : Java코드 내에서 작성하기 때문에 반복문이나 조건문, 유용한 메소드들을 활용 가능
 단점 : 복잡, 혹시라도 나중에 HTML을 수정하고자 할 때 JAVA코드 내에서 수정이 이뤄지기 때문에 
         다시 수정한 내용을 반영시키려면 서버를 restart해야 함

 

* response객체를 통해 사용자에게 html(응답화면) 전달

1단계) 이제부터 내가 출력할 내용은 문서형태의 html이고 문자셋은 utf-8을 사용

response.setContentType("text/html; charset=UTF-8");

2단계) 응답하고자하는 사용자와의 스트림을 연결 (클라이언트와의 통로를 생성)

PrintWriter out = response.getWriter();

3단계) 생성된 스트림을 통해서 응답 HTML구문을 한 줄씩 출력

out.println("<html>");
out.println("<head>");
out.println("<style>");
out.println("h1{color : orangered}");
out.println("#name{color : skyblue}");
out.println("#age{color : blue}");
out.println("#city{color : navy}");
out.println("#height{color : purple}");
out.println("#gender{color : pink}");
out.println("li{color : tomato}");
out.println("</style>");
out.println("</head>");

out.println("<body>");

out.println("<h1>개인정보 응답화면</h1>");
        out.printf("<span id='name'>%s</span>님은 <br>", name);
out.printf("<span id='age'>%s</span>살이며 <br>", age);
out.printf("<span id='city'>%s</span>에 삽니다. <br>", city);
out.printf("키는<span id='height'>%.1f</span>cm이고 <br>", height);
out.print("성별은");

if(gender == null) {
    out.println("선택을 안했습니다.");
} else {
    if(gender.equals("M")) {
        out.println("<span id='gender'>남자</span>입니다. <br>");
    } else {
        out.println("<span id='gender'>여자</span>입니다. <br>");
    }
}

out.print("좋아하는 음식은");
if(foods==null) {
    out.println("없습니다.");
} else {
    out.println("<ul>");
    for(int i = 0; i<foods.length; i++) {
        out.printf("<li>%s</li>", foods[i]);
    }
    out.println("</ul>");
}


out.println("</body>");
out.println("</html>");
  < 참고 : 자주보는 오류 >
 404 : 파일이나 요청을 받아주는 서블릿을 못 찾았을 때 발생 => 경로가 잘못되었거나 파일명에 오타났을 때 
 500 : 자바 소스코드 상의 오류 (예외발생)

2) POST방식으로 요청 후 응답페이지 받아보기

특징1. POST방식으로 요청하면 URL에 BODY영역에 데이터를 포함시켜서 요청 
=> 사용자가 입력한 값(데이터)들이 URL에 노출되지 않음
=> 보안유지가 가능함
=> 즉, 로그인이나 회원가입 같은 경우 POST방식이 적합함

특징2. BODY영역은 전송하는 길이에 제약이 없음
=> 즉, 게시판 작성 같은 경우 POST방식이 적합함 

특징3. 즐겨찾기는 가능하다. 전달되는 데이터가 URL에 노출되지 않음
(기존에 봤던 응답화면을 볼 수는 없음)

특징4. 최대 요청 받는 시간(Time out)이 존재함

 

서블릿매핑값 : localhost:8888/1_Servlet/test2.do

 

method 속성값을 post로 설정

<form action="/1_Servlet/test2.do" method="post">

 

* POST방식 호출 시 doPost메소드가 먼저 호출되지만, 매개변수로 받은 인자값을 그대로 doGet메소드를 호출해 인자값으로  넘겨줌

=> 따라서 doGet메소드에 내가 실행할 것을 작성하면 됨

 

0단계) 인코딩 설정 
POST방식의 기본 인코딩 설정은 ISO-8859-1로 설정되어있음
POST방식의 경우 값을 뽑기 전에 미리 UTF-8방식으로 인코딩 설정을 해야한다. ***

request.setCharacterEncoding("UTF-8");

1단계) request.getParameter 또는 request.getParameterValues로 값 뽑아내기

String name = request.getParameter("name"); //: String
String gender = request.getParameter("gender");
int age = Integer.parseInt(request.getParameter("age"));
String city = request.getParameter("city");
Double height = Double.parseDouble(request.getParameter("height"));

String[] foods = request.getParameterValues("food");

2단계 ) 처리 -> Service -> DAO -> DB : 아직 안 배워서 생략

 

3단계) 응답페이지

3_1) JSP이용해서 응답페이지 만들기

- JSP(Java Server Page) : HTML내에서 JAVA코드를 넣는다. 

- 응답화면(jsp)에서 필요로 하는 데이터들을 request객체에 담아서 보내줘야 함

- request에 attribute영역이 있음 => key-value 세트로 묶어서 담을 수 있음

- request.setAttribute(key, value);

request.setAttribute("name", name);
request.setAttribute("gender", gender);
request.setAttribute("age", age);
request.setAttribute("city", city);
request.setAttribute("height", height);
request.setAttribute("foods", foods);	

request.setAttribute("msg", "조회를 성공하셨습니다.");

=> Object로 담겨서 무슨 자료형이든 다 담을 수 있음(다형성적용)

 

3_2) 응답페이지를 JSP에서 위임(떠넘기기)

현재 작업중인 doGet()에서 응답페이지를 만드는 과정을 위임해야한다. 

* 위임 시 필요한 객체 : RequestDispatcher

① 응답하고자 하는 뷰(jsp)를 선택하면서 객체를 생성 request.getRequestDispatcher(jsp경로)

RequestDispatcher view = request.getRequestDispatcher("view/responsePage.jsp");

② forwarding : forward()

view.forward(request,response);

* reponsePage.jsp 파일 생성

< view/response.jsp >

<%이 구문을 스클립틀릿(scriptlet)이라고 해서 HTML내에 자바코드를 쓸 수 있는 영역 %>

- 현재 이 jsp파일에서 필요한 데이터들 = request객체의 attribute영역에 담겨있음

- 값 추출 방법 : request.getAttribute("키값") : Object

String name = (String)request.getAttribute("name");
String gender = (String)request.getAttribute("gender");
int age = (int)request.getAttribute("age");
String city = (String)request.getAttribute("city");
double height = (double)request.getAttribute("height");
String[] foods = (String[])request.getAttribute("foods");

String msg = (String)request.getAttribute("msg");
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>개인정보 응답화면</title>
</head>
<body>
	<div>요청결과 : <%=msg %></div>
	
	<span><%=name %></span>님은
	<span><%=age %></span>살이며, 
	<span><%=city %></span>에 삽니다.
	
	키는 <span><%=height %></span> cm이고 <br>
	
	성별은 
	<%
	if(gender==null){%>
	 <!-- 자바 사용 가능 -->
	
	<!-- 성별을 선택 안 했을 경우 -->
	<span>선택을 안했습니다.</span> <br>
	<% } else{%> 
	<% if(gender.equals("M")){ %>
	<!-- 남자선택 -->
	<span>남자입니다.</span> <br>
	<%} else{ %>
	<!-- 여자선택 -->
	<span>여자입니다.</span> <br>
	<% } %>
	<%} %>
	
	좋아하는 음식은
	<%if(foods == null) { %>
	<!-- 체크를 안했을 경우 -->
		없습니다.
	<% } else { %>	
	<!-- 체크를 했을 경우 -->
		<ul>
			<%for(int i=0; i<foods.length; i++) { %>
				<li><%= foods[i] %></li>
			<%} %>
		</ul>
	<% } %>
	
	
</body>
</html>