[7.13] 서블릿 (맵핑 & API & 파라미터 처리)
* 서블릿 맵핑
1. web.xml에 등록하는 방법
Servlet 2.5까지 사용하던 방법이며 Servlet 3.x에서도 사용 가능하다.
WEB-INF 폴더안의 web.xml 파일에 다음과 같이 태그와 태그 를 사용하여 설정한다.
여러 개의 서블릿 등록이 가능하며, 주의할 점은 url-pattern 값에는 임의의 값으로 지정 가능하지만 반드시 ‘/’를 사용해야 되고, 태그의 값과 태그의 값도 임의의 값으로 지정 가능하지만 반드시 일치해야 된다.
2. @WebServlet 어노테이션 사용
1) 서블릿 맵핑명만 지정하는 방식 가장 일반적으로 사용되는 방식이다.
@WebServlet("/맵핑명“)
public class MyServlet extends HttpServlet{ ..}
2) 추가 속성을 이용하는 방식
서블릿 별명과 urlPatterns 속성을 사용하여 여러 개의 맵핑명을 지정할 수 있는 방식이다.
@WebServlet( name="서블릿별명“, urlPatterns={ "/맵핑명“, "/맵핑명2” } )
public class MyServlet extends HttpServlet{ ..}
여러 개의 맵핑명을 지정할 수 있는 다른 방식은 value 속성을 사용하는 것이다.
@WebServlet( name="서블릿별명“, value={ "/맵핑명“, "/맵핑명2” } )
public class MyServlet extends HttpServlet{ ..}
<servlet-mapping>에서 <url-pattern> 안의 내용은 Servlet 클래스를 생성할 때 URL mappings 부분과 같다.
* 서블릿 핵심 API
- 클라이언트에서 웹 브라우저를 이용하여 적절한 URL 형식으로 서블릿에 요청하면, 웹 컨테이너에서 서블릿을 실행하고 결과값을 html로 구성하여 클라이언트로 응답 처리한다.
1. HttpServletRequest API
- HTTP Request 관련 작업을 처리하는 핵심 API
- 클래스가 아닌 인터페이스로 제공된다.
2. HttpServletResponse API
- HTTP Response 관련 작업을 처리하는 핵심 API
- 클래스가 아닌 인터페이스로 제공된다.
3. HttpServlet API
- 서블릿을 구현하기 위한 핵심 API로서, 추상 클래스로 제공된다.
<< 계층구조 >>
1. 최상위 - Servlet 인터페이스
(구성)
- 초기화 작업에 필요한 init(ServletConfing) 메서드
- 핵심 로직 작업에 필요한 service(request,respons) 메서드
- 자원 반납 처리작업에 필요한 destroy() 메서드
2. 그 아래 - GenericServlet 추상 클래스
(구성)
- 초기화 파라미터 작업에 필요한 getInitParameter(String) 메서드
- 서블릿명을 알 수 있는 getServletName() 메서드 등
3. 하위 - HttpServlet 추상 클래스
(구성)
HttpServletRequest와 HttpServletResponse 2개의 인자를 가진 doGet 또는 doPost 메서드
* 서블릿 LifeCycle 메서드
- 톰캣 컨테이너는 서블릿의 인스턴스(instance)를 init, service, destroy 3가지 메서드를 사용 하여 관리한다.
1) init 메서드
- 웹 컨테이너에 의해서 서블릿 인스턴스가 처음 생성될 때, 단 한번 호출된다.
- 따라서 서블릿에서 필요한 초기화 작업 시 주로 사용된다.
2) service 메서드
- 클라이언트가 요청할 때마다 호출된다.
- 따라서 클라이언트가 원하는 동적인 처리 작업 시 필요하다.
3) destroy 메서드
- 서블릿 인스턴스가 웹 컨테이너에서 제거될 때 호출된다.
- 따라서 init 메서드에서 구현했던 초기화 작업을 반납 처리하는 작업 시 주로 사용된다.
* 서블릿에서 파라미터 처리
- HTML 의 input 태그에 값을 지정하고 submit 버튼을 선택하면, 서버에 파라미터(폼 데이터) 가 전송된다.
요청받은 서블릿은 HttpServletRequest 객체의 3가지 메서드를 사용하여 파라미터 값을 얻을 수 있다.
(* 수업에서 scoop으로 Postman 설치해서 폼 데이터 간편하게 생성하여 실습 진행 )
1. getParameter(name) 메서드 / 리턴타입 : String
- 아이디의 name 값을 userid로 지정한다. 서블릿에서는 getParameter("userid") 메서드 로 입력된 아이디 값을 얻을 수 있다.
- 비밀번호의 name 값을 passwd로 지정한다. 서블릿에서는 getParameter("passwd") 메 서드로 입력된 비밀번호 값을 얻을 수 있다.
@Log4j2
@NoArgsConstructor
@WebServlet("/Login")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
log.trace("service({}) invoked.");
// Step.1 전송파라미터 획득
String userid = req.getParameter("userid");
String passwd = req.getParameter("passwd");
log.info("\t + userid: {}, passed: {}", userid, passwd);
// Step.2 에코(echo)
res.setCharacterEncoding("utf8");
@Cleanup
PrintWriter out = res.getWriter();
out.println("<ul>");
out.println(" <li>"+ userid+ "<li>");
out.println(" <li>"+ passwd+ "<li>");
out.println("</ul>");
} // service
} // class
2. getParameterValues(name) 메서드 / 리턴타입 : String [ ]
- 하나의 name에 여러 값을 가지는 checkbox와 radio 태그를 이용한 실습 예제
- 파라미터 값을 서블릿에서 getParameterValues(name) 메서드를 사용하여 얻고 결과값을 출력한다.
@Log4j2
@NoArgsConstructor
@WebServlet("/Sport")
public class SportServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
log.trace("service(req, res) invoked.");
// Step.1 전송파라미터 획득
req.setCharacterEncoding("utf8");
String gender = req.getParameter("gender");
String[] sports = req.getParameterValues("sports");
log.info("\t+ gender: {}, sports: {}", gender, Arrays.toString(sports));
// Step.2 응답문서 생성 및 전송
res.setContentType("text/html; charset=utf8");
@Cleanup("close")
PrintWriter out = res.getWriter();
out.println("<ol>");
for(String sport : sports) {
out.println("\t<li>"+sport+"</li>");
} // enhanced for
out.println("</ol>");
out.flush();
} // service
} // end class
- 파라미터 값이 한글인 경우에는 반드시 한글 인코딩 처리를 해야 된다.
- 주의할 점은 반드시 파라미터 값을 얻기 전에 지정해야 된다.
req.setCharacterEncoding("utf8");
- request.getParameterValues("sports") 메서드를 사용하여 checkbox에서 선택한 값들을 배열로 리턴 받는다.
- 향상된 for 문을 사용하여 배열값을 출력한다.
<콘솔 log>
< + Postman을 이용해 서버에 전송할 데이터 생성하는 방법 >
먼저, 전송방식을 선택한다.
POST 방식 - Body 이용 / GET 방식 - Params 이용
(get방식으로 할 때, url 뒤에 쿼리스트링이 생기는 이유 - get방식은 request 행에 담기기 때문에)
KEY와 VALUE 값을 작성한 후, 오른쪽 Send 버튼 클릭하면 서버로 데이터가 전송된다.
3. getParameterNames() 메서드 / 리턴타입 : Enumeration
@Log4j2
@NoArgsConstructor
@WebServlet("/Member")
public class MemberServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
log.trace("service(req,res) invoked.");
// Step.1 전송파라미터 획득
req.setCharacterEncoding("utf8");
Enumeration<String> enu = req.getParameterNames();
// Step.2 응답화면 생성 및 전송
res.setContentType("text/html; charset=UTF-8");
@Cleanup
PrintWriter out = res.getWriter();
out.println("<ol>");
while(enu.hasMoreElements()) {
String paramName = enu.nextElement();
String paramValue = req.getParameter(paramName);
log.info("\t+ paramName: {}, paramValue: {}", paramName,paramValue);
out.println( String.format("<li> %s : %s </li>", paramName, paramValue) );
} // while
out.println("</ol>");
out.flush();
}// service
}
- HTML 태그의 name 값만을 얻기 위해서 getParameterNames() 메서드를 사용하여 Enumeartion 타입으로 리턴 받는다.
- Enumeration의 hasMoreElements() 메서드와 nextElement() 메서드를 사용하여 name 값을 먼저 얻고, getParameter(name) 메서드를 사용하여 value 값을 나중에 얻어 출력한다.
- Postman에서 데이터 작성 & 전송
<콘솔 log>