교육과정 기록/💻back-end

[7.13] 서블릿 (맵핑 & API & 파라미터 처리)

춘식이왔엉 2022. 7. 14. 03:48

* 서블릿 맵핑

 

1. web.xml에 등록하는 방법

Servlet 2.5까지 사용하던 방법이며 Servlet 3.x에서도 사용 가능하다.

WEB-INF 폴더안의 web.xml 파일에 다음과 같이 태그와 태그 를 사용하여 설정한다.

여러 개의 서블릿 등록이 가능하며, 주의할 점은 url-pattern 값에는 임의의 값으로 지정 가능하지만 반드시 ‘/’를 사용해야 되고, 태그의 값과 태그의 값도 임의의 값으로 지정 가능하지만 반드시 일치해야 된다.

프로젝트 DD 안에 Servlet Mappings 확인

 

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>