Open berryberrybin opened 2 years ago
@WebListener
public class HandlerMappingListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
Map<String, Controller> map = new HashMap<String, Controller>();
// map.put()을 몇개 처리할지 알 수 없으며, 하나하나 넣기에는 귀찮음
//actionMapping.properties을 따로 생성하여 Map의 내용을 저장해서 관리
// ~.properties 파일 로딩
ResourceBundle rb = ResourceBundle.getBundle("kosta/mvc/listener/actionMapping");
// 폴더를 가져오므로 .을 사용하는 것이 아닌 /을 사용하며, 확장자는 생략함
for(String key : rb.keySet()) {
String value = rb.getString(key);
System.out.println(key + " = " + value);
}
}
}
<context-param>
<param-name>fileName</param-name>
<param-value>kosta/mvc/listener/actionMappin</param-value>
</context-param>
HandlerMappingListenr. java 수정 : fileName을 가져옴
public class HandlerMappingListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent e) {
Map<String, Controller> map = new HashMap<String, Controller>();
ServletContext application = e.getServletContext();
String fileName = application.getInitParameter("fileName");
ResourceBundle rb = ResourceBundle.getBundle(fileName);
for(String key : rb.keySet()) {
String value = rb.getString(key);
System.out.println(key + " = " + value);
}
}
}
----------------------------------------------------------------------------------------
### 문제점 및 해결 방법
- 현재 value는 String타입이므로 Controller 객체 타입으로 변경해야 함
- Class<?> 을 이용하여 객체타입으로 변경
- Class<?> 이란?
- 어떤 객체가 가지고 있는 필드, 생성자, 메소드의 정보를 동적으로 가져올수 있도록 도와주는 객체이다
- reflection 개념
- reflection 개념은 동적으로 즉 실행도중에 필요한 객체를 적절하게 생성하고 그 객체가 가지고 있는 생성자나 메소드를 동적으로 호출해줄수 있도록 하는 개념을 reflection이라고 하고, 자바에서 이 개념을 적용해 놓은 API가 Class<?> 이다.
### HandlerMappingList.java 최종
```java
@WebListener
public class HandlerMappingListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
Map<String, Controller> map = new HashMap<String, Controller>();
ServletContext application = sce.getServletContext();
String fileName = application.getInitParameter("fileName");
ResourceBundle rb = ResourceBundle.getBundle(fileName);
try {
for (String key : rb.keySet()) {
String value = rb.getString(key);
System.out.println(key + " = " + value);
// String의 문자열을 Controller의 객체로 생성해야 함
Class<?> className = Class.forName(value);
Controller controller = (Controller) className.getDeclaredConstructor().newInstance();
map.put(key, controller);
}
} catch (Exception e) {
e.printStackTrace();
}
//모든 영역에서 map을 사용할 수 있도록 application에 저장해야 함
application.setAttribute("map", map);
}
}
@WebServlet(urlPatterns = "/front", loadOnStartup = 1)
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
Map<String, Controller> map;
@Override
public void init() throws ServletException{
//init()에서 super.getServletContext() 을 통해 Application을 꺼낼 수 있음
// Object타입으로 나오므로 Map 형태로 downcasting되어야 함
map = (Map<String,Controller>)super.getServletContext().getAttribute("map");
}
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Controller controller = null;
String key = request.getParameter("key");
controller = map.get(key);
ModelAndView mv = controller.handleRequest(request, response);
if (mv.isRedirect()) {
response.sendRedirect(mv.getViewName());
} else {
request.getRequestDispatcher(mv.getViewName()).forward(request, response);
}
}
}
DispatcherServlet.java 개선 방법