1. 현행 시스템의 문제점 다른 부분은 무시하고 색깔 있는 부분만 보자 현재는 factory 패턴으로 서블릿으로 넘어온 커멘드를 처리하고 있다. --------------------UserServlet.java ------------------------------------------ package sdwa.src.user.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import sdwa.src.common.action.Action; import sdwa.src.common.action.ActionForward; import sdwa.src.user.servlet.UserActionFactory; public class UserServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ActionForward forward = null; Action action = null; try { String command = request.getParameter("command"); UserActionFactory saf = UserActionFactory.getInstance(); action = saf.getAction(command); forward = action.execute(request, response); } catch (Exception e) { throw new ServletException(e.getMessage()); } /* Action에 의해서 전달된 User, List객체들이 response객체를 통하여 전달된다. */ if (forward.isRedirect()) { response.sendRedirect(forward.getPath()); } else { RequestDispatcher rd = request.getRequestDispatcher(forward.getPath()); rd.forward(request, response); } } } ------------------------------------------------------------------------------------ UserActionFactory class 를 살펴보자~ ------------------- UserActionFactory.java --------------------------------------- package sdwa.src.user.servlet; import sdwa.src.common.action.IllegalCommandException; import sdwa.src.common.action.Action; import sdwa.src.user.action.*; public class UserActionFactory { public static UserActionFactory getInstance() { return new UserActionFactory(); } public Action getAction(String command) throws IllegalCommandException { Action action = null; if ("LoginForm".equals(command)) { action = new LoginFormAction(); }else if ("LoginCheck".equals(command)) { action = new LoginAction(); }else if ("Logout".equals(command)) { action = new LogoutAction(); }else if ("GoFindSchoolId".equals(command)) { action = new GoFindSchoolIdAction(); }else if ("GoFindSchoolPw".equals(command)) { action = new GoFindSchoolPwAction(); }else if ("FindSchoolId".equals(command)) { action = new FindSchoolIdAction(); }else if ("FindSchoolPw".equals(command)) { action = new FindSchoolPwAction(); }else{ throw new IllegalCommandException(""); } return action; } } ------------------------------------------------------------------ 문제점은 무엇일까? 1. if, else로 이어지는 분기문 -> 효율성 문제, FindSchoolPw 커멘드를 처리하려면 상위의 if else 비교를 다 하고서야 도달한다. 2. 리로딩문제 -> 추가적인 커멘드 추가시 리 컴파일 해야하는 문제가 발생한다. 2. 해결방법 해결방법은 일단 커멘트와 객체를 매핑하는 부분을 프로퍼티 파일로 따로 분리하여 동적으로 클래스를 로딩하도록 하였다 팩토리 클래스는 없다. --------------------UserServlet.java ------------------------------------------ package sdwa.src.user.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import sdwa.src.common.action.Action; import sdwa.src.common.action.ActionForward; import sdwa.src.common.servlet.ServletMap;; public class UserServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ActionForward forward = null; Action action = null; try { //command - action mapping String command = request.getParameter("command"); action = ServletMap.getInstance().getAction("user", command); forward = action.execute(request, response, reqBox); } catch (Exception e) { throw new ServletException(e.getMessage()); } /* Action에 의해서 전달된 User, List객체들이 response객체를 통하여 전달된다. */ if (forward.isRedirect()) { response.sendRedirect(forward.getPath()); } else { RequestDispatcher rd = request.getRequestDispatcher(forward.getPath()); rd.forward(request, response); } } } ------------------------------------------------------------------------------------ ServletMap 을 살펴보자 --------------------ServletMap.java ------------------------------------------ package sdwa.src.common.servlet; import java.io.File; import java.io.FileInputStream; import sdwa.src.common.log.LogCommand; import sdwa.src.common.action.Action; public class ServletMap { private static ServletMap instance; protected static Object lock = new Object(); //java.util.Properties 관련 게시물 확인해 볼것! protected static java.util.Properties props = null; //property dir location - 프로퍼티 파일 절대 경로 private static final String property_dir = "D:\\src\\WEB-INF\\classes\\src\\conf\\"; //property servlet file location - 프로퍼티 파일 명 private static final String property_ServletMap = "servlet.properties"; //real-time update values - 파일 수정 시간을 비교하여 변경시 파일을 다시 읽어온다. private static long ServletMap_last_modified = 0; private static long last_modified = 0; private ServletMap() throws Exception { initialize(); } public static ServletMap getInstance() throws Exception{ if(instance == null){ instance = new ServletMap(); } return instance; } protected void initialize() throws Exception{ synchronized(lock){ try{ //파일을 다시 읽을 것인지 아닌지 판단 boolean needUpdate = false; //read property_init File ServletMap_file = new File( property_dir+property_ServletMap ); if ( !ServletMap_file.canRead() ) throw new Exception( this.getClass().getName() + " - Can't open Servlet.properties : " + property_ServletMap ); if ( (ServletMap_last_modified != ServletMap_file.lastModified()) || props == null ){ needUpdate = true; } //reload property file if ( needUpdate ){ props = new java.util.Properties(); FileInputStream ServletMap_fin = new FileInputStream( ServletMap_file ); //java.util.Properties 관련 게시물 확인해 볼것! props.load( new java.io.BufferedInputStream( ServletMap_fin ) ); ServletMap_fin.close(); ServletMap_last_modified = ServletMap_file.lastModified(); last_modified = System.currentTimeMillis(); } // end if }catch( Exception ex ){ ex.printStackTrace(); LogCommand.getInstance("error",ex); throw new Exception( this.getClass().getName() + " - Can't open properties: " + ex.getMessage() ); } } // end of sunchronized(lock); } public java.util.Properties getProperties(){ return props; } public long lastModified(){ return this.last_modified; } /** * 시스템 환경설정 config 파일(servlet.properties)의 설정값을 String type 으로 리턴한다. * * @param key * servlet.properties 의 각 옵션별 설정명 * @return String value 를 반환한다. */ public String getProperty(String key) { String value = null; try { String tmp = props.getProperty( key ); if ( tmp == null ) throw new Exception( "value of key(\"" + key + "\") is null" ); value = kfda.src.common.util.StringUtil.korEncode( tmp ); } catch( Exception ex ) { LogCommand.getInstance("error",ex); throw new IllegalArgumentException( "Illegal String Key : " + key ); } return value; } /** * servlet command 를 받아서 action을 반환한다. * @param key * @return */ public Action getAction(String servletName, String command) { Action action = null; String key = ""; try{ key = servletName+"."+command; //STEP01 command로 class 이름을 가져온다. //STEP02 class 이름으로 Class를 생성한다. Class roadClass = Class.forName(this.getProperty(key)); //STEP03 Object 생성 Object obj = roadClass.newInstance(); //STEP04 Action 으로 형변환 action = (Action)obj; }catch( Exception ex ){ LogCommand.getInstance("error",ex); } return action; } } ---------------------------------------------------------------------------------- 마지막으로 servlet.properties 프로퍼티 파일을 보자 ---------------------------- servlet.properties ------------------------- user.LoginCheck=sdwa.src.user.action.LoginAction user.Logout=sdwa.src.user.action.LogoutAction Meal.SchoolInfo=sdwa.src.Meal.action.MealInfoAction --------------------------------------------------------------------------------- [서블릿구분자].[커멘트]=로드할 클래스명 출처 : http://cafe.naver.com/junes81.cafe
Java/[Servlet/JSP]