edu day 37,38
23/07/06 : Web, Servlet 개념, 활용-응답처리
23/07/07 : Servlet 활용-요청처리
servlet을 사용하기 전 웹(Web)에 대해 자세히 알아보자.
일반적으로 많이 사용되는 웹의 Client/Server 구조는 다음과 같다.
--> 한번의 요청에 한번의 응답을 받는다.
URL은 웹 서버가 인터넷상에 존재하는 자원(정보, 파일 등)을 검색하고 해석하는데 필요한 네트워크 서비스의 표현식을 의미한다.
문법은 다음과 같으며 웹 브라우저 주소란에 입력되어 사용된다.
프로토콜://호스트 번호:포트 번호:/경로/파일명
http://www.naver.com:80:/index.html
Hyper Text Transfer Protocol
로서 TCP/IP 통신상의 어플리케이션 프로토콜의 일종으로 웹 클라이언트와 웹 서버간의 통신 규약이다.
기본 port는 80
이다.
특징은 다음과 같다.
- Connectionless 통신방식
- HTTP요청에 대해 TCP통신을 설정한 후 요청에 대한 응답이 처리되면 TCP연결을 끊어버리는 형태의 통신
- ❗Stateless 통신방식❗
- 한 번의 요청에 대해 한 번의 응답으로 HTTP 트랜잭션이 종료
HTTP 요청은 라인, 헤더, 본체로 구성되어 있는데 특징은 다음과 같다.
- 요청 라인(Request Line)
- HTTP 메서드 방식 및 요청 URL과 같은 프로토콜 정보를 갖는다.
- 요청 헤더(Request Header)
- 웹 브라우저 정보, 언어, 인코딩 방식, 요청 서버 정보 등과 같은 추가 정보를 갖는다.
- 요청 본체(Request Body)
- 요청에 필요한 내용을 갖는다. 일반적으로 HTML 폼 태그 안에 입력된 값들인 파라미터 정보를 의미한다.
HTTP 응답도 마찬가지로 라인, 헤더, 본체 3가지 요소로 구성된다. 다른 점은 응답 라인
이 아닌 상태 라인
이다.
- 상태 라인(Status Line)
- 응답 상태 코드 및 프로토콜 정보를 갖는다.
- 응답 헤더(Response Header)
- 응답처리 날짜, 인코딩 방식, 요청 서버 정보 등과 같은 추가 정보를 갖는다.
- 응답 본체(Response Body)
- 응답에 필요한 내용을 갖는다. 일반적으로 HTML 문서이다.
주요 상태 코드
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>
서블릿은 웹 컨테이너에 의해서 관리되며, 다양한 클라이언트 요청에 의해서 동적인 컨텐츠(contents)로 응답 가능한 자바 기반의 웹 컴포넌트이다.
특징은 다음과 같다.
- 자바기반의 웹 컴포넌트로서 java확장자를 갖는다.
- 클라이언트의 요청에 의해서 동적으로 실행된다. 따라서 다양한 클라이언트 요구 사항을 처리할 수 있다.
- 서블릿은 반드시 웹 컨테이너에 의해서 관리되며, 스레드로 동적되어 효율적인 요청처리가 가능하다.
- MVC 패턴의 Controller 역할로서 서블릿이 사용된다.
서블릿 컨테이너는 Setvlet 컴포넌트를 실행시켜주는 환경을 제공한다.
클라이언트의 HTTP요청을 Servlet에 전달하고, Servlet의 HTTP 응답 결과를 클라이언트에 돌려주는 역할을 한다.(Servlet 엔진이라고도 부른다.)
- Servlet 클래스 작성: 서블릿 하나는 하나의 클래스
- javax.sevlet.http.HttpServlet 클래스를 상속 받아 구현
- web.xml 설정: 서블릿 정의, URL 매핑, config 설정
- 클래스 배포: WEB-INF/lib, WEB-INF/classes 디렉토리에 배포
- 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>
Tomcat 컨테이너는 서블릿의 인스턴스를 init
, service
, destroy
메서드를 사용하여 관리한다.
init
메서드
- 웹 컨테이너에 의해서 서블릿 인스턴스가 처음 생성될 때, 단 한번 호출된다.
따라서 서블릿에서 필요한 초기화 작업 시 주로 사용된다.
service
메서드
- 클라이언트가 요청할 때마다 호출된다.
따라서 클라이언트가 원하는 동적인 처리 작업 시 필요하다.
일반적으로service
메서드 보다는doGet
또는doPost
메서드를 사용한다.
destroy
메서드
- 서블릿 인스턴스가 웹 컨테이너에서 제거될 때 호출된다.
따라서init
메서드에서 구현했던 초기화 작업을 반납 처리하는 작업 시 주로 사용된다.
서버가 호출될 때 객체를 자동 생성, 응답 후 종료될 때 객체를 삭제한다. 맨 처음 서버 호출할 때 시간이 좀 걸리는 이유가 이 때문이다.
클라이언트에서 서블릿으로 요청하면 서블릿은 처리된 결과를 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를 사용해야 된다.
/info
이다.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을 전송하게 하여 테이블을 구현한다.
코드는 가독성 있게 구현하였다.
- 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
메서드가 요청을 처리
리턴 타입 | 메서드명 | 내용 |
---|---|---|
String | getParameter(name) | name에 해당되는 파라미터 값을 리턴한다. 만약 지정된 name의 파라미터 값이 없으면 null 을 리턴한다. |
String[ ] | getParameterValues(name) | checkbox, radio 태그와 같이 하나의 name에 여러 값을 가지는 경우에 주로 사용된다. name에 해당되는 파라미터 값을 배열 로 리턴한다. |
Enumeration | getParameterNames() | 폼 태그 안에 여러 개의 input 태그가 있는 경우에 주로 사용된다. 모든 name값을 |
📕request.getParameter(name)
❗아래 코드는 모두 Servlet의 doGet함수에서 수행된다.
//.java file
@WebServlet("/login")
//.html file
<form action="login" method="post"> //메서드를 생략하면 자동으로 get방식으로 호출한다.
request.setCharacterEncoding("utf-8"); //이 한글처리 코드를 안써주면 get처리는 상관 없지만, post처리는 글자가 깨진다.
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)
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()
<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()
똑같고 맵의 성질을 지녔다. 설명 생략
<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>
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+" ";
}
out.print(key+": "+str+"<br>");
}
}