自定义MVC框架

C(控制层) :Servlet,Action,Controller

M(模型层) :entity、dao

自定义MVC工作原理图

举例:

我们之前写增删改查的时候,每写一个方法就有一个对应的servlet用来调用方法及获取数据,再传值给jsp界面,但是这样会产生很多重复的代码,降低开发效率。

增加

删除

修改

查询

方法的调用取决于name ,我们可以把所有方法放在一个servlet 中,通过获取name 的值控制方法的调用 ,但是如果有新的方法增加,我们还是要不断改动原来的代码,使代码过于冗余。

因此我们可以利用反射,不改动原有逻辑,通过读取name读取实现需求

package com.ltf.mvc.Servlet;

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;

@WebServlet(“/index.do”)

public class indexServlet extends HttpServlet{

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

doPost(req, resp);

}

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

String a=req.getParameter(“a”);

// if(“add”.equals(a)) {

// add();

// }else if(“del”.equals(a)) {

// del();

// }else if(“upd”.equals(a)) {

// upd();

// }else if(“find”.equals(a)) {

// find();

//

// }

try {

Method m = this.getClass().getDeclaredMethod(a, HttpServletRequest.class,HttpServletResponse.class);

m.setAccessible(true);

m.invoke(this,req,resp);

} catch (Exception e) {

e.printStackTrace();

}

}

private void find(HttpServletRequest req, HttpServletResponse resp) {

// TODO Auto-generated method stub

System.out.println(“查询。。。。。。。。。”);

}

private void upd(HttpServletRequest req, HttpServletResponse resp) {

// TODO Auto-generated method stub

System.out.println(“修改。。。。。。。。。”);

}

private void del(HttpServletRequest req, HttpServletResponse resp) {

// TODO Auto-generated method stub

System.out.println(“删除。。。。。。。。。”);

}

private void add(HttpServletRequest req, HttpServletResponse resp) {

System.out.println(“增加。。。。。。。。。”);

}

private void ref(HttpServletRequest req, HttpServletResponse resp) {

System.out.println(“ref()。。。。。。。。。”);

}

}

利用放射,可以解决改动代码的缺陷

反射这段代码相当于中央控制器,并不直接处理浏览器请求

处理浏览器请求的是子控制器

那么 我们来思考一个问题:例如 book要进行增删改查,goods也要进行增删改查,那么在bookServlet和goodsServlet都要写反射,一旦需求多了起来,反射代码会变得重复繁多,但是它又是必须的,我们可以调整这段代码的位置,也就是说还需要进一步优化

Action这一接口的作用:针对add、del进行向上抽取的抽象方法

package com.ltf.framework;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

/**

  • 子控制器

  • 处理浏览器请求

  • 针对于add/ref/other进行向上抽取、抽象 abstract

*/

public interface Action {

public String execute(HttpServletRequest req, HttpServletResponse resp);

}

ActionSupport

实现Action 重写execte方法 ,通过反射获取对应方法(处理所有请求)

作用:当出现更多需求时,只需要继承 ActionSupport 类即可

package com.ltf.framework;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.lang.reflect.Method;

/**

  • 作用:能够处理浏览器的“所有”请求。包括add/ref/other…

*/

public class ActionSupport implements Action {

@Override

public String execute(HttpServletRequest req, HttpServletResponse resp) {

String methodName = req.getParameter(“methodName”);

String res = null;

try {

Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,

HttpServletResponse.class);

m.setAccessible(true);

res = (String) m.invoke(this, req, resp);

} catch (Exception e) {

e.printStackTrace();

}

return res;

}

}

DispatchServlet (中央控制器)

package com.ltf.framework;

import java.io.IOException;

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;

/**

  • 中央控制器

*/

@WebServlet(“*.action”)

public class DispathServlet extends HttpServlet {

// 在当前中央控制器中必然会有所有子控制器的集合

// 缺陷:如果有商品的增删改查–>意味着要改动代码–>代码的设计不够灵活

// 思考:在不改动代码的情况下,中央控制器也能找到对应的子控制器去处理浏览器请求

// 方案:把加子控制器的逻辑/动作,放到配置文件中完成(Dbutil改连接信息是放在代码中完成/现在是放在Properties文件中完成)

// 放在配置文件中完成的好处在于:代码更加灵活,修改相关信息不用动代码了

// private Map<String, ActionSupport> actions = new HashMap<>();

// configModel对象又通过建模的知识,把所有的配置信息给读取过来了

private ConfigModel configModel = null;

/**

  • 初始化所有的子控制器到当前的中央控制器中

*/

public void init() throws ServletException {

// 在集合中就有了一个子控制器

// actions.put(“/book”, new BookAction());

// actions.put(“/goods”, new GoodsAction());

// actions.put(“/order”, new OrderAction());

// …

try {

configModel = ConfigModelFactory.build();

} catch (Exception e) {

e.printStackTrace();

}

}

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

doPost(req, resp);

}

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

// 把子控制器与浏览器请求关联起来,"寻找"能够处理请求的子控制器

// http://localhost:8080/book.action?methodName=add–>BookAction.add();

/*

  • 思路 1.url–>/book 2.通过/book字符串在actions找到BookAction

  • 3.调用BookAction的add,想要调用add,实际上只要统一调用execute就可以了

*/

// 获取到浏览器的请求地址

String url = req.getRequestURI();

// url–>/book

url = url.substring(url.lastIndexOf(“/”), url.lastIndexOf(“.”));

// 通过/book字符串在actions找到BookAction

// ActionSupport actrion = actions.get(url);

// 在Map中寻找子控制器–>在配置文件中寻找子控制器

/*

  • 1.通过/book找到对应的ActionModel对象 2.通过ActionModel对象拿到类的全路径名com.zking.web.BookAction

  • 3.反射实例化对象

*/

ActionModel actionModel = configModel.pop(url);

// 类的全路径名

String type = actionModel.getType();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值