본문 바로가기
Java Web Programming/3. Servlet

[Servlet] 서블릿 ServletConfig / ServletContext

by 파프리카_ 2020. 8. 21.
728x90
반응형

[ ServletConfig ]

: Config = Configration 

: 개별 서블릿이 실행하기 위해 필요한 설정 정보를 제공

개별 서블릿 객체 당 하나씩 생성 (web container에 의해 init() 메서드 실행 시 전달됨)

→ 초기 파라미터 (init-param), ServletContext 객체의 주소값 등이 ServletConfig 객체에 저장된다.

→ 코드와 설정 정보를 분리해서, 유지보수성을 향상시킬 수 있다. (코드 - Servlet / 설정 정보 - xml / ServletConfig로 연결)

 

ServletConfig는 javax.servlet의 public interface이다.


ServletConfig를 분석하는 예제

package step1;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * ServletConfig를 분석하는 예제
 */

public class ConfigServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
    
	//instance 변수 정의
	private int serviceCount;
	private String savePath;
	
	//1. Servlet 생성
        public ConfigServlet() {
            super();
            System.out.println(getClass().getName()+ "생성");
        }

        //2. Servlet 초기화 : init() 
        // instance 변수 (serviceCount) 정보 가져옴
        @Override
        public void init() throws ServletException {

            // web.xml에 있는 init-param 읽어오기
            savePath = this.getServletConfig().getInitParameter("savePath");

            try {
                //파일 객체 생성
                File countFile = new File(savePath);

                //파일 읽어올 객체 생성 - 파일일 경우에만x
                if (countFile.isFile()) {

                    BufferedReader br 
                    = new BufferedReader(new FileReader(countFile));

                    //파일 정보 읽어서 인스턴스 변수(serviceCount)에 저장
                    serviceCount = Integer.parseInt(br.readLine());

                    System.out.println("init() 실행 .. 서비수 수, 인스턴스 변수에 할당 완료" +
                                        serviceCount);
                } else {
                    System.out.println("init() 실행");
                }

            } catch (NumberFormatException | IOException e) {
                e.printStackTrace();
            } 
        }

      	//3. service (요청내용 처리&응답)
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		response.setContentType("text/html; charset=utf-8");
		PrintWriter out = response.getWriter();
		out.println("서비스 count:");
		out.println(++serviceCount);
		out.close();
	}

	//4. Servlet 소멸 : destroy()
	// instance 변수 (serviceCount) 정보 저장함
	@Override
	public void destroy() {
		try {
			//파일 저장 객체 설정
			PrintWriter fw 
			= new PrintWriter(new FileWriter(savePath));
			// 파일 저장
			fw.println(serviceCount);
			//파일 저장 객체 닫기
			fw.close();
			
			System.out.println("destroy() 실행");
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}

 

web.xml에 <init-param>에 path 추가

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>webstudy7-ServletConfig-ServletContext2</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <description></description>
    <display-name>ConfigServlet</display-name>
    <servlet-name>ConfigServlet</servlet-name>
    <servlet-class>step1.ConfigServlet</servlet-class>
    
    <!--savePath 경로 추가-->
    <init-param>
      <param-name>savePath</param-name>
      <param-value>C:\\kosta203\\count.txt</param-value>
    </init-param>
  
  </servlet>
  <servlet-mapping>
    <servlet-name>ConfigServlet</servlet-name>
    <url-pattern>/ConfigServlet</url-pattern>
  </servlet-mapping>
</web-app>

 

브라우저 결과


 

추가 예제

 

ServletConfig를 이용해서 Email과 Tel을 반환받음 

public class AdminServlet extends HttpServlet {
	
	private static final long serialVersionUID = 1L;
       
    public AdminServlet() {
        super();
        // TODO Auto-generated constructor stub
    }


	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		response.setContentType("text/html; charset=utf-8");
		PrintWriter out = response.getWriter();
		out.println("<h1>관리자 모드 <br><br><br>");
		
		//adminEmail 과 adminTel이 필요
		//아래 코드는 하드 코딩 -> 변경 시 소스코드 수정, 유지보수성이 낮다
		//String adminEmail = "yewool0818@naver.com";
		//String adminTel = "010-1234-1234";
		
		//ServletConfig를 이용해서 Email과 Tel을 반환받음
		//코드와 설정 정보를 분리해서 유지보수성을 향상시킨다.
		String adminEmail = getServletConfig().getInitParameter("adminEmail");
		String adminTel = getServletConfig().getInitParameter("adminTel");
		
		out.println("관리자 이메일: "+adminEmail+"<br>");
		out.println("관리자 TEL: "+adminTel);
		out.println("</h1>");
		
		out.close();
	}

}

 

web.xml에서 해당 servlet에 init-param에서 설정 정보를 추가해준다.

 


[ ServletContext ]

: web application의 전역에서 공유(사용)할 수 있는 객체이다.

→ 웹 어플리케이션 내 모든 Servlet과 JSP가 공유할 수 있는 정보이다.→ 웹 어플리케이션 시작 시에 생성되고, 종료시에 소멸된다.

→ 단, ServletConfig안에 ServletContext의 주소값이 있기 때문에,

ServletConfig가 있는 객체만 ServletContext의 대상이 된다.

 

→ 대표적인 메서드 : getInitParameter(name), setAttribute(name, value), getAttribute(name) : Object 등이 있다.

1) getInitParameter(name)

  ⇒ web.xml(DD - Deploymet Descriptor : 배포 기술서)에 명시한 데이터(context-param)를 name에 의해 value를 반환 

  ⇒ 코드와 데이터를 분리해서 유지보수성을 향상하기 위해 사용한다

2) setAttribute(name, value)

⇒  특정 정보를 공유하기 위해 사용

3) getAttribute(name)

⇒ 공유한 정보를 반환받기 위해 사용

⇒ return 값은 Object type으로 반환된다.

 


ServletContext를 분석하는 예제

 

두 개의 Servlet class

 

/One.java

package step3;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class One extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public One() {
		super();

	}

	// doGet()
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html; charset=utf-8");
		PrintWriter out = response.getWriter();
		out.println("<h1>  <br><br><br>");
		
		//ServletConfig를 통해 설정정보 가져오기
		String name = getServletConfig().getServletName();
		out.println(name);
		
		//ServletContext 정보 받아오기
		out.println("<br> ServletContext에서 dbUrl을 받아옴");
		String dbUrl =
				getServletConfig().getServletContext().getInitParameter("dbUrl");
		out.println(dbUrl);
		
		//ServletContext에 특정 정보 할당하기
		getServletContext().setAttribute("nick", "펭수");
		out.println("<br><br>ServletContext에 nick을 할당");
		
		// Two Servlet 링크
		out.println("<br><br><a href = Two> Two 서블릿 실행</a>");
		
		// JSP 링크 추가
		out.println("<br><br><a href = contextTest.jsp>contextTest.jsp 실행</a>");
		
		
		out.close();
	}

}

 

/Two.java

package step4;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class Two extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

    public Two() {
        super();

    }

    //doGet()
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    	throws ServletException, IOException {
		response.setContentType("text/html; charset=utf-8");
		PrintWriter out = response.getWriter();
		out.println("<h1> <br><br><br>");
		
		//ServletConfig를 통해 설정정보 가져오기
		String name = getServletConfig().getServletName();
		out.println(name);
		
		//ServletContext 정보 받아오기
		out.println("<br> ServletContext에서 dbUrl을 받아옴");
		String dbUrl =
				getServletConfig().getServletContext().getInitParameter("dbUrl");
		out.println(dbUrl);
		
		//One Servlet에서 ServletContext에 할당한 nick 정보를 받환받기
		//ServletContext는 Object type으로 오기 때문에 downcasting 필요
		String nick = 
				(String)getServletConfig().getServletContext().getAttribute("nick");
		out.println("<br><br>ServletContext로부터 One이 할당한 nick을 반환받아옴 : "+nick);
		
		// One Servlet 링크
		out.println("<br><br><a href = One> One 서블릿 실행</a>");
		
		// JSP 링크 추가
		out.println("<br><br><a href = contextTest.jsp>contextTest.jsp 실행</a>");

		
		out.close();
	}

}

 

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>webstudy7-ServletConfig-ServletContext2</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>

  <servlet>
    <description></description>
    <display-name>One</display-name>
    <servlet-name>One</servlet-name>
    <servlet-class>step3.One</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>One</servlet-name>
    <url-pattern>/One</url-pattern>
  </servlet-mapping>
  
  <servlet>
    <description></description>
    <display-name>Two</display-name>
    <servlet-name>Two</servlet-name>
    <servlet-class>step4.Two</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Two</servlet-name>
    <url-pattern>/Two</url-pattern>
  </servlet-mapping>
  
  <!-- ServletContext는 어플리케이션 전역에서 공유하는 것이기 때문에
  servlet 밖 web application 내에 기재한다 -->
  <context-param>	
  	<param-name>dbUrl</param-name>
  	<param-value>127.0.0.1:3306</param-value>
  </context-param>

</web-app>

 

JSP

/contextTest.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ServletContext Test</title>
</head>
<body>
	<h1>
		contextTest.jsp <br><br>
		ServletContext에서 dbUrl 받아옴 : 
		<%= application.getInitParameter("dbUrl") %><br>
		ServletContext로부터 One Servlet이 할당한 nick을 반환:
		<%= application.getAttribute("nick") %>	<br><br>
		<a href="One">One Servlet으로 이동</a> <br>
		<a href="Two">Two Servlet으로 이동</a>
	</h1>
</body>
</html>

 

 

브라우저

→ web.xml에 기입한 ServletContext의 자원이 두 Servlet에서 공유됨을 확인할 수 있다.

→jsp에서도 ServletContext의 자원 공유가 된다!

→ One Servlet에 할당한 ServletContext(nick)이 Two, jsp에서도 공유된다.

 


getInitParameter()  연습 예제

: ServletContext의 초기 파라미터(init-param)를 반환받아 화면에 출력

 - 직접 adminEmail의 정보(data)를 코드 상에 명시하지 않고(=하드코딩하지 않고),

이후 변경에 유연하게 대처하기 위해(=유지보수성을 위해) ServletContext의 초기 파라미터를 이용해 정보를 반환받는다.

- initParamServlet와 initParamServlet2에서 ServletContext가 서로 공유됨을 확인할 수 있다.

 

Serlvet

/InitParamServlet.java

package step1;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class InitParamServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

    public InitParamServlet() {
        super();
    }


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html; charset=utf-8");
		PrintWriter out = response.getWriter();
		
		out.println("<h2>");	
		
		//getInitParameter() 사용
		//: ServletContext의 초기 파라미터(init-param)를 반환받아 화면에 출력
		String adminEmail = getServletContext().getInitParameter("adminEmail");
		
		//본인 Servlet의 이름을 ServletConfig를 통해 반환받아 화면에 출력
		out.println(getServletConfig().getServletName()+"<br>");
		out.println("관리자 이메일: "+adminEmail+"<br>");
		out.println("<a href=InitParamServlet2> 두번째 서블릿 </a>");
		out.println("</h2>");
		
		out.close();
	}

}

 

/InitParamServlet2.java

package step1;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class InitParamServlet2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

    public InitParamServlet2() {
        super();
    }


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html; charset=utf-8");
		PrintWriter out = response.getWriter();
		
		out.println("<h2>");
		
		//getInitParameter() 사용
		//: ServletContext의 초기 파라미터(init-param)를 반환받아 화면에 출력
		String adminEmail = getServletContext().getInitParameter("adminEmail");
		
		//본인 Servlet의 이름을 ServletConfig를 통해 반환받아 화면에 출력
		out.println(getServletConfig().getServletName()+"<br>");
		out.println("관리자 이메일: "+adminEmail+"<br>");
		out.println("<a href=InitParamServlet> 첫번째 서블릿 </a>");
		out.println("</h2>");
		
		out.close();
	}

}

 

 

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>webstudy8-ServletContext-Exam</display-name>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>
	<servlet>
		<description></description>
		<display-name>InitParamServlet</display-name>
		<servlet-name>InitParamServlet</servlet-name>
		<servlet-class>step1.InitParamServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>InitParamServlet</servlet-name>
		<url-pattern>/InitParamServlet</url-pattern>
	</servlet-mapping>
	<servlet>
		<description></description>
		<display-name>InitParamServlet2</display-name>
		<servlet-name>InitParamServlet2</servlet-name>
		<servlet-class>step1.InitParamServlet2</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>InitParamServlet2</servlet-name>
		<url-pattern>/InitParamServlet2</url-pattern>
	</servlet-mapping>
    
    	<!--context 부분 -->
	<context-param>
		<param-name>adminEmail</param-name>
		<param-value>javaking@kosta.or.kr</param-value>
	</context-param>
    
</web-app>

 

브라우저 결과

링크 클릭하면 !


ServletConfig / ServletContext 총 정리 예제 !

 

 

/index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ServletContext 연습 예제</title>
<link rel="stylesheet" type="text/css" href="css/mystyle.css">
</head>
<body>

<form action = "RegServlet" method ="POST">
	<table>
		<tr>
			<td>별명</td>
			<td><input type="text" name="nick"></td>
		</tr>
		<tr>
			<td>이메일</td>
			<td><input type="email" name="email"></td>
		</tr>
		<tr>
			<td colspan=2 align="center">
			<input type="submit" value="등록">
			</td>
		</tr>
	</table>
</form>

</body>
</html>

 

/RegServlet.java

package step2;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model.MemberVO;

public class RegServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	//ArrayList<MemberVO> list;
	private List<MemberVO> list; //동기화처리한 리스트로 변경해준다.
	
	//init 메서드는 ServletContext의 list를 생성해 할당한다.
	//init 메서드는 단 한 번 실행되고, ServletContext 객체를 사용할 수 있다.
	@Override
	public void init() throws ServletException {
		//멀티스레드에 의해 공유되는 자원이므로 동기화 처리를 해준다.
		//list = new ArrayList<MemberVO>();
		//동기화 처리된 리스트로 할당하는 것으로 변경해본다.
		list = Collections.synchronizedList(new ArrayList<MemberVO>());
		
		//setAttribute(name, value)
		getServletContext().setAttribute("list", list);
	}
	
		
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// contents type + 한글처리
		response.setContentType("text/html; charset=utf-8");

		PrintWriter out = response.getWriter();

		// POST 방식일 때, request 한글 처리
		request.setCharacterEncoding("utf-8");

		// browser에 입력된 정보 받기
		String nick = request.getParameter("nick");
		String email = request.getParameter("email");

		// ServletContext에 저장된 list에 등록 회원 정보를 할당한다.
		list.add(new MemberVO(nick, email));

		out.println(nick+"님 리스트에 등록되었습니다. <br><br>");
		out.println("<a href = ListServlet>등록 목록 보기</a>");
		
		out.close();

	}

}

 

 

/ListServlet.java

package step3;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model.MemberVO;

public class ListServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	List<MemberVO> list;

    //한번 실행되는 init() 메서드에서 
	//ServletContext로부터 리스트를 반환받아서 
	//instance varible에 할당한다
    @SuppressWarnings("unchecked")	
	@Override
    public void init() throws ServletException {
    	//getAttribute(name)
    	list = (List<MemberVO>) getServletContext().getAttribute("list");
    }
    
    //link연결이므로 GET 방식
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		
		//화면에 출력
		for (int i = 0; i < list.size(); i++) {
			out.println(i+1 + "." + list.get(i).getNick() + " "
						+ list.get(i).getEmail() + "<br>");
		}
		
		out.println("<br><br>");
		out.println("<a href=index.html>등록화면으로 이동</a>");
		out.close();
	}

}

 


DB 객체 calss

/memberVO.java

package model;

public class MemberVO {
	private String nick;
	private String email;


	public MemberVO(String nick, String email) {
		super();
		this.nick = nick;
		this.email = email;
	}

	@Override
	public String toString() {
		return "MemberVO [nick=" + nick + ", email=" + email + "]";
	}

	public String getNick() {
		return nick;
	}

	public void setNick(String nick) {
		this.nick = nick;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}
}
728x90
반응형