JavaWeb之搭建自己的MVC框架(二)
1. 前言
在 JavaWeb之搭建自己的MVC框架(一) 中我们完成了URL到JAVA后台方法的最基本跳转。但是实际操作中会发现有一个不方便的地方,现在在com.mvc.controller包中只有一个SayController类,如果我们想增加一个新的***Controller类,我们还需要到UrlMappingCollection中修改controllerList属性,这样是不合理的。
所以我们在这一节中要将这种耦合解除掉。我们要将UrlMappingCollection中controllerList提到xml配置文件中。
2. 准备Jar包
在这一节里我们需要用dom4j来解析xml文件。当然你也可以用其他工具来解析xml。
3. 实现
(1)首先我们要在web.xml中记录下我们将来需要扫描的controller列表:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <listener> <listener-class>com.mvc.listener.UrlMappingCollection</listener-class> </listener> <mymvc> <controllers> <controller>com.mvc.controller.SayController</controller>
</controllers> </mymvc> <servlet> <servlet-name>main</servlet-name> <servlet-class>com.mvc.servlet.ServletCenter</servlet-class> </servlet> <servlet-mapping> <servlet-name>main</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
其中,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 List<MVCBase> mvcBases; private final String MyMVC_NodeName = "mymvc"; private final String ControllerList_NodeName = "controllers"; private final String Control_NodeName = "controller"; //我们要扫描的Controller列表 @SuppressWarnings("unchecked") private List<String> getControllerList(ServletContextEvent sce) throws DocumentException{ List<String> ctrlList = new ArrayList<String>(); 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<Element> 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<MVCBase>(); try { List<String> 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<MVCBase> 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:
<mymvc> <controllers> <controller>com.mvc.controller.SayController</controller> <controller>com.mvc.controller.EatController</controller> </controllers> </mymvc>
最后,我们启动tomcat,在浏览器中输入:
http://127.0.0.1:8080/MyMVC/Eat/Apple
http://127.0.0.1:8080/MyMVC/Eat/Banana
http://127.0.0.1:8080/MyMVC/Say/Hello
http://127.0.0.1:8080/MyMVC/Say/Hi
看看是否能打印出我们想要的结果。