一.优化MVC框架
1.1优化的思路:
相比我们上篇所讲的MVC框架,我们今天所要优化的代码是要更加的方便,我们只要在一个配置文件中改变我们要传递的对象和对象的路径就能够实现一个增删改查的操作。
1.2优化的代码区域
1.中央控制器的action容器变成一个配置文件(将集合➡配置文件,作用:配置文件的内容是可以随时修改的)
2.我们反射代码调用具体的业务逻辑代码。(能够减少转发,重定向的代码)
3.从jsp页面传递参数到servlet的代码优化。
注意:查看使用转发,增删改使用重定向(只会提交一次)。
1.3怎么使用代码实现优化MVC框架?
1.优化中央控制器的action容器
创建一个conf文件进行保存请求对象(所以我们用一个公共的用来存前台发送的地址请求。)
注意:只能创建Foload文件夹,在里面配置xml文件,用来存放将来要实例化的对象
创建模型对象作用:用于连接xml与中央控制器。将页面传递的内容放到configmodel中去,关于如何创建模型对象我在如何创建模型对象中已经详细说明了
注意:这里记得要导包;
更改的地方:
(1) 改变用configmodel保存
(2)通过工厂获取内容
(3) 改变用模型的方式获取url
(4)根据反射获取到实例的对象(根据URL)
但我们运行有path的,path值是对的,我们就能够成功!!!
具体实现代码:
DispatherServlet(中央控制器)类
package com.lya.farmework; import java.io.IOException; 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 org.apache.commons.beanutils.BeanUtils; import com.lya.model.ActionModel; import com.lya.model.ConfigModel; import com.lya.model.ConfigModelFactory; import com.lya.model.ForwardModel; /** * 李永安 */ @WebServlet("*.action") public class DispatherServlet extends HttpServlet { private static final long serialVersionUID = 1L; // 定以Map接收请求 // public Map<String, Action> actionMap = new HashMap<String, Action>(); // (1) 改变用configmodel保存 private ConfigModel configmodel; @Override public void init() throws ServletException {// 根据book找到BookAction // actionMap.put("/book", new BookAction()); // (2)通过工厂获取内容 try { configmodel = ConfigModelFactory.build(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.首先获取请求路径名. String url = request.getRequestURI(); // 2.根据路径名截取到对应的请求. url = url.substring(url.lastIndexOf("/"), url.lastIndexOf(".")); // 3.根据请求获取到对应的子控制器Action. // Action action = actionMap.get(url); // (3) 改变用模型的方式获取url // 通过/book找对应类的路径 ActionModel actionModel = configmodel.pop(url); // 这里要判空,防止我们大意没有改或写 if (actionModel == null) { throw new RuntimeException("action not config !!!!"); } else { String type = actionModel.getType();// 是通过/book获取到xml配置的路径 // (3)这里给据反射获取到实例的对象(根据URL) try { Action action = (Action) Class.forName(type).newInstance(); if(action instanceof ModelDriver) { ModelDriver md = (ModelDriver) action; Object bean = md.getModel(); Map<String, String[]> parameterMap = request.getParameterMap(); // BeanUtils---------设值到action中 BeanUtils.populate(bean, parameterMap); } //execute------list/tolist String execute = action.execute(request, response); ForwardModel ForwardModel = actionModel.pop(execute); if(ForwardModel!=null) { boolean redirect = ForwardModel.isRedirect(); String path = ForwardModel.getPath(); if(redirect) {//是重定向(丢失路径 + request.getContextPath()+ "/") response.sendRedirect(request.getContextPath()+ "/"+ path); }else { request.getRequestDispatcher(path).forward(request, response); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
Action(子控制器类)
package com.lya.farmework; import java.io.IOException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 子控制器 * * @author :JAVA-李永安 * @date :2023年6月29日 下午7:38:35 */ @WebServlet("/Action") public class Action extends HttpServlet { protected String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String methodName = req.getParameter("name"); String res = ""; try { Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class); m.setAccessible(true); res = (String) m.invoke(this, req, resp); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return res; } }
使用建模方法保存/book
模型configmodel类
package com.lya.model; import java.util.HashMap; import java.util.Map; 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); } public static void main(String[] args) throws Exception { ConfigModel configModel = ConfigModelFactory.build(); ActionModel actionModel = configModel.pop("/loginAction"); ForwardModel forwardModel = actionModel.pop("success"); System.out.println(forwardModel.getPath()); } }
模型工厂configmodelFactory类
package com.lya.model; 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; /* * * build/newinstance */ public class ConfigModelFactory { public static ConfigModel build(String xmlPath) throws Exception { ConfigModel configModel = new ConfigModel(); InputStream in = ConfigModelFactory.class.getResourceAsStream(xmlPath); SAXReader sr = new SAXReader(); Document doc = sr.read(in); // System.out.println(doc.asXML()); // configModel要有类容,就意味着actionmodel要有类容,然后放入到configmodel中去 List<Element> actionEles = doc.selectNodes("/config/action"); for (Element actionEle : actionEles) { // System.out.println(actionEle.asXML()); ActionModel actionModel = new ActionModel(); actionModel.setPath(actionEle.attributeValue("path")); actionModel.setType(actionEle.attributeValue("type")); // actionModel要有forwardModel,就意味着forwardmodel要有类容,然后放入到actionmodel中去 List<Element> forwardEles = actionEle.selectNodes("forward"); for (Element forwardEle : forwardEles) { System.out.println(forwardEle.asXML()); ForwardModel forwardModel = new ForwardModel(); forwardModel.setName(forwardEle.attributeValue("name")); forwardModel.setPath(forwardEle.attributeValue("path")); // 只有填写false才是转发,其它都为重定向 // forwardModel.setRedirect(false); forwardModel.setRedirect(!"false".equals(forwardEle.attributeValue("redirect"))); actionModel.push(forwardModel); } configModel.push(actionModel); } return configModel; } public static ConfigModel build() throws Exception { return build("/mvc.xml"); } public static void main(String[] args) throws Exception { ConfigModelFactory.build(); } }
xml文件
<?xml version="1.0" encoding="UTF-8"?> <config> <action path="/book" type="com.lya.web.BookAction"> <forward name="list" path="/index2.jsp" redirect="false" /> <forward name="tolist" path="/index2.jsp" redirect="true" /> </action> <action path="/goods" type="com.lya.web.BookAction"> <forward name="a" path="/index.jsp" redirect="false" /> <forward name="b" path="/welcome.jsp" redirect="true" /> </action> </config>
2.优化Bookaction中我们使用req,resp跳转到指定的页面!(一行代码解决)
这里仍要注意:查看使用转发,增删改使用重定向(只会提交一次)。(会丢失路径)
思路:这里我们想Bookaction是继承action的,所以我们改变action中的代码。同过判断查看与增删改的返回,来执行是转发还是重定向。注意解决路径丢失问题:(丢失路径 = request.getContextPath()+ "/")
代码:放置在中央控制器中(通过中央控制器去调对应的请求)
Action action = (Action) Class.forName(type).newInstance(); if(action instanceof ModelDriver) { ModelDriver md = (ModelDriver) action; Object bean = md.getModel(); Map<String, String[]> parameterMap = request.getParameterMap(); // BeanUtils---------设值到action中 BeanUtils.populate(bean, parameterMap); } //execute------list/tolist String execute = action.execute(request, response); ForwardModel ForwardModel = actionModel.pop(execute); if(ForwardModel!=null) { boolean redirect = ForwardModel.isRedirect(); String path = ForwardModel.getPath(); if(redirect) {//是重定向(丢失路径 + request.getContextPath()+ "/") response.sendRedirect(request.getContextPath()+ "/"+ path); }else { request.getRequestDispatcher(path).forward(request, response); } }
3.优化Bookaction中我们使用的new 1.对象 2.去get, 3.set 对象的属性,4.子控制器通用。
注意:实例对象在方法外面,通过构建ModelDrivel( 模型驱动接口(用来设置实体的值))用BookAction调用对应的方法getModel();在中央控制器中判断Action是否实现模型驱动接口,利用BeanUtils将值设置到Action中
Action action = (Action) Class.forName(type).newInstance(); if(action instanceof ModelDriver) { ModelDriver md = (ModelDriver) action; Object bean = md.getModel(); Map<String, String[]> parameterMap = request.getParameterMap(); // BeanUtils---------设值到action中 BeanUtils.populate(bean, parameterMap);
好了今天就分享到这!!!希望能够帮助到你的学习或工作!!!