您的位置:首页 > 其它

自定义MVC《二》

2019-06-07 22:22 183 查看

MVC通用

今天我们学习MVC模式就是对减少重复代码,节约开发时间,通过今天的学习,发现在前篇博客上海市有许多的重复代码,对此今天对它进行一些改进。

首先写一个主控制器:DispatcherServlet

package com.wangshaoyang.framework;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;

/**
* 主控制器
*
*/
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 5061973068949172309L;
private ConfigModel configModel = null;

public void init() {
try {
//将原有的读取框架的默认配置文件 转变成 可配置路径的配置文件
String xmlPath = this.getInitParameter("xmlPath");
if(xmlPath == null || "".equals(xmlPath)) {
configModel = ConfigModelFactory.build();
}else {
configModel = ConfigModelFactory.build(xmlPath);
}
//主控制器有哪些子控制器由configModel决定
configModel = ConfigModelFactory.build();
} 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 url = req.getRequestURI();//路径
url = url.substring(url.lastIndexOf("/"),url.lastIndexOf("."));

//通过 path 拿到  type
ActionModel actionModel = configModel.pop(url);

//如果没有配置子控制器
if(actionModel == null) {
throw new RuntimeException("没有配置对应的子控制器 Action");
}

/**
* 将Action的信息配置到xml(反射实例化)
*
* 原来子控制器的来源是map集合,如此,子控制器就被写死在map容器中,代码不灵活
* 现将子控制器以配置的方式存在config.xml中,即通过改变config.xml中的内容给中央控制器添加子控制器
*/

try {
Action action = (Action)Class.forName(actionModel.getType()).newInstance();//反射实例化
/**
* 调用模型驱动接口,获取所要操作的实体类,然后将jsp传递过来的参数封装到实体类中
*/
if(action instanceof ModelDriven) {
ModelDriven modelDriven = (ModelDriven) action;//CalAction向上提升为ModelDriven
Object model = modelDriven.getModel();//要操作的实体类

/*//String-属性  String[]-属性值
Map<String, String[]> map = req.getParameterMap();
for (Map.Entry<String, String[]> entry : map.entrySet()) {//遍历
//可以获取到类对应的属性、属性值
}*/  //底层源码

//设置属性、属性值  将所有的参数自动封装到实体类T中
BeanUtils.populate(model, req.getParameterMap());
}
/**
* 通过结果码控制页面跳转
*
* 每个子控制器都要对结果进行处理(重定向/转发),代码重复量较大
* 针对这一现象,将其交给配置文件处理。
*/
//调用增强版的子控制器处理业务逻辑
String code = action.execut(req, resp); //要跳转的路径
ForwardModel forwardModel = actionModel.pop(code);

//如果没有配置子控制器
if(forwardModel == null) {
throw new RuntimeException("没有配置对应的子控制器Action的处理方式forwardModel");
}

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();
}
}
}

相对于之前的子控制器已经不适应了,所以写一个加强版子控制器:ActionSupport

package com.wangshaoyang.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;

/**
* 之前的Action只能处理一个业务,现在增强版的子控制器
* 凡是操作这个实体类的操作对应方法都可以写在当前增强版的子控制器来完成
*
*
*/
public class ActionSupport implements Action{

@Override
public final String execut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub

String methodName=req.getParameter("methodName");
String code=null;
try {
Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
method.setAccessible(true);

try {
//具体调用了你自己所写的子控制器的方法来处理浏览器的请求
code=(String)method.invoke(this,req,resp);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return code;
}

}

XML建模 ActionModel :

package com.wangshaoyang.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 void push(ForwardModel forwardModel) {
fMap.put(forwardModel.getName(), forwardModel);
}
public ForwardModel pop(String name) {
return fMap.get(name);
}
}

XML解析 ConfigModel

package com.wangshaoyang.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);
}
}

进而紧要写一个类ForwardModel

package com.wangshaoyang.framework;

public class ForwardModel {
//	<forward name="success" path="/index.jsp" redirect="true" />
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.wangshaoyang.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 ConfigM
4000
odelFactory {
public static ConfigModel build() throws DocumentException {
return build("config.xml");
}

public  static ConfigModel build(String xmlPath) throws DocumentException {
ConfigModel configModel =new ConfigModel();
InputStream in = ConfigModelFactory.class.getResourceAsStream(xmlPath);
SAXReader saxreder=new SAXReader();
Document doc = saxreder.read(in);
ActionModel actionModel=null;
ForwardModel forwardModel=null;
List<Element> actionEles = doc.selectNodes("/config/action");
for (Element actionEle : actionEles) {
actionModel =new ActionModel();
//接下来需要往actionModel填充内容
actionModel.setPath(actionEle.attributeValue("path"));
actionModel.setType(actionEle.attributeValue("type"));
List<Element> forwardEles = actionEle.selectNodes("forward");
for (Element forwardEle : forwardEles) {
forwardModel =new ForwardModel();
forwardModel.setName(forwardEle.attributeValue("name"));
forwardModel.setPath(forwardEle.attributeValue("path"));
forwardModel.setRedirect(!"false".equals(forwardEle.attributeValue("redirect")));
actionModel.push(forwardModel);
}
configModel.push(actionModel);
}
return configModel;
}

public static void main(String[] args) throws DocumentException {
ConfigModel configModel =ConfigModelFactory.build();
/*ActionModel actionModel = configModel.pop("/loginAction");
System.out.println(actionModel.getType());

ForwardModel forwardModel = actionModel.pop("b");
System.out.println(forwardModel.getPath()+"   "+ forwardModel.isRedirect());*/
}
}

Action

package com.wangshaoyang.framework;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* 子控制器
* 专门用来处理业务逻辑
* @author 86182
*
*/
public interface Action {
String execut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
}

模型驱动 ModelDriven

package com.wangshaoyang.framework;

/**
* 模型驱动接口
* 是用来处理jsp页面传递过来的参数
* 将所有的参数自动封装到实体类T中
* @author Lzdwzqad
*
* @param <T>
*/
public interface ModelDriven<T> {
T getModel();
}

建立一个config.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>
注意:如果没有配置的话就会出现 你还没有配置对应子控制器的Action的处理方式,所以一定要记得。

最后我们写一个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=UTF-8">
<title>Insert title here</title>
</head>
<body>
<script type="text/javascript">
function doSub(value){
if(value==1){
calForm.action="${pageContext.request.contextPath}/addCal.action";
}
else if(value==2){
calForm.action="${pageContext.request.contextPath}/delCal.action";
}
else if(value==3){
calForm.action="${pageContext.request.contextPath}/chenCal.action";
}
else{
calForm.action="${pageContext.request.contextPath}/chuCal.action";
}
calForm.submit();
}

</script>

</head>
<body>
<form id="claForm" name="calForm" action="">
num1:<input type="text" name="num1" /><br/>
num2:<input type="text" name="num2" /><br/>
<input type="button" onclick="doSub(1)" value="+" />
<input type="button" onclick="doSub(2)" value="-" />
<input type="button" onclick="doSub(3)" value="x" />
<input type="button" onclick="doSub(4)" value="/" />
</form>
</body>
</html>

运行可得

点击除法就得到了我们相应答案

今天就更新到这里
喜欢的可以关注我
不定时更新

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: