sun cloud

목차



Deployment Descriptor

: 웹어플리케이션의 설정 정보를 기술한 파일입니다.

저희가 사용해온 WEB-INF 경로의 web.xml 파일이 DD(Deployment Descriptor)입니다.

(참고: 서블릿 3.1 이상부터는 어노테이션이 자동 적용됩니다. 저희는 연습을 위해 서블릿 2.5 버전을 사용해서 xml을 직접 적용해보고 나중에 어노테이션을 배우면서 필요에 따라 두 방법 모두 사용할 수 있도록 하겠습니다.)

특징을 간단히 살펴보겠습니다.

  • Web Application은 반드시 하나의 DD파일을 가져야 합니다

  • Web Application에 대해 서블릿 등록, 초기파라미터 등록, 보안 설정 등의 설정을 하는 xml기반 파일입니다

  • WEB-INF 경로 아래 위치합니다

  • Web Application 실행 첫 시점에 메모리에 DD(web.xml)를 로드하여 서비스에 반영합니다. (수정 시 Web Application을 다시 시작해야 합니다)

web.xml의 서블릿 설정 부분을 살펴보겠습니다.

1
2
3
4
5
6
7
8
 <servlet>
  	<servlet-name>basic</servlet-name><!--  서블릿 별칭  -->
  	<servlet-class>step1.BasicServlet</servlet-class><!-- 패키지명.클래스명   -->
  </servlet>
  <servlet-mapping>
  	<servlet-name>basic</servlet-name><!-- 위 서블릿을 지칭   -->
  	<url-pattern>/bs</url-pattern><!-- 클라이언트가 해당 서블릿을 실행시켜 서비스 받기 위한 url   -->
  </servlet-mapping>	 

2번 라인에서 서블릿의 별칭(실제 파일명이 노출되지 않게 합니다)을 지정하고 6번 라인에서 앞과 동일한 별칭으로 mapping을 시켜줍니다.

(mapping은 서블릿을 요청할 때 전체 경로를 알려주면 번거롭기에 간단하게 경로를 표시해주는 것이라고 보시면 됩니다)

3번 라인에서는 패키지명을 포함해서 클래스명을 적어주고, 7번 라인에서 클라이언트가 해당 서블릿을 실행해 서비스를 받기 위한 url을 입력합니다.


xml 파일은 위와 같이 서블릿매핑 정보를 입력해주면 됩니다. 확인해야 할 사항을 정리하면 다음과 같습니다.

  • servlet-name 일치
  • 패키지명.클래스명
  • 슬래쉬

현재까지도 xml 설정이 자바 스프링 기반 회사에서는 지배적으로 사용되고 있습니다. 직접 설정을 할 일은 거의 없겠지만 적어도 구조를 보고 이해할 수는 있어야 할 것 같습니다.



HTTP Request Method: Get과 Post방식

http 메세지는 서버와 클라이언트 간에 데이터가 교환되는 방식입니다. 클라이언트 측에서 서버에게 request(요청)을 보내면 이에 대해 서버는 적절한 response(응답)을 하게 됩니다.

image

위 그림은 GET 메서드를 사용한 http request를 보여주고 있습니다.

  • 첫 번째 줄에는 request method, 요청 파일(URL, 프로토콜, 도메인 절대경로 등으로 나타냄) 그리고 HTTP 버전이 기록됩니다.
  • 빈 줄까지 모두 헤더 영역이며 request에 대한 설명이나 메세지 본문에 대한 설명이 기록됩니다.
  • request에 대한 모든 메타 정보가 전송되면 빈 줄(blank line)이 삽입됩니다.
  • 빈 줄의 아래부분에는 바디가 오게 되는데 GET 방식의 요청에는 보통 바디가 비어 있습니다.

저희는 여기서 첫번째 줄에 나오는 request method 방식에 대해 알아보도록 하겠습니다.


HTTP Request Method에는 GET, POST, PUT, PATCH, DELETE 등의 메서드들이 있습니다.

하지만 이번 시간에는 가장 기본적이고 중요한 GET과 POST 메서드를 공부해보도록 하겠습니다.


참고) http 요청 및 응답 과정에서 web server와 web container의 Deployment diagram입니다

image





GET 방식

: 요청의 기본 방식입니다. 데이터 요청이 목적으로 URL을 통해 요청 파라미터를 전달합니다.

특징

  • 정보 조회
  • URL 상에 전송 정보노출
  • 전송 데이터 용량에 제한이 있음

URL 주소 뒤의 입력데이터(쿼리 스트링)는 은 다음과 같습니다

: URL?name1=value1&name2=value2 (물음표는 구분자입니다)


GET 방식 예제 코드를 보겠습니다.

점심메뉴와 수량을 입력한 후 전송을 누르면 입력한 데이터가 전송됩니다.

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>step2 request get 방식 테스트</title>
    </head>
    <body>
        <form method="get" action="GetTestServlet">
            <input type="text" name="food" placeholder="점심 메뉴" required="required">
            <input type="number" name="count" placeholder="수량" required="required">
            <input type="submit" value="전송">
        </form>
        <hr>
        <a href="GetTestServlet?food=김밥&count=7">get 방식 테스트</a>
    </body>
</html>

get 방식의 form을 사용하며 사용자가 데이터를 입력하고 전송을 누르면 GetTestServlet으로 데이터가 전송되고 다음과 같이 출력됩니다.

image

get 방식이기 때문에 url을 보시면 사용자가 입력한 정보가 노출되어 있는 것을 확인하실 수 있습니다.


서블릿 파일은 다음과 같이 작성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package step2;

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

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

/**
 * Servlet implementation class GetTestServlet
 */
public class GetTestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public GetTestServlet() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //아래는 응답시 한글처리를 위해 charset=utf-8 을 명시한다 
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out=response.getWriter();
		//클라이언트가 전송한 데이터를 입력받는다 
		String info=request.getParameter("food");
		String info2=request.getParameter("count");
		out.println("<h3>GetTestServlet doGet 메서드 실행</h3>");
		out.println("client가 보낸 메뉴 정보:"+info+" "+info2+"인분");
		out.close();
	}
}



이와 별개로 get 방식이 a tag를 이용해 데이터를 전송할 수 있다는 것을 확인하기 위해 html 파일의16번 라인(아래 코드)에서 직접 데이터를 링크에 입력해서 데이터가 전송되는지 확인해보겠습니다.

<a href="GetTestServlet?food=김밥&count=7">get 방식 테스트</a>

image




POST 방식

: 서버에 데이터 전송이 목적으로 Body를 통해 요청 파라미터를 전달합니다.

특징

  • 정보 전달용(주로 서버 자원의 데이터 변경 시 사용)
  • URL 상에 정보 노출 X
  • HTTP Request Body 부분에 저장되어 전송(별도의 한글 처리 필요)
  • 전송 데이터 용량 제한 X


아래는 html 파일과 서블릿 코드입니다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>step3 post test</title>
</head>
<body>
<form action="PostTestServlet" method="post">
<input type="text" name="location" placeholder="지역" required="required">
<br><input type="text" name="nick" placeholder="별명" required="required">
<input type="submit" value="전송">
</form>
</body>
</html>

get 방식과 상당히 유사해 보이지만 코드와 결과물에 약간의 차이가 있습니다.

image


서블릿 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package step3;

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

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

/**
 * Servlet implementation class PostTestServlet
 */
public class PostTestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public PostTestServlet() {
        super();
    }

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//post 방식일때는 요청 정보에 대한 별도의 한글 처리가 필요하다 
		request.setCharacterEncoding("utf-8");	
		//아래는 응답시 한글처리를 위해 charset=utf-8 을 명시한다 
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out=response.getWriter();
		out.println("PostTestServlet doPost");
		String info=request.getParameter("location");
		String nick=request.getParameter("nick");
		out.println(" 지역명 : "+info+" 별명 : "+nick);
		out.close();
	}
}

post 방식의 경우 응답 시의 한글처리 뿐만 아니라 요청 정보에 대한 별도의 한글 처리도 필요합니다.

사용자가 데이터를 입력하고 전송 버튼을 누르면 PostTestServlet으로 데이터가 전달되고, 다음과 같이 화면이 출력됩니다.

image

url 상에는 전달받은 데이터를 노출시키지 않습니다.





Form 연동 예제

이번에는 radio와 checkbox 기능을 활용해서 클라이어트(html form)와 서버(servlet)를 연동해보는 예제를 진행하겠습니다.



Radio 활용

radio 버튼은 여러 개의 항목 중 하나만 선택하도록 하는 기능입니다.

라디오 버튼의 “남”을 선택하고 전송하면 male이 출력되고, “여”를 선택하고 전송하면 female이 출력되도록 해보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>step4 form radio 연동 테스트</title>
</head>
<body>
<form action="RadioServlet">
<input type="radio" name="gender" value="male" required="required"><br>
<input type="radio" name="gender" value="female" required="required"><br>
<button>전송</button>
</form>
</body>
</html>

코드를 보시면 form 태그의 메서드 방식과 버튼 태그의 타입을 설정하지 않았는데, default 값이 설정되어 있습니다.

직접적인 설정이 없다면 form method = "get", button type = "submit"이 기본 설정입니다.

화면에는 다음과 같이 보여집니다.

image

사용자가 둘 중 하나를 선택해서 전송을 누르면 서버에 데이터가 전송되고, 저희는 서블릿에서 전송받은 데이터를 출력하도록 하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package step4;

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

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * Servlet implementation class RadioServlet
 */
public class RadioServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public RadioServlet() {
        super();
    }
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	    response.setContentType("text/html;charset=utf-8");
	    PrintWriter out=response.getWriter();//원칙은 html 양식을 모두 입력해줘야 하지만 편의 상 생략
	    out.println(request.getParameter("gender"));
	    out.close();
	}
}

다음과 같이 출력되고, get 방식으로 전송했기 때문에 url 상에 value값이 노출되는 것을 확인하실 수 있습니다.

image



Checkbox 방식

checkbox는 다중 선택이 가능합니다.

음식 메뉴를 제공해서 사용자가 하나 이상의 메뉴를 선택해 제출하도록 하는 예제를 진행하겠습니다.

그런데 메뉴를 고를 때 아무것도 고르지 않는다면 전송의 의미가 없어지기 때문에 반드시 하나 이상의 메뉴를 고르도록 자바스크립트에서 기능을 작성했습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>step5 form checkbox와 Servlet 연동</title>
</head>
<body>
    <script type="text/javascript">
        function checkForm() {
            let a = document.getElementsByName("menu");
            let flag = false;
            for (let i = 0; i < a.length; i++) {
                if (a[i].checked)
                    flag = true;
            }
            if (!flag) {//하나 이상 체크 되어있지 않다면
                alert("메뉴를 선택하세요")
                return false;//false를 리턴해서 전송시키지 않는다
            }
        }
    </script>
	<form action="CheckboxServlet" method="get" onsubmit="return checkForm()">
		<input type="checkbox" name="menu" value="치킨">치킨<br> 
         <input type="checkbox" name="menu" value="피자">피자<br> 
         <input type="checkbox" name="menu" value="맥주">맥주<br>
		<button type="submit">주문하기</button>
	</form>
</body>
</html>

form 태그에 onsubmit 속성으로 false값이 들어올 경우 submit 하지 않도록 합니다.

메뉴를 한 가지 이상 선택할 경우에만 전송을 해야 하기 때문에, checkForm() 함수에서 배열을 받을 변수를 선언해줍니다.

document.getElementsByName(name) 메서드로 배열을 반환받고, 반복문을 돌리며 if문으로 checked 속성을 이용해 하나 이상 체크되어 있는지 판단합니다.

하나 이상 체크되지 않았으면 if문으로 “메뉴를 선택하세요”라고 alert를 사용해 출력하고 return false를 반환합니다.

onsubmit속성은 false 값이 아닌 다른 경우 정상적으로 다음 작업(submit)을 진행하기 때문에 꼭 true를 리턴받지 않더라도 정상적인 작동을 합니다.


servlet은 다음과 같이 작성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package step5;

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

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

/**
 * Servlet implementation class CheckboxServlet
 */
public class CheckboxServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CheckboxServlet() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	    response.setContentType("text/html;charset=utf-8");
        PrintWriter out=response.getWriter();
        out.println("CheckboxServlet doGet 실행");
        out.println("<hr>");
        // checkbox는 동일한 name으로 다수의 value가 전송될 수 있으므로
        // request.getParameterValues(name): String[]를 이용해서 입력받는다
        String[] list = request.getParameterValues("menu");
        for(int i=0; i< list.length;i++) {
            out.println(list[i]);
        }
        out.println(" 주문완료");
        out.close();
	}
}


checkbox_servlet




HTTP 상태 코드

: 특정 HTTP 요청이 성공적으로 완료되었는지 알려주는 코드입니다. 총 5개의 그룹으로 나뉘는데, 여기서는 간단한 설명만 제공하도록 하겠습니다.

  • 1xx (정보): 요청을 받았으며 프로세스를 계속한다
  • 2xx (성공): 요청을 성공적으로 받았으며 인식했고 수용하였다
  • 3xx (리다이렉션): 요청 완료를 위해 추가 작업 조치가 필요하다
  • 4xx (클라이언트 오류): 요청의 문법이 잘못되었거나 요청을 처리할 수 없다
  • 5xx (서버 오류): 서버가 명백히 유효한 요청에 대해 충족을 실패했다


저희가 지금까지 만나본 상태 코드는 다음과 같습니다.

  • 200: 정상 수행
  • 404: 페이지 찾을 수 없음(자원 없음)
  • 405: 허용되지 않는 메서드

image





맨 위로 이동하기

Java Web Programming 카테고리 내 다른 글 보러가기

댓글남기기