Servlet
Web
- 웹프로그래밍이란 웹어플리케이션을 구현하는 행위
- Protocol : 네트워크상에서 약속한 통신규약(Http,FTP,SMTP,POP,DHCP)
- IP : 네트워크상에서 컴퓨터를 식별할 수 있는 주소
- DNS : IP주소를 인간이 쉽게 외우도록 맵핑한 문자열
- Port : IP 주소가 컴퓨터를 식별하게 해준다면 Port 번호는 해당컴퓨터의 구동되고있는 프로그램을 구분할 수 있는 번호
- 웹 동작
- 웹서버 : 클라이언트의 요청에 의해 정보를 제공해주는 서버(Aphach)
- 웹 브라우저 : 웹서버에 정보를 요청(request) 하고 웹서버로부터 응답(response)을 받는 매개체
servlet
-
.java 확장자 사용, java thread 이용하여 동작함.
- 자바를 이용해 웹을 만들기 위해서 필요한 기술(클라이언트의 요청에 응답)
사용자가 어떠한 동작(요청) 을 하면 동작에 대한 응답 을 해줘야 함. 그것이 바로 서블릿임. 서블릿은 자바로 구현된 CGI 라고 불림
- MVC 패턴에서 Controller 로 이용됨.
웹 서버는 정적인 페이지만 제공함. 웹서버가 동적인 페이지를 제공하기 위해 도와주는 어플리케이션(CGI)이 서블릿임.
servlet Container(Tomcat)
서버에 서블릿을 만들었다고 스스로 동작하는것이 아님, 서블릿을 관리해주는것이 필요함. 그것이
Tomcat
- 서블릿을 위한 상자, 동작(요청,응답,웹서버와 소켓으로 통신)을 담당(통신 지원, 생명주기 관리, 선언적인 보안 관리, JSP 지원)
servlet 구조
- 기본적으로 Servlet 클래스는 기본적으로 HttpServlet 을 상속받음.
- 클라이언트에서 임의 동작에 대한 요청: HttpServletRequest 객체(요청 처리 객체)
- 요청에 대한 정보를 다시 보냄 : HttpServletResponse 객체(응답 처리 객체)
- 두개의 객체에 담아 요청/응답 처리를 함.
// 응답 처리 객체에 담길 정보의 타입을 html 으로 인코딩 값을 euc-kr 으로 지정 response.setContentType("text/html; charset=euc-kr"); // 서블릿은 java 파일이라 PrintWriter 스트림을 가져와 출력 PrintWriter writer = response.getWriter(); writer.println("<html>"); ...
- HTML Form 태그 method 속성값에따라 = doGet(), doPost() 두개의 메소드로 바뀜
- GET : URL 값으로 정보가 전송되어 보안에 약함.
- html 내 from 태그의 method 값이 get일경우 doGet() 호출
-
웹브라우저의 주소창을 이용하여 servlet을 요청한 경우에도 doGet() 호출
- POST : header를 이용해 정보가 전송되어 보안에 강함.
- html 내 from 태그의 method 값이 post일경우 doPost() 호출
// HTML <form action="He" method="post"> <input type="submit" value="post"> </form> // servlet protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doPost"); response.setContentType("text/html; charset=utf-8"); PrintWriter writer = response.getWriter(); writer.println("<html>"); writer.println("<head>"); writer.println("</head>"); writer.println("<body>"); writer.println("<h1>Hello~~~Post</h1>"); writer.println("</body>"); writer.println("</html>"); }
- Context Path
WAS(Web Appliaction Server) 에서 웹어플리케이션을 구분하기 위한 Path 이클립스에서 프로젝트 생성 시 자동으로 server.xml 에 추가됨.
<Context docBase="servletPjt" path="/servletPjt" reloadable="true" source="org.eclipse.jst.jee.server:servletPjt"/>
작동 순서
클라이언트에서 servlet 요청이 들어오면 서버에서는 servlet 컨테이너를 만들고 요청이 있을 때마다 스레드가 생성됨.
- 사용자가 URL을 입력하면 HTTP Request 가 Servlet Container 로 전송
- 요청받은 container 는 HttpServletRequest, HttpServletResponse 객체를 생성
- web.xml 을 기반으로 사용자가 요청한 URL 이 어느 서블릿에 대한 요청인지 확인
- 해당 서블릿은 service 메소드를 호출 후 클라이언트의 요청방식(get/post)에 따라 doGet(), doPost()를 호출
- 해당 메소드(doGet(),doPost())는 동적 페이지를 생성 후 생성된 HttpServletResponse 객체에 응답을 보냄
- 응답이 끝나면 생성된 두 객체 삭제
- 생명주기
- 서블릿 객체 생성 - 최초 한번
- init() - 최초 한번
- 반복[service() > doXXX()] - 요청시 매번
- destory() - 마지막 한번(자원 해제, servlet 수정, 서버 재가동 등)
- 서블릿 종료
Servlet 은 최초 요청 시 객체가 만들어져 메모리에 로디오디고 이후 요청시에는 기존의 객체를 재활용해 동작이 빠름.
- Servlet 선처리, 후처리
Servlet 객체 생성 > @PostConstruct 어노테이션 사용 해 메소드 선언 시 Init() 호출 전 한번 실행됨. > 이후 모든작업이 끝나고 @PreDestroy 어노테이션 사용 해 메소드 선언 시 destroy() 호출 후 한번 실행됨.
@PostConstruct private void initConstruct() { System.out.println("선처리"); } @PreDestroy private void Predestroy() { System.out.println("후처리"); }
맵핑
- 너무 길고 보안에 노출되어 있는 url 경로를 간단하게 맵핑하는 것
- 기존경로 :
localhost:8080/hello(ContextName)/servlet/com.javaservlet.ex.helloServlet
- URL 맵핑 경로 :
localhost:8080/hello(컨텍스트명)/hello
- 기존경로 :
-
맵핑 방법은 2가지 존재 (web.xml 에 서블릿 맵핑, 어노테이션을 활용한 서블릿 맵핑)
- web.xml 에 서블릿 맵핑
<servlet>
// 지정한 클래스의 이름을 부여
<servlet-name>Hello</servlet-name>
// com.javaweb.ex.HelloServlet 의 클래스 지정
<servlet-class>com.javaweb.ex.HelloServlet</servlet-class>
</servlet>
// 지정한 클래스의 서블릿 이름을 맵핑해야함.
<servlet-mapping>
// 클래스의 부여한 servlet-name 을 가져온뒤
<servlet-name>Hello</servlet-name>
// url 태그를 이용해 /Mapping 이라고 지정함.
<url-pattern>/Mapping</url-pattern>
</servlet-mapping>
// 실행 시 http://localhost:8181/servletPjt/Mapping 으로 정상적으로 맵핑되는 url 주소 보여짐.
- servlet-name 은 임의의 이름을 만듬
- servlet-class 는 맵핑할 정확한 패키지 및 클래스명 작성해야함.
-
url-pattern 은 반드시
/
로 시작해야함. - 어노테이션을 이용한 서블릿 맵핑
@WebServlet("/He") //어노테이션을 사용해 맵핑할 수 있음.
public class HelloServlet extends HttpServlet {
}
- 맵핑 할 url 주소는 반드시
/
로 시작해야함.
Servlet Parameter
- from 태그의 submit 버튼을 클릭하여 데이터를 서버로 전송하면 해당파일(Servlet)에서는 HttpServletRequest 객체를 이용해 파라미터 값을 얻을 수 있음.
<input name="value"/>
에서 name 값을 통해 servlet 에서 값을 얻을수있음.- HttpServletRequest 객체를 이용해 파라미터값을 얻음.
- getParameter(name) : 해당하는 데이터를 가져옴.
- getParameterValues(name) : 다수의 값을 가져올때 사용
- getParameterNames() : HTML 의 폼 name 을 가져옴.
<form action="He" method="post"> 이름:<input type="text" name="name" size="10" /> 아이디:<input type="text" name="id" size="10" /> 비밀번호<input type="password" name="password"/> <input type="checkbox" name="hobby" value="cook" />요리 <input type="checkbox" name="hobby" value="swim" />수영 <input type="checkbox" name="hobby" value="sleep" />잠 <input type="submit" value="post"> </form>
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doPost"); String name = request.getParameter("name"); String id = request.getParameter("id"); String password = request.getParameter("password"); String[] list = request.getParameterValues("hobby"); response.setContentType("text/html; charset=EUC-KR"); PrintWriter writer = response.getWriter(); writer.println("<html><head></head>"); writer.println("<body>"); writer.println(name + " 님 안녕하세요"); writer.println(id + " 입니다."); writer.println(password + " 개인정보"); writer.print(Arrays.toString(list)); writer.println("</body>"); writer.println("</html>"); }
한글처리
Tomcat 서버의 기본 문자 처리 방식은 IOS-8859-1 방식임. 별도의 한글 인코딩을 하지 않으면 한그링 깨져보임. Get 방식과 Post 방식에 따라 한글처리 방식에 차이가 있음.
- Get 방식
- server.xml 을 수정해야함.
// Server.xml <Connector URIEncodeing="UTF-8"></Connector> // Servlet.java response.setContentType("text/html; charset=UTF-8");
-
Post 방식
request.setCharacterEncoding("UTF-8"); response.setContentType("text/html; charset=UTF-8");
서블릿 초기화 파라미터
특정 Servlet 이 생성될 때 초기에 필요한 데이터들을 초기화 파라미터라 하며, web.xml 에 기술하고 Servlet 파일에서는 ServletConfig 클래스를 이용해 접근(사용) 함.
- web.xml 이용 방식
- Servlet 클래스 제작
- web.xml 파일에 초기화 파라미터 기술
- ServletConfig 메소드 이용해 데이터 불러오기
// web.xml 파일에 초기화 파라미터 기술 <servlet> <servlet-name>ServletInit</servlet-name> <servlet-class>com.servletinitparam.ServletInitParam</servlet-class> <init-param> <param-name>id</param-name> <param-value>초기id</param-value> </init-param> <init-param> <param-name>pw</param-name> <param-value>초기pw</param-value> </init-param> <init-param> <param-name>path</param-name> <param-value>c:\workspace</param-value> </init-param> </servlet>
//서블릿 생성 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html; charset=UTF-8"); System.out.println("doGet"); // ServletConfig 메소드(getInitParameter()) 이용해 데이터 불러오기 String id = getInitParameter("id"); String pw = getInitParameter("pw"); String path = getInitParameter("path"); response.setContentType("text/html; charset=UTF-8"); PrintWriter writer = response.getWriter(); writer.println("<html>"); writer.println("<head>"); writer.println("</head>"); writer.println("<body>"); writer.println("id : "+ id + "</br>"); writer.println("pw : "+pw+ "</br>"); writer.println("path : "+path+ "</br>"); writer.println("</body>"); writer.println("</html>"); }
- Servlet 이용 방식
Servlet 파일에 초기화 파라미터 기술
- Servlet 클래스 제작
- @WebInitParam 에 초기화 파라미터 기술
- ServletConfig 메소드 이용해 데이터 불러오기
@WebServlet(urlPatterns = {"/InitParam"}, initParams={@WebInitParam (name="id",value="aaaa"), @WebInitParam (name="pw",value="pwww")}) String id = getInitParameter("id"); String pw = getInitParameter("pw");
데이터 공유(ServletContext)
- 여러 Servlet 에서 특정 데이터를 공유해야 할 경우 context parameter 를 이용해 web.xml 에 데이터를 기술하고 Servlet 에서 공유하면서 사용 가능
<context-param>
<param-name>id</param-name>
<param-value>idvalue</param-value>
</context-param>
<context-param>
<param-name>pw</param-name>
<param-value>pw값</param-value>
</context-param>
String id = getServletContext().getInitParameter("id");
String pw = getServletContext().getInitParameter("pw");
웹 어플리케이션 감시(ServletContextListener)
- 웹어플리케이션의 생명주기를 감시하는 리스너, 리스너의 해당 메소드가 웹 어플리케이션 시작과 종료 시 호출됨.
// 사용 시 ServletContextListener 인터페이스 구현해야함.
public class ServletL implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("contextDestroyed");
}
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("contextInitialized");
}
}
<listener>
<listener-class>com.servletinitparam.ServletL</listener-class>
</listener>