본문 바로가기

Java, Spring/09일

9일차 3 - properties 파일 적용하기

이어서..

현재는 Action이 추가될 때 마다 DispatcherServlet을 수정해야 하잖아.

		ModelAndView mav = null;
		
		if(command.equals("/Login.do")){
			controller = new Login();	//upcast
			mav = controller.handleRequestInternal(request, response);
		} else if(command.equals("/LoginAction.do")){
			controller = new LoginAction();
			mav = controller.handleRequestInternal(request, response);			
		}		
		

이거 좀 귀찮어..

그래서 property파일을 만들거야. (이런경우 보통 property파일을 만드는 경우와 xml을 사용하는 경우가 있지. 근데 속성파일을 xml로 사용할 경우 xml에 대한 정의를 또 해야하는 등 할 일이 좀 많아. 그냥property속성파일로 하자. )

WEB-INF밑에 conf폴더 만들고 New->File

dispatcher-servlet.properties 파일 만들어

 

주석은 #을 앞에 붙이는데 글자가 UTF코드로 출력이 돼. 불편하잖아.

#\ub85c\uadf8\uc778 \ud3fc
/Login.do=controller.Login

#\ub85c\uadf8\uc778 \ud655\uc778
/LoginAction.do=controller.LoginAction

#\uac8c\uc2dc\ud310 \ub9ac\uc2a4\ud2b8
/BoardList.do=controller.BoardList

#\uac8c\uc2dc\ud310 \uae00\uc4f0\uae30 \ud3fc
/BoardInsert.do=controller.BoardInsert

#\uac8c\uc2dc\ud310 \uae00\uc4f0\uae30 \ub370\uc774\ud130\ub97c DB\uc5d0 \uc800\uc7a5
/BoardInsertAction.do=controller.BoardInsertAction

#\uac8c\uc2dc\ud310 \uc0c1\uc138\ubcf4\uae30	
/BoardView.do=controller.BoardView

#\uae00\uc218\uc815 \ud3fc	
/BoardUpdate.do=controller.BoardUpdate

이럴때 plugin 깔면 편해.

Add.. 버튼

properties editor - http://propedit.sourceforge.jp/eclipse/updates

이제 화면에 잘 나와..

#로그인 폼
/Login.do=controller.Login

#로그인 확인
/LoginAction.do=controller.LoginAction

#게시판 리스트
/BoardList.do=controller.BoardList

#게시판 글쓰기 폼
/BoardInsert.do=controller.BoardInsert

#게시판 글쓰기 데이터를 DB에 저장
/BoardInsertAction.do=controller.BoardInsertAction

#게시판 상세보기	
/BoardView.do=controller.BoardView

#글수정 폼	
/BoardUpdate.do=controller.BoardUpdate

 

 

이제 이 property파일을 servlet에서 읽을 수 있게 해줘야지.

web.xml에 dispatcher-servlet.properties등록

  
  <servlet>
  	<servlet-name>dispatcher</servlet-name>
  	<servlet-class>controller.DispatcherServlet</servlet-class>
  	<init-param>
  		<param-name>dispatcher-servlet</param-name>
  		<param-value>C:/Java/workspace/webdev/WebContent/WEB-INF/conf/dispatcher-servlet.properties</param-value>
  	</init-param>
  </servlet>
  <servlet-mapping>
  	<servlet-name>dispatcher</servlet-name>
  	<url-pattern>*.do</url-pattern>
  </servlet-mapping>    
  

param-value는 다음과 같이 찾아서 가져다 붙이고 \를 /로 바꿔줘..

 

이제 DispatcherServlet에서 처리해야지.. DispatcherServlet가 처음 수행이 될 때, 즉 DispatcherServlet의 인스턴스가 처음 한번 만들어질 때 파일을 가지고 오지. 이 servlet 으로 전달이 될 때 맨 처음에 ,, .serlvet은 한번 만들어지면 다른 데서 로드를 하게 되면 계속 이용이돼. 내부적으로 servlet하나가 thread형태로 동작해. 여러개를 안만들고..

최초 한번을 만들 때 init이라는 method가 한번 실행되게 되어있어. 그래서 init에다가 property 파일의 정보를 읽어서 맵에다 넣어놓게 하는거지.

init method override해.. HttpServlet에 없네.. 그 부모인 GenericServlet에 있어..

 

package controller;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

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

public class DispatcherServlet extends HttpServlet {
	
	//properties 받을 맵 생성
	private Map<String, AbstractController> commandMap
		= new HashMap<String, AbstractController>();

	//servlet 최초에 실행하는 메서드
	@Override
	public void init(ServletConfig config) throws ServletException {
		
		//param-value(property 파일의 경로)를 읽어와				
		String props = config.getInitParameter("dispatcher-servlet");

		Properties pr = new Properties();
		FileInputStream f = null; //filestream 사용
		
		try {
			f = new FileInputStream(props);
			pr.load(f);	//property 파일 내용을 읽어와
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if ( f != null ) try {f.close();} catch (Exception e){}
		}	
		
		Iterator keyiter = pr.keySet().iterator();		
		while(keyiter.hasNext()){
			String command = ((String) keyiter.next()).trim();
			String classname = pr.getProperty(command).trim();

			//뭔가 실행을 할 때 new하면 오래걸리니까 미리 new 해놔
			//그렇게 만든 인스턴스 자체를 맵에 넣어놓는거지..
			try {
				//드라이버 있는지 판단
				Class commandClass = Class.forName(classname);
				
				//instance 생성해놓고
				AbstractController commandInstance = 
						(AbstractController) commandClass.newInstance();
				//맵에 넣어놔
				commandMap.put(command, commandInstance);								
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
		}		
	}

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		//요청이름만 짤라내
		String requestURI = request.getRequestURI();
		String contextPath = request.getContextPath();
		String command = requestURI.substring(contextPath.length());

		AbstractController controller = null;
		ModelAndView mav = null;
		
/*		if(command.equals("/Login.do")){
			controller = new Login();	//upcast
			mav = controller.handleRequestInternal(request, response);
		} else if(command.equals("/LoginAction.do")){
			controller = new LoginAction();
			mav = controller.handleRequestInternal(request, response);			
		}	*/	
		
		//맵에 넣어놓은 instance를 받아와.
		controller = commandMap.get(command);
		mav = controller.handleRequestInternal(request, response);
		
		if(mav != null) {
			if (mav.isRedirect()){
				response.sendRedirect(mav.getViewName());
			} else {					
				//값보내게..(HashTable (dictionary)에 있는값)
				Enumeration<String> en = mav.getDictionary().keys();
				while(en.hasMoreElements()){
					String key = en.nextElement();
					request.setAttribute(key, mav.getDictionary().get(key));
				}				
				
				RequestDispatcher dispatcher = 
						request.getRequestDispatcher(mav.getViewName());
				dispatcher.forward(request, response);
			}
		} else {
			System.out.println("DispatcherServlet에서 길을 잃었다.");
		}		
	}
}

 

로그인 잘되나 실행해봐..

이제 새로운 클래스가 추가되면 코드를 수정하는 게 아니라 property파일에 한줄 추가하면 되지.