自定义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>
运行可得
点击除法就得到了我们相应答案
今天就更新到这里
喜欢的可以关注我
不定时更新
相关文章推荐
- ASP.NET mvc 自定义验证和Filter过滤器传参
- Spring+SpringMVC+Freemarker(自定义标签)+Mybatis+Log4j快速整合
- .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(三)
- ASP.NET MVC---自定义HtmlHelper方法
- Attribute(二)——自定义特性+Asp.net MVC中的filter详解
- ASP.NET MVC中的统一化自定义异常处理
- MVC筛选自定义属性下拉表
- MVC学习十四:ASP.NET MVC如何实现自定义验证 AgeRangeAttribute
- MVC 自定义标签,给Html.ActionLink加上支持图片链接的功能
- ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)
- 自定义 mvc
- [转]自定义ASP.NET MVC JsonResult序列化结果
- web form中自定义HttpHandler仿mvc
- asp.net MVC中使用自定义HtmlForm控件动态生成表单
- springmvc+shiro自定义过滤器
- 通过自定义MVC的Controller的Json转换器解决日期序列化格式问题
- MVC 自定义AuthorizeAttribute实现权限管理
- ASP.NET MVC 模版切换 自定义模板路径
- ASP.NET MVC Part.3(自定义视图、强化模型)
- springmvc+shiro自定义过滤器的实现代码