前言
这篇文章接上一篇文章,上一篇文章分享了简单的自定义了MVC。本片文章就来分享自定义MVC优化。
一、中央控制器动态加载储存子控制器
我们自定义MVC最后要将它导出成jar包,那如果我们要加的子控制器怎么办,都导成jar包。
这里我们就要用到之前分享的内容XML。
通过之前的建模我们可以知道,configModel对象会包含config.xml中的所有子控制器信息
同时为了解决中央控制器能够动态的加载保存子控制器的信息,我们只需要引入configModel对象即可
DispatcherServlet
package com.zhw.framework;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zhw.web.BookAction;
import com.zhw.xml.ActionModel;
import com.zhw.xml.ConfigModel;
import com.zhw.xml.ConfigModelFactory;
//@WebServlet("*.action")
public class DispatcherServlet extends HttpServlet{
// private Map<String,Action> actions = new HashMap<String,Action>();
private ConfigModel configModel;
/*
* 通过之前的建模我们可以知道,configModel对象会包含config.xml中的所有子控制器信息
* 同时为了解决中央控制器能够动态的加载保存子控制器的信息,我们只需要引入configModel对象即可
*/
@Override
public void init() throws ServletException {
// actions.put("/book",new BookAction());
// actions.put("/order",new BookAction());
try {
configModel = ConfigModelFactory.bulid();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//http://localhost:8080/mvc/book.action?methodName=list
String uri = req.getRequestURI();
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
// Action action = actions.get(uri);
// action.execute(req, resp);
//
ActionModel actionModel = configModel.pop(uri);
if(actionModel == null) {
throw new RuntimeException("action 配置错误 ");
}
//是action子控制器的全路径名
String type = actionModel.getType();
try {
//类类是反射的开始,通过子控制器的全路径名用newInstance方法得到子控制器。
Action action = (Action) Class.forName(type).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
}
config.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<action path="/book" type="com.zhw.web.BookAction">
<forward name="failed" path="/login.jsp" redirect="false" />
<forward name="success" path="/main.jsp" redirect="true" />
</action>
</config>
ConfigModel
package com.zhw.xml;
import java.util.HashMap;
import java.util.Map;
/**
* 对应标签
* @author zhw
*
*/
public class ConfigModel {
private Map<String,ActionModel> aMap = new HashMap<String,ActionModel>();
public void push(ActionModel actionModel) {
aMap.put(actionModel.getPath(), actionModel);
}
public ActionModel pop(String path) {
return aMap.get(path);
}
}
ConfigModelFactory
package com.zhw.xml;
import java.io.InputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* 23种设计模式之工厂模式
* sessionfactory
*
* @author zhw
*
*/
public class ConfigModelFactory {
public static ConfigModel bulid() throws Exception {
String defaultPath = "/config.xml";
InputStream in = ConfigModelFactory.class.getResourceAsStream(defaultPath);
SAXReader s = new SAXReader();
Document doc = s.read(in);
ConfigModel configModel = new ConfigModel();
List<Element> actionEles = doc.selectNodes("/config/action");
for (Element ele : actionEles) {
ActionModel actionModel = new ActionModel();
actionModel.setPath(ele.attributeValue("path"));
actionModel.setType(ele.attributeValue("type"));
//将forwardModel 赋值并添加到ActionModel
List<Element> forwardEles = ele.selectNodes("forward");
for (Element fele : forwardEles) {
ForwardModel forwardModel = new ForwardModel();
forwardModel.setName(fele.attributeValue("name"));
forwardModel.setPath(fele.attributeValue("path"));
forwardModel.setRedirect("true".equals(fele.attributeValue("redirect")));
actionM