WAS/WAS수업

#47. Servlet (Get방식)

열하나요 2023. 9. 6. 12:49

web.xml

 

 

welcome-file-list에서 쓸 주소만 빼고 지워줌

 

<!-- 
1) 새로운 워크스페이스를 만들어서 이클립스로 열기 (보통 C드라이브에 web-workspace로 생성)

2) 워크스페이스 설정(작업환경)
2_1) 웹개발 작업을 하기 위해서 Java EE환경으로 설정

2_2) 보여질 UI탭을 세팅[Window] - [Show View]
(navigator, Console, Problems, Servers)

2_3) 인코딩 설정 및 서버 Runtime Environments [Window] - [Preferences]
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 수정 가능(안하면 기본값) : Browse 클릭 -> 설치한 톰캣폴더 선택
   -> Finish
   
3) 서버 생성하기
3_1) [Server] - [New] - [Server] 

3_2) 창에 기본적으로 2_3_2과정에서 세팅해 놓은 Runtime이 잡혀있을 것(ServerName바꿀 수 있음)

3_3) Finish

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

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

4_2) default output folder 경로 재성정 : WebContent/WEB-INF/classes - Next
=> output folder로 지정된 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) web.xml에 지정해둔 welcome-file만들기!(index.html 만들었음)

6) 생성해 놓은 서버에 어플리케이션 올리기

=> [Server] - Server에 오른쪽 클릭 : Add and Remove - 가용하고 싶은 어플리케이션 선택 후
오른쪽으로 옮기고 - Finish
(이거는 서버 꺼져있는 상태에서 하세요~)

7) 서버 Start 후 브라으저를 실행해서 URL요청을 통해 index파일이 잘 응답하는지 확인해보기!
 -->

 

 

 

 

 

Dynamic project(program)생성

1. index.html

>> get방식

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>어떡하지??????????????????</title>
</head>
<body>

	<!-- <h1>뭐야 ~ 이게 이게 인덱스야 ~ ? 니들이 인덱스를 알아 ~ ?</h1> -->
	
	<h1>Web을 배워봅시다~</h1>
	
	<h2>* Servlet</h2>
	
	<p>
		서블릿이란? <br>
		자바를 이용해서 웹을 만들기 위해 필요한 하나의 기술이다. <br>
		웹 서비스를 위한 "자바 클래스" <br>
		
		- 사용자의 요청을 받아서 처리하고 그에 해당하는 응답페이지를 만들어서 
		 다시 사용자에게 전송해주는 역할을 할 수 있는 자바 클래스(컨트롤러) <br>
		- 웹에서 동적인 페이지를 JAVA로 구현할 수 있게 해주는 서버측 프로그램
		
		=> JAVA클래스에서 웹페이지 구현을 위해 HTML을 작성해볼것 !!
		
	</p>
	<!--  
		// ip주소로 서로간의 장치(컴퓨터)까지 찾아갈 수 있음 
		// -> port번호로 웹 서버를 가서!! 
		// -> 톰캣같은 프로그램으로 http://을 이용하여 HTML로 접근할 수 있음(먼저 홈페이지:웰컴페이지) 
		// -> Servlet을 이용해 동적인 정보를 보여주기 위해 JAVA에 갔다옴(마이페이지 등으로 이동)
	 -->
	
	<h3><a href="view/requestTest_Get.html">GET방식 테스트</a></h3>
	
	

</body>
</html>

 

2. 1_Servlet > WEB-INF폴더 > web.xml

생성할 때 Generate 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">

<!-- 
	* web.xml 파일
	
	- 배포 서술자(DD, Deployment Descriptor)라고 해서
	해당 웹 어플리케이션의 기본적인 설정을 위해 작성하는 파일
	- 해당 웹 어플리케이션을 구동시키는 서버가 Start시 제일 먼저 읽히는 파일
	- 개발자가 web.xml파일을 수정하지 않고도 개발 및 운영이 가능하지만 규모가 커지고,
	다양한 API를 사용하게 되면 직접 수정을 해야하는 경우가 생김
 -->
 
  <display-name>1_Servlet</display-name>
  
  
  <!-- 
	* welcome-file : 처음에 url로 해당 어플리케이션 루트 요청 시 제일 처음 보여지게 되는
	메인페이지를 지정!
	
	http://구동중인서버의ip주소:포트번호/
	=> 각자 본인 컴퓨터에 구축해 놓은 서버의 IP주소를 요청 : 127.0.0.1 == localhost
	=> 서버의 포트번호 : 8888
	=> 서버내의 구동중인 context root 지정 : 1_Servlet
	
	http://localhost:8888/1_Servlet
	
	단, welcome-file-list에 존재하는 파일명은 반드시 WebContent폴더 안에 위치해야 함!!
	
   -->
   
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  
</web-app>

 

3. 1_Servlet > WebContent > view에 html생성

requestTest_Get.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>GET방식 요청 테스트</title>
<style>
	ul{
		list-style:none;
		line-height:200%;
	}
</style>

</head>
<body>

	<h1>GET방식으로 요청 후 응답데이터 받아보기</h1>
	
	<p>
		특징1. GET방식으로 요청하는 건 URL의 Header영역에 데이터들을 포함시켜서 요청함 <br>
		=> 사용자가 입력한 값(데이터)들이 URL에 노출됨 <br>
		=> 보안에 취약함 <br>
		=> 즉, 로그인이나 회원가입 같은 경우 GET방식이 부적합하다.
		
		특징2. Header영역은 전송하는 데이터의 길이에 제한이 있음 <br>
		=> 방대한 데이터를 담았을 경우 초과된 데이터는 절단돼서 넘어감 <br><br>
		=> 즉, 게시글 작성 같은 경우 GET방식이 부적합하다. <br><br>
		
		특징3. 장점이라고 한다면 URL에 데이터가 노출되기 때문에 <br>
		즐겨찾기(북마크) 기능(즐겨찾기에 해당 URL을 등록해놔서 재 요청이 가능) <br>
		=> 검색 기능 같은 경우 GET방식이 가장 적합
		
	</p>
	
	<h2>개인정보입력 - GET</h2>
	<p>개인정보를 입력해 주세요. 입력 확인 후 버튼을 눌러주세요 </p>
	
	<!-- 
		form 태그 안에 있는 제출 버튼(submit) 클릭 시
		form 태그 속성 중에 action에 작성된 url로 요첨됨!!(제출)
		Controller(Servlet)를 호출한다고 생각하면 됨
		
		Servlet요청 같은 경우 반드시 그 요청 값이 현재 웹 어플리케이션의 context Path == /context root/경로
		형식으로 지정해야 함
		
		=> http://localhost:8888/1_Servlet/test1.do(서블릿 매핑값 :일단 아무거나 내가 적고싶은거)
	 -->
	
	<form method="get" action="/1_Servlet/test1.do">
		<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 value="GW">강원도</option>
					<option>충청도</option>
					<option>전라도</option>
					<option>경상도</option>
					<option>제주도</option>
				</select>
			</li>
			<li>
				키 : <input type="range" name="height" min="140" max="200">
			</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">
				갈비탕 <input type="checkbox" value="얼큰갈비탕" name="food">
			</li>
			<li>
				<input type="submit">
				<input type="reset">
			</li>
			
		
		</ul>
	</form>
	

</body>
</html>

 

4. java package com.kh.controller에 Servlet생성

RequestGetServlet.java

하면, WebContent > WEB-INF에 class파일이 자동생성됨

package com.kh.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;

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

/**
 * Servlet implementation class RequestGetServlet
 */
@WebServlet("/test1.do")
public class RequestGetServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public RequestGetServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		// System.out.println("진짜임?? 뻥치는 거 아님?? 말이 됨?????");
		
		/*
		 * Controller <- 얘는 하는 일이...?
		 * 1. 데이터 가공
		 * 2. 응답화면 지정
		 * 
		 * Get방식으로 요청하면 doGet()가 호출됨!
		 * 
		 * 첫 번째 매개변수인 HttpServletRequest request에는 요청 시 전달된 내용들이 담김
		 * => 요청 전송방식, 요청한 사용자의 ip주소, 사용자가 입력한 값 등등...
		 * 
		 * 두 번째 매개변수인 HttpServletResponse response는 요청 처리 후 응답을 할 때 사용하는 객체 
		 * 
		 * 요청 처리 스텝
		 * 
		 * 1. 우선 요청을 처리하기 위해 요청 시 전달된 값(사용자가 입력한 값)들을 뽑는다.
		 * => request에는 parameter라는 영역에 값이 존재
		 * => key-value 세트로 담겨있음!! (name속성값=value속성값)
		 * 
		 * 2. 뽑아낸 값들을 가지고 요청 처리해야 함(Service -> DAO -> DB)
		 * 
		 * 3. 처리결과에 따른 성공 / 실패 페이지 응답
		 */
		
		/*
		 * request의 parameter영역으로부터 전달된 데이터를 뽑는 방법
		 * 
		 * - request.getParameter("키값") : String(그에 해당 value)
		 * => 무조건 문자열 형태로 반환 됨!!! 그렇기 때문에
		 * 	   다른 자료형으로 사용하려면 parsing해야함
		 * 
		 * - request.getParameterValues("키값") : String[] (그에 해당하는 value값)
		 * => 하나의 key값으로 여러 개의 value들을 받는 경우(ex. checkbox)
		 *    String배열로 반환!
		 */
		
		// 1단계
		String name = request.getParameter("name");
		// 사용자가 입력할 값의 경우의 수 : 셀 수 없음 => 양호하네
		// "홍길동" / "" (아무것도 입력하지 않음)
		
		// form태그 안의 요소에 name이 있다면 submit버튼 클릭 시 무조건 넘어가야 함. input요소의 value값은 기본적으로 빈 문자열이 들어있음 value=""
		System.out.println(name);
		
		String gender = request.getParameter("gender");
		// "M" / "F" / null(라디오 버튼의 경우 체크된 것이 없을 경우 null이 넘어옴) ~~~~~~~~~~~~~~~~~~~~~~
		System.out.println(gender);
		
		// String key = request.getParameter("실수");
		// System.out.println(key); // 안되지요~
		
		int age = Integer.parseInt(request.getParameter("age"));
		// "15" / ""
		// "15" -> 15
		// Wrapper 클래스를 이용한 파싱
		// "" : NumberFormatException발생
		
		// 아예 value값을 0으로 해놓을 수도 있고.. 정규표현식처리..  자바단에서.. (예외처리 해줘도 되겠고..)
		
		System.out.println(age);
		
		String city = request.getParameter("city"); // "서울시"
		
		double height = Double.parseDouble(request.getParameter("height")); // 170.0
		
		System.out.println(height);
		
		String[] foods = request.getParameterValues("food");
		// ["빵", "치킨"] / null(체크박스의 경우 하나도 없으면 null이 넘어옴) ~~~~~~~~~~~~~~~~~~~~~~~~
		
		if(foods == null) {
			System.out.println("없음");
		} else {
			System.out.println(Arrays.toString(foods));
		}
		
		// 자주보는 오류
		// 404 : 파일이나 요청을 받아주는 서블릿을 못 찾았을 때 발생
		// => 경로를 잘못 적었거나 파일명에 오타가 났을 때
		// 500 : 자바 소스코드상의 오류(예외 발생)
		
		// 2단계
		// 뽑아낸 값들을 가지고 요청처리!(DB와 상호작용 => JDBC)
		// 보통의 흐름 : Controller단에서 Service단의 메소드를 호출하면서 값을 전달
		// -> DAO호출 - DB SQL문 실행 - 결과반환
		/*
		Person p = new Person(name, gender, age, city, height, foods);
		
		int result = new PersonService().insertPerson(p);
		
		if(result > 0) {
			성공페이지  ~;
		} else {
			실패페이지 ~;
		}
		*/
		
		// 3단계 
		// 자바를 이용해서 응답데이터 넘기기(JAVA코드 안에 HTML코드를 넣을 수 있음)
		
		// * response객체를 통해 사용자에게 HTML(응답화면)전달
		// 장점 : Java코드 내에 작성하기 때문에 조건문, 유용한 메소드(자바꺼)들을 활용 가능
		// 단점 : 복잡, 혹시라도 나중에 HTML수정할 때 JAVA코드 내에서 수정이 이루어지기 떄문에
		// 수정한 내용을 반영하려면 서버를 restart해야 함!
		
		/*
		 * XXX님은
		 * XX살이며
		 * XXX에 삽니다.
		 * 키는 XXXcm이고
		 * 
		 * 성별은 case 1. 선택을 안했습니다.
		 * 		case 2. 남성/여성입니다.
		 * 
		 * 좋아하는 음식은 case 1. 없습니다.
		 * 			  case 2. 뭐시기뭐시기무어시기.
		 */

		// 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 : yellowgreen}");
		out.println("#age{color : greenyellow}");
		out.println("#city{color : forestgreen}");
		out.println("#height{color : skyblue}");
		out.println("gender{color : crimson}");
		out.println("li{color : lightpink}");
		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'>%d</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>");
		
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 

* 자바를 실행할 때는 서버를 다시 시작해줘야 함.