1.通过XML对自定义mvc框架进行增强
今天我们要对上一篇的MVC进行加强,主要解决重复代码和代码不能灵活运用的问题
案例
1.导入之前的XML建模和解析
ActionModel
package com.aixincheng.framework;
import java.util.HashMap;
import java.util.Map;
public class ActionModel {
// <action path="/registerAction" type="test.action.RegisterAction">
private String path;
private String type;
private Map<String, ForwardModel> fMap = new HashMap<>();
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public ForwardModel pop(String name) {
return fMap.get(name);
}
public void push(ForwardModel forwardModel) {
fMap.put(forwardModel.getName(), forwardModel);
}
}
ConfigModel
package com.aixincheng.framework;
import java.util.HashMap;
import java.util.Map;
public class ConfigModel {
private Map<String, ActionModel> acMap = new HashMap<>();
public void push(ActionModel actionModel) {
acMap.put(actionModel.getPath(), actionModel);
}
public ActionModel pop(String path) {
return acMap.get(path);
}
}
DispathcherServlet主控制器
/**
* 主控制器
* @author yinyi
*
*/
//通过init()方法获取对应的配置文件
public class DispathcherServlet extends HttpServlet {
private static final long serialVersionUID = 1718695479595952099L;
// private Map<String, Action> actionMap = new HashMap<>();
private ConfigModel configModel = null;
public void init() {
// actionMap.put("/addCal", new CalAction());
// actionMap.put("/delCal", new CalAction());
// actionMap.put("/xCal", new CalAction());
// actionMap.put("/cCal", new CalAction());
try {
//将原有的读取框架的默认文件转变成可配置路径的配置文件
String xmlPath = this.getInitParameter("xmlPath");
if (xmlPath == null || "".equals(xmlPath))
configModel = ConfigModelFactory.bulid();
else
configModel = ConfigModelFactory.bulid(xmlPath);
} 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 {
init();
String uri = req.getRequestURI();//获取请求的全路径
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
//
// Action action = actionMap.get(uri);//AddCalAction
// System.out.println(uri);
ActionModel actionModel = configModel.pop(uri);
String type = actionModel.getType();
if (actionModel==null) {
throw new RuntimeException("你没有配置对应的子控制器Action!!!");
}
try {
// 原来自控制器的来源是map集合,这样的话子控制器会被写死在map容器中,代码不灵活
// 现在将子控制器以配置的方式放在config.xml中,
// 未来可以通过改变xml中的内容给中央控制器添加子控制器
Action action = (Action) Class.forName(type).newInstance();
//调用模型驱动接口,获取所要操作的实体类,将jsp传递过来的参数,封装到实体类中
if (action instanceof ModelDriven) {//是否实现
ModelDriven modelDriven = (ModelDriven) action;
Object model = modelDriven.getModel();//子控制器需要操作的实体类
//将所有的参数自动封装到实体类T中
BeanUtils.populate(model, req.getParameterMap());
}
//每个子控制器,都需要对结果进行相对应的处理,也就是说要么转发要么重定向。代码重复量较大
//针对这一现象,将其交给配置文件来处理
//调用了增强版的自控制器来处理业务逻辑
String code = action.execute(req, resp);
ForwardModel forwardModel = actionModel.pop(code);
if (forwardModel == null) {
throw new RuntimeException("你没有配置对应的子控制器Action的处理方式!!!");
}
String jspPath = forwardModel.getPath();
if (forwardModel.isRedirect()) {
resp.sendRedirect(req.getContextPath()+jspPath);//转发使用全路径名
}else {
req.getRequestDispatcher(jspPath).forward(req, resp);
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
// action.execute(req, resp);
}
}
ActionSupport子控制器———加强版
package com.aixincheng.framework;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ActionSupport implements Action {
@Override
public final String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String methodName = req.getParameter("methodName");//获取方法名
String code = null;
try {
//动态获取方法
Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
method.setAccessible(true);
//具体调用了自己所写的自控制器中的方法来处理请求
code = (String) method.invoke(this, req,resp);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return code;
}
}
ForwardModel
package com.aixincheng.framework;
public class ForwardModel {
// <forward name="a" path="/index.jsp" redirect="false" />
private String name;
private String path;
private boolean redirect;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public boolean isRedirect() {
return redirect;
}
public void setRedirect(boolean redirect) {
this.redirect = redirect;
}
}
ConfigModelFatory文件解析工厂
package com.aixincheng.framework;
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;
public class ConfigModelFactory {
public static ConfigModel bulid() throws Exception {
return bulid("config.xml");
}
public static ConfigModel bulid(String xmlPath) throws Exception {
ConfigModel configModel = new ConfigModel();
InputStream in = ConfigModelFactory.class.getResourceAsStream(xmlPath);
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(in);//获得xml格式字符串
ActionModel actionModel = null;//创建空的对象
ForwardModel forwardModel = null;
List<Element> aElements = doc.selectNodes("/config/action");
for (Element aelement : aElements) {
actionModel = new ActionModel();
///接下来需要往actionModel填充内容
actionModel.setPath(aelement.attributeValue("path"));
actionModel.setType(aelement.attributeValue("type"));
List<Element> fElements = aelement.selectNodes("forward");
for (Element felement : fElements) {
forwardModel = new ForwardModel();
///接下来需要往forwardModel填充内容
forwardModel.setName(felement.attributeValue("name"));
forwardModel.setPath(felement.attributeValue("path"));
forwardModel.setRedirect(!"false".equals(felement.attributeValue("redirect")));
actionModel.push(forwardModel);
}
configModel.push(actionModel);
}
return configModel;
}
public static void main(String[] args) throws Exception {
ConfigModel configModel = ConfigModelFactory.bulid();
ActionModel actionModel = configModel.pop("/registerAction");
ForwardModel forwardModel = actionModel.pop("success");
System.out.println(forwardModel.getPath()+" "+forwardModel.getName());
}
}
Action
package com.aixincheng.framework;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Action {
String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
}
ModelDriven
package com.aixincheng.framework;
/**
* 模型驱动接口
* 使用来处理jsp页面传递过来的参数
* 将所有的参数自动封装到实体类T中
* @author yinyi
*
* @param <T>
*/
public interface ModelDriven<T> {
T getModel();
}
config.XML
建立一个MVC.XML
<?xml version="1.0" encoding="UTF-8"?>
<config>
<action path="/addCal" type="com.yinyi.web.CalAction">
<forward name="calRes" path="/calRes.jsp" redirect="false" />
</action>
</config>
在web.xml中配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>T224_mvc</display-name>
<servlet>
<servlet-name>dispathcherServlet</servlet-name>
<servlet-class>com.yinyi.framework.DispathcherServlet</servlet-class>
<init-param>
<param-name>xmlPath</param-name>
<param-value>/mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispathcherServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
最后通过Cal.jsp运行
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript">
function dosub(val) {
if(val ==1){
myform.methodName.value="add";
}
else if(val ==2){
myform.methodName.value="del";
}
else if(val ==3){
myform.methodName.value="chengfa";
}
else{
myform.methodName.value="chufa";
}
myform.submit();
}
</script>
</head>
<body>
<form id="calForm" name="calForm" action="${pageContext.request.contextPath }/Cal.action">
num1:<input type="text" name="num1"><br>
num2:<input type="text" name="num2"><br>
<button οnclick="dosub(1)">+</button>
<button οnclick="dosub(2)">-</button>
<button οnclick="dosub(3)">X</button>
<button οnclick="dosub(4)">/</button>
</form>
</body>
</html>