Web & Servlet / request, response

Cheol·2023년 7월 6일
1

edu day 37,38

update

23/07/06 : Web, Servlet 개념, 활용-응답처리
23/07/07 : Servlet 활용-요청처리

📌웹 프로그래밍의 이해

servlet을 사용하기 전 웹(Web)에 대해 자세히 알아보자.


웹 기술🤔???

일반적으로 많이 사용되는 웹의 Client/Server 구조는 다음과 같다.

--> 한번의 요청에 한번의 응답을 받는다.



기본 용어/개념 숙지하기

URL (Uniform Resource Locator)

URL은 웹 서버가 인터넷상에 존재하는 자원(정보, 파일 등)을 검색하고 해석하는데 필요한 네트워크 서비스의 표현식을 의미한다.
문법은 다음과 같으며 웹 브라우저 주소란에 입력되어 사용된다.

프로토콜://호스트 번호:포트 번호:/경로/파일명
http://www.naver.com:80:/index.html


HTTP 프로토콜

Hyper Text Transfer Protocol로서 TCP/IP 통신상의 어플리케이션 프로토콜의 일종으로 웹 클라이언트와 웹 서버간의 통신 규약이다.
기본 port는 80이다.

특징은 다음과 같다.

  • Connectionless 통신방식
    • HTTP요청에 대해 TCP통신을 설정한 후 요청에 대한 응답이 처리되면 TCP연결을 끊어버리는 형태의 통신

  • ❗Stateless 통신방식❗
    • 한 번의 요청에 대해 한 번의 응답으로 HTTP 트랜잭션이 종료

HTTP Request

HTTP 요청은 라인, 헤더, 본체로 구성되어 있는데 특징은 다음과 같다.

  • 요청 라인(Request Line)
    • HTTP 메서드 방식 및 요청 URL과 같은 프로토콜 정보를 갖는다.
  • 요청 헤더(Request Header)
    • 웹 브라우저 정보, 언어, 인코딩 방식, 요청 서버 정보 등과 같은 추가 정보를 갖는다.
  • 요청 본체(Request Body)
    • 요청에 필요한 내용을 갖는다. 일반적으로 HTML 폼 태그 안에 입력된 값들인 파라미터 정보를 의미한다.

HTTP Response

HTTP 응답도 마찬가지로 라인, 헤더, 본체 3가지 요소로 구성된다. 다른 점은 응답 라인이 아닌 상태 라인이다.

  • 상태 라인(Status Line)
    • 응답 상태 코드 및 프로토콜 정보를 갖는다.
  • 응답 헤더(Response Header)
    • 응답처리 날짜, 인코딩 방식, 요청 서버 정보 등과 같은 추가 정보를 갖는다.
  • 응답 본체(Response Body)
    • 응답에 필요한 내용을 갖는다. 일반적으로 HTML 문서이다.

주요 상태 코드

  • 200 : 정상 응답
  • 404 : 파일을 찾을 수 없음
  • 500 : 서버 코드 에러

HTTP method

method는 클라이언트가 서버에 요청을 하는 동작 방식을 의미한다.


GET

  • HTTP 요청시 본문이 없이 헤더만 요청
  • 일반적으로 HTML, Image 요청시에는 GET방식으로 서버에 요청하게 된다.
  • 헤더의 URL 부분에 필요로 하는 정보를 넣어 전송한다.
  • URL에 Input값을 넣을 경우 특수문자는 URL Encoding후 전송한다.

POST

  • 헤더의 URL에는 위치 정보만 담고 있다.
  • 서버로 데이터 전송시 HTTP본문 부분에 Input값을 넣어서 보내되 한글이 깨지니 한글 처리를 해줘야함
  • & 문자를 구분자로 하여 name=value 형태로 데이터를 생성함

❗POST방식은 form에서 밖에 사용하지 못한다. 99% GET방식으로 처리한다.

  • 예시
<HTML>
...
  <!-- 다음과 같이 method 속성에 POST또는 GET을 지정하여 전송 방식 결정-->
  <form name = "form1" action = "/servlet/LoginServlet" method = "POST">
  </form>
...
  <!-- 링크를 이용하는 경우는 GET 방식으로만 가능함 -->
  <a href = "/servlet/MyServlet?id=user01&passwd=12345"> 로그인 </a>
...
</HTML>

웹 컴포넌트

내용추가!!


MVC 패턴

내용추가!



🔎Servlet

서블릿은 웹 컨테이너에 의해서 관리되며, 다양한 클라이언트 요청에 의해서 동적인 컨텐츠(contents)로 응답 가능한 자바 기반의 웹 컴포넌트이다.

특징은 다음과 같다.

  • 자바기반의 웹 컴포넌트로서 java확장자를 갖는다.

  • 클라이언트의 요청에 의해서 동적으로 실행된다. 따라서 다양한 클라이언트 요구 사항을 처리할 수 있다.

  • 서블릿은 반드시 웹 컨테이너에 의해서 관리되며, 스레드로 동적되어 효율적인 요청처리가 가능하다.

  • MVC 패턴의 Controller 역할로서 서블릿이 사용된다.

Servlet Container

서블릿 컨테이너는 Setvlet 컴포넌트를 실행시켜주는 환경을 제공한다.
클라이언트의 HTTP요청을 Servlet에 전달하고, Servlet의 HTTP 응답 결과를 클라이언트에 돌려주는 역할을 한다.(Servlet 엔진이라고도 부른다.)

  • 관련 제품:
    WebSphere, WebLogic, JEUS, Jboss, Tomcat 등

서블릿 작성 및 배포

  • Servlet 클래스 작성: 서블릿 하나는 하나의 클래스
    • javax.sevlet.http.HttpServlet 클래스를 상속 받아 구현
  • web.xml 설정: 서블릿 정의, URL 매핑, config 설정
  • 클래스 배포: WEB-INF/lib, WEB-INF/classes 디렉토리에 배포
  • URL 매핑 처리는 다음 2가지 방법 제공
    • web.xml : WEB-INF파일의 web.xml파일에서 URL 매핑처리한다.

    • @Web : 생성한 servlet의 .java파일에서 @WebServlet 주소를 수정하여 URL 매핑처리한다.
      ❗❗해당 방법을 매우 권장

@Web😁

@WebServlet("/hello")	//내부 주소만 수정

web.xml😭

  <servlet>
  	<servlet-name>HelloServlet</servlet-name>
  	<servlet-class>com.controller.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>HelloServlet</servlet-name>
  	<url-pattern>/xxx</url-pattern>	<!-- URL을 /xxx로 변경 -->
  </servlet-mapping>



Servlet Life Cycle

Tomcat 컨테이너는 서블릿의 인스턴스를 init, service, destroy 메서드를 사용하여 관리한다.

  • init 메서드
    • 웹 컨테이너에 의해서 서블릿 인스턴스가 처음 생성될 때, 단 한번 호출된다.
      따라서 서블릿에서 필요한 초기화 작업 시 주로 사용된다.

  • service 메서드
    • 클라이언트가 요청할 때마다 호출된다.
      따라서 클라이언트가 원하는 동적인 처리 작업 시 필요하다.
      일반적으로 service 메서드 보다는 doGet 또는 doPost 메서드를 사용한다.

  • destroy 메서드
    • 서블릿 인스턴스가 웹 컨테이너에서 제거될 때 호출된다.
      따라서 init 메서드에서 구현했던 초기화 작업을 반납 처리하는 작업 시 주로 사용된다.

서버가 호출될 때 객체를 자동 생성, 응답 후 종료될 때 객체를 삭제한다. 맨 처음 서버 호출할 때 시간이 좀 걸리는 이유가 이 때문이다.



Servlet의 활용~


일단 Servlet 응답 처리를 먼저 알아보자🤔

클라이언트에서 서블릿으로 요청하면 서블릿은 처리된 결과를 HTML 형식으로 작성하여 응답처리한다.

서블릿에서 응답 처리와 관련된 API는 HttpServletResponse 이고 다음과 같은 2가지 메서드를 사용하여 클라이언트에게 HTML을 전송한다.

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

--> 클라이언트인 웹브라우저에서 처리할 데이터의 MIME(ascii/영어가 아닌 문자) 타입을 알려주는 메서드이다.
기본은 일반 텍스트를 의미하는 text/plain이다.

PrintWriter out = response.getWriter();

--> 응답처리는 기본적으로 자바 I/O 기술을 이용한다.
따라서 출력을 위한 OutputStream 또는 Writer API를 사용해야 된다.


  • 예제
    다음과 같은 결과가 나오게 Servlet을 활용해보자. 매핑값은 /info이다.
  • code👍
package com.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("/info")
public class MyServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		String name = "홍길동";
		int age = 20;
		String address = "서울";
		
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		
		String	str  = "<html><head></head><body><table border = '1'><tr>";
				str += "<td>이름</td>";
				str += "<td>나이</td>";
				str += "<td>주소</td></tr>";
				str += "<tr>";
				str += "<td>"+name+"</td>";
				str += "<td>"+age+"</td>";
				str += "<td>"+address+"</td>";
				str += "</tr></table></body></html>";
		
		out.print(str);
	}

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

}

--> 2가지 메서드를 사용하여 선언한 객체 out을 이용해 클라이언트에게 HTML을 전송하게 하여 테이블을 구현한다.
코드는 가독성 있게 구현하였다.


Servlet 요청 처리

form 태그와 파라미터 처리

  • action
    • form 태그의 action은 submit 버튼을 선택했을 때, 웹 서버에서 요청을 처리할 웹 컴포넌트를 지정한다. 즉 html 및 jsp와 servlet 설정이 모두 가능하다.

사용 가능한 형태는 다음과 같다.

<form action = "login.html">	//login.html로 요청
<form action = "login.jsp">		//login.jsp로 요청
<form action = "login">			//login로 매핑된 서블릿으로 요청

  • method : 웹 브라우저에서 웹 서버로 요청하는 처리 방법을 명시한다.

    • GET(get) : 서블릿의 doGet 메서드가 요청을 처리

    • POST(post) : 서블릿의 doPost 메서드가 요청을 처리


Servlet 요청 파라미터 처리 메서드

리턴 타입메서드명내용
StringgetParameter(name)name에 해당되는 파라미터 값을 리턴한다. 만약 지정된 name의 파라미터 값이 없으면 null을 리턴한다.
String[ ]getParameterValues(name)checkbox, radio 태그와 같이 하나의 name에 여러 값을 가지는 경우에 주로 사용된다. name에 해당되는 파라미터 값을 배열로 리턴한다.
EnumerationgetParameterNames()폼 태그 안에 여러 개의 input 태그가 있는 경우에 주로 사용된다. 모든 name값을


📚파라미터 메서드별 사용 예제


📕request.getParameter(name)

❗아래 코드는 모두 Servlet의 doGet함수에서 수행된다.

  • 일단 action의 주소부터 맞춰준다.
//.java file
@WebServlet("/login")

//.html file
<form action="login" method="post">	//메서드를 생략하면 자동으로 get방식으로 호출한다.
  • post 한글처리를 해준다.
request.setCharacterEncoding("utf-8"); //이 한글처리 코드를 안써주면 get처리는 상관 없지만, post처리는 글자가 깨진다.
  • 요청 작업을 처리한다. 이때 Servelt method를 사용한다.
String userid = request.getParameter("userid");	//getParameter()는 값이 하나일때 주로 사용
String passwd = request.getParameter("passwd");	//메서드 키값이 다를 경우 에러가 아닌 null로 반환
  • 응답처리 작업을 한다.
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("<html><body>");
out.println("이름은: "+userid);
out.println("비번은: "+passwd);
out.print("</body></html>");

--> request한 userid, passwd의 value를 response하여 html type으로 출력해줄 수 있다.



📙request.getParameterValues(name)

  • html은 다음과 같다. 공통 name인 fruit를 이용해 value를 전달할거다.
<body>
<h1>폼 실습</h1>
    <h3>좋아하는 과일 선택</h3>
    <form action="TestServlet" method="get">
        사과:<input type="checkbox" name="fruit" value="apple"><br>
        바나나:<input type="checkbox" name="fruit" value="banana"><br>
        수박:<input type="checkbox" name="fruit" value="watermelon"><br>
        <input type="submit" value="전송">
    </form>
</body>
  • 요청 작업 처리
request.setCharacterEncoding("utf-8");
String [] fruits = request.getParameterValues("fruit");	//fruit의 value를 배열로 받는다.
  • 응답처리
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
		
out.print("<html><body>");
for (String s : fruits) {	//foreach를 이용해 fruits 배열에 든 value값을 출력한다.
  System.out.println(s);
  out.print(s+"<br>");
}
out.print("</body></html>");



📒request.getParameterNames()

  • html은 다음과 같다. name값은 다르지만 이 name값들을 Enumeration 타입으로 리턴할것이다.
<body>
<h1>로그인폼</h1>
<form action="login" method="post">
아이디:<input type="text" name="userid"><br>
비밀번호:<input type="text" name="passwd"><br>
<input type="submit" value="로그인">
</form>
</body>
  • 요청작업 처리
//name값에 해당하는 value를 Enumeration<String> 타입으로 받는다.
Enumeration<String> keys = request.getParameterNames();

response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
  • 응답처리
out.print("<html><body>");
while(keys.hasMoreElements()) {		//hasMoreElements()로 종료조건 설정 
	String key = keys.nextElement();	//nextElement로 key값을 넘겨준다.
	String value = request.getParameter(key);
	out.print(key+": " +value + "<br>");
}
out.print("</body></html>");

📗request.getParameterMap()
똑같고 맵의 성질을 지녔다. 설명 생략

  • .html
<body>
<h1>로그인폼</h1>
<form action="login" method="post">
		아이디:<input type="text" name="userid"><br>
		비밀번호:<input type="text" name="passwd"><br>

		사과:<input type="checkbox" name="fruit" value="apple"><br>
        바나나:<input type="checkbox" name="fruit" value="banana"><br>
        수박:<input type="checkbox" name="fruit" value="watermelon"><br>
<input type="submit" value="전송">
</form>
</body>
  • .java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		
		Map<String, String[]> map = request.getParameterMap();
		
		response.setContentType("text/html; charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("<html><body>");
		Set<String> keys = map.keySet();
		for (String key : keys) {
			String [] values = map.get(key);
			String str = "";
			for (String s : values) {
				str += s+"&nbsp";
			}
			out.print(key+": "+str+"<br>");
		}
	}

0개의 댓글