1. 前言
在 中我们完成了URL到JAVA后台方法的最基本跳转。但是实际操作中会发现有一个不方便的地方,现在在com.mvc.controller包中只有一个SayController类,如果我们想增加一个新的***Controller类,我们还需要到UrlMappingCollection中修改controllerList属性,这样是不合理的。
所以我们在这一节中要将这种耦合解除掉。我们要将UrlMappingCollection中controllerList提到xml配置文件中。
2. 准备Jar包
在这一节里我们需要用dom4j来解析xml文件。当然你也可以用其他工具来解析xml。
3. 实现
(1)首先我们要在web.xml中记录下我们将来需要扫描的controller列表:
com.mvc.listener.UrlMappingCollection com.mvc.controller.SayController
main com.mvc.servlet.ServletCenter main /
其中,mymvc节点及其子节点就是我们在本节中新增的节点。
(2)然后我们调整UrlMappingCollection这个类,来读取web.xml中新增的mymvc节点内容。
package com.mvc.listener;import java.io.File;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import com.mvc.annotation.URLMapping;import com.mvc.base.MVCBase;public class UrlMappingCollection implements ServletContextListener { //被注解了URLMapper的类方法列表 private static ListmvcBases; private final String MyMVC_NodeName = "mymvc"; private final String ControllerList_NodeName = "controllers"; private final String Control_NodeName = "controller"; //我们要扫描的Controller列表 @SuppressWarnings("unchecked") private List getControllerList(ServletContextEvent sce) throws DocumentException{ List ctrlList = new ArrayList (); String webxml = sce.getServletContext().getRealPath("WEB-INF\\web.xml"); SAXReader saxReader = new SAXReader(); Document document = saxReader.read(new File(webxml)); Element rootElement = document.getRootElement(); List crtlNodeList = rootElement.element(MyMVC_NodeName). element(ControllerList_NodeName). elements(Control_NodeName); for (Element element : crtlNodeList) { ctrlList.add(element.getText()); } return ctrlList; } @Override public void contextDestroyed(ServletContextEvent sce) { // TODO Auto-generated method stub } @Override public void contextInitialized(ServletContextEvent sce) { mvcBases = new ArrayList (); try { List controllerList = getControllerList(sce); //循环所有需要扫描的Controller for (int i = 0; i < controllerList.size(); i++) { String controllerName = controllerList.get(i); String classURL = ""; String methodURL = ""; Class clazz = Class.forName(controllerName); //获取Controller类 if (clazz.isAnnotationPresent(URLMapping.class)) { //class被标记了URLMapping注解 classURL = ((URLMapping) clazz.getAnnotation(URLMapping.class)).url(); } //获取method列表 Method[] methods = clazz.getMethods(); for (Method method : methods) { if (method.isAnnotationPresent(URLMapping.class)) { //method被标记了URLMapping注解 methodURL = ((URLMapping) method.getAnnotation(URLMapping.class)).url(); MVCBase mvcBase = new MVCBase(); mvcBase.setUrl(classURL+methodURL); mvcBase.setController(controllerName); mvcBase.setMethod(method.getName()); mvcBases.add(mvcBase); } } } } catch (Exception e) { } } public static List getMvcBases() { return mvcBases; }}
我们增加了getControllerList函数来读取web.xml中的配置信息,然后把controller列表读取出来,其他地方稍作修改,读着可对比上一节中此处代码来观察做了哪些修改。
4. 测试效果:
首先,我们需要增加一个新的controller:
package com.mvc.controller;import com.mvc.annotation.URLMapping;@URLMapping(url="/Eat")public class EatController { @URLMapping(url="/Apple") public String EatApple(){ System.out.println("I'm eating apples"); return "Apple"; } @URLMapping(url="/Banana") public String EatBanana(){ System.out.println("I'm eating Banana"); return "Banana"; }}
然后,调整web.xml,增加com.mvc.controller.EatController:
com.mvc.controller.SayController com.mvc.controller.EatController
最后,我们启动tomcat,在浏览器中输入:
看看是否能打印出我们想要的结果。