컴퓨터 프로그래밍/servlet

servlet의 필드값 저장하고 읽어들여 초기화

깝돌이 2020. 6. 3. 13:11

servlet의 필드 최종 값을 프로그래밍이 꺼질때 DB 저장(destroy())해야하고, 다시 DB에서 가져와야(init())합니다. 

서블릿 필드값 count값을 영구적으로 보관할 수 있는 방법은 지금으로서는 없습니다. 왜냐하면 서버가 stop되는 순간 destroy() callback 함수가 자동으로 호출되어 지고,  서블릿 인스턴스를 메모리에서 unbound 시켜버리기 때문입니다. 서버가 내려가더라도 서비스를 수행한 후 필드에 저장시킨 값을 영구적으로 보관하려면

1) DB
2) file(수업은 이것으로 합니다)

 위 두가지의 형태로 자료를 저장해야합니다.  이때 서블릿 라이프 사이클 메소드가 중요하게 사용되어 집니다.
1) 해당 필드값을 파일로 출력 : destroy()
2) 파일에 저장된 값을 읽음:  init()

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>lifeCycle</title>
</head>
<body>
<h2 align="center">LifeCycle....CallBack Method Test...</h2>
<a href="life3">LifeCyle Test...click</a>
</body>
</html>
/*
 * 서블릿 필드값 count값을 영구적으로 보관할 수 있는 방법은 지금으로서는 없다.
 * 왜냐하면 서버가 stop되는 순간 destroy() callback 함수가 자동으로 호출되어 지고, 
 * 서블릿 인스턴스를 메모리에서 unbound 시켜버리기 때문이다. 
 * 
 * 서버가 내려가더라도 서비스를 수행한 후 필드에 저장시킨 값을 영구적으로 보관하려면 
 * 1) DB
 * 2) file(수업은 이것으로 합니다)
 * 이때 서블릿 라이프 사이클 메소드가 중요하게 사용되어 진다.
 * 1) 해당 필드값을 파일로 출력 : destroy()
 * 2) 파일에 저장된 값을 읽음:  init()
 */
package servlet.life;

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;

public class ServletLifeCyleTest3 extends HttpServlet {
	private static final long serialVersionUID = 1L;
    private int count = 0;
    private String path="c:\\filestore\\life\\count.txt";//컴퓨터는 이것을 디렉토리로 구분합니다. 
    
    
    public ServletLifeCyleTest3() {
        super();
        System.out.println("1. ServletLifeCyleTest1...call by container(WAS)");
    }

	public void init() throws ServletException {
		System.out.println("2. init...call by container(WAS)");
		//서버가 다시 시작되리 때 init()에서 파일에 저장된 내용을 읽어서 필드 count에 다시 할당
		//0이 아닌 해당 숫자 이후부터 카운팅이 진행된다.
		try {
			BufferedReader br = new BufferedReader(new FileReader(path));
			String str=br.readLine();
			count=Integer.parseInt(str);
			System.out.println("count.txt 파일의 내용을 읽어들임 count:: "+count);
			br.close();
		}catch(IOException e){
			System.out.println("파일을 읽어들이는데 실패했습니다. ");
		}
	}

	public void destroy() {
		System.out.println("4. destroy...call by container(WAS)");
		//필드에 저장된 값을 파일로 뿌리고..... 서버가 내려질 것입니다. 
		File file = new File(path);
		//출력용 파일이 출력스트림에서 자동적으로 생선되려면 그전에 반드시 디렉토리는 먼저 만들어져 있어야합니다. 
		file.getParentFile().mkdirs();//"c:\\filestore\\life\\count.txt"에서 count.text를 제외 하고 만든다.getParentFile()을 해주고 .mkdirs를 쓰는게 안전합니다. 
								// 이렇게 해서 파일을 제외한 디렉토리를 만들어 줍니다. 
		try {
			PrintWriter pw = new PrintWriter(new FileWriter(file));
			//PrintWriter pw = new PrintWriter(new FileWriter(file, true(append)), true(autoflush);
			pw.println(count);
			pw.close();
			System.out.println(path+"count 값:: "+count +" 파일에 영구적으로 저장됨....");
		}catch(IOException e) {
			System.out.println("스트림 생성 실패....");
		}
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doProcess(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doProcess(request, response);
	}
	protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("3. service...call by container(WAS)");
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		//web browser로 출력
		out.println("<html><body bgcolor='yellow'>");
		out.println("<h3>LifeCycle CallBack Method...</h3>");
		out.println("<b>Count::"+ ++count+"</b>");
		out.println("</body></html>");
		out.close();
	}
	

}