增强版的mvc模式:
首先需要四个架包
在这里插入图片描述
然后要导入
ConfigModel
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);
}
}
ActionModel
public class ActionModel {
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);
}
}
ForwardModel
public class ForwardModel {
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文件解析工厂:
public class ConfigModelFatory {
public static ConfigModel build() throws Exception {
return build("config.xml");
}
public static ConfigModel build(String string) throws Exception {
ConfigModel configmodel=new ConfigModel();
InputStream in = ConfigModelFatory.class.getResourceAsStream("config.xml");
SAXReader reader=new SAXReader();
Document doc = reader.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"));
//拿到foward
List<Element> forword = actionEle.selectNodes("forward");
for (Element forwardEle : forword) {
forwardmodel=new ForwardModel();
//往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;
}
}
主控制器DispatcherServlet
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = -7094025920085803724L;//版本号
private ConfigModel configModel = null;//配置文件
//初始化方法
public void init() {
try {
//将原来的读取框架的默认配置文件转变成读取可配置路径的配置文件
String xmlPath = this.getInitParameter("xmlPath");
if(xmlPath == null || "".equals(xmlPath)) {
System.out.println(xmlPath+"qqq");
configModel = ConfigModelFatory.build();
}
else {
System.out.println(xmlPath+"as");
configModel = ConfigModelFatory.build(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 url = req.getRequestURI();//Mvc/xxx.action
url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
//根据路径获取action的模型
ActionModel actionModel = configModel.pop(url);
if(actionModel==null) {
throw new RuntimeException("你没有配置对应的子控制器Action!!!");
}
try {
//原来子控制器的来源是map集合,这样的话子控制器被写死再map容器中,代码不够灵活
//现在将子控制器配置方式存放再config.xml中,未来可以通过改变config.xml中的内容
//随意给中央控制器添加子控制器
Action action = (Action)Class.forName(actionModel.getType()).newInstance();
// 调用模型驱动接口,获取所需要操作的实体类,然后将jsp传递过来的参数,封装到实体类中
if(action instanceof ModelDriver) {
ModelDriver modelDriver=(ModelDriver)action;
Object model = modelDriver.getModel();
BeanUtils.populate(model, req.getParameterMap());
//这是上面方法实现的底层所有代码
// Map<String, String[]> map = req.getParameterMap();
// for (Entry<String, String[]> entry : map.entrySet()) {
// //可以获取到类对应的属性bname,获取到类所对应的属性值
// if(!entry.getKey().equals("methodName")) {
// Field field= model.getClass().getDeclaredField(entry.getKey());
// field.setAccessible(true);
// field.set(model, req.getParameter(entry.getKey()));
// }
// }
}
// 每个子控制器,都需要对结果进行对应的处理,要么重定向,要么转发,代码重复量较大
// 针对于这一现象,将其交给配置文件来处理
// 调用了增强版的子控制器来处理业务逻辑
String code = action.execute(req, resp);
ForwardModel forwardModel = actionModel.pop(code);
if(forwardModel ==null) {
throw new RuntimeException("你没有配置对应的子控制器Action的处理方式Forward!!!");
}
String jspPath = forwardModel.getPath();
if(forwardModel.isRedirect()) {
resp.sendRedirect(req.getContextPath()+jspPath);//拼接上路径,相当于绝对路径
}
else {
req.getRequestDispatcher(jspPath).forward(req, resp);
}
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
Action
public interface Action {
String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException ;
}
ModelDriver模型驱动接口:
/**
* 模型驱动接口
* 是用来处理jsp页面传递过来的参数,
* 将所有的参数自动封装到实体类T中
public interface ModelDriver<T> {
T getModel();
}
ActionSupport,处理所有业务的增强的子控制器
/**
* 之前的Action只能处理一个实体类的业务
* 现在这个是增加版的子控制器
* 凡是这个实体类的操作,对应方法都可以写在当前增强版的子控制器来完成
*/
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 | SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return code;
}
}
config.xml文件
< ?xml version="1.0" encoding="UTF-8"?>
<config>
<!-- <action path="/addCal" type="com.zking.web.AddCalAction">
<forward name="calRes" path="/calRes.jsp" redirect="false" />
</action>
<action path="/delCal" type="com.zking.web.delCalAction2">
<forward name="calRes" path="/calRes.jsp" redirect="false" />
</action>
<action path="/chenCal" type="com.zking.web.chenCalAction2">
<forward name="calRes" path="/calRes.jsp" redirect="false" />
</action>
<action path="/chuCal" type="com.zking.web.chuCalAction3">
<forward name="calRes" path="/calRes.jsp" redirect="false" />
</action> -->
<action path="/cal" type="com.zking.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>dispatcherServlet</servlet-name>
<servlet-class>com.zking.framework.DispatcherServlet</servlet-class>
<init-param>
<param-name>xmlPath</param-name>
<param-value>/mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
CalAction.java:
public class CalAction extends ActionSupport implements ModelDriven<Cal>{
private Cal cal = new Cal();
public String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// String num1 = req.getParameter("num1");
// String num2 = req.getParameter("num2");
req.setAttribute("res", Integer.valueOf(cal.getNum1()) +Integer.valueOf(cal.getNum2()));
// req.getRequestDispatcher("calRes.jsp").forward(req, resp);
return "calRes";
}
public String del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// String num1 = req.getParameter("num1");
// String num2 = req.getParameter("num2");
req.setAttribute("res", Integer.valueOf(cal.getNum1()) -Integer.valueOf(cal.getNum2()));
// req.getRequestDispatcher("calRes.jsp").forward(req, resp);
return "calRes";
}
public String chen(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// String num1 = req.getParameter("num1");
// String num2 = req.getParameter("num2");
req.setAttribute("res", Integer.valueOf(cal.getNum1()) *Integer.valueOf(cal.getNum2()));
// req.getRequestDispatcher("calRes.jsp").forward(req, resp);
return "calRes";
}
public String chu(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// String num1 = req.getParameter("num1");
// String num2 = req.getParameter("num2");
req.setAttribute("res", Integer.valueOf(cal.getNum1()) / Integer.valueOf(cal.getNum2()));
// req.getRequestDispatcher("calRes.jsp").forward(req, resp);
return "calRes";
}
@Override
public Cal getModel() {
// TODO Auto-generated method stub
return cal;
}
}
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=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function doSub(val){
if(val == 1){
//calForm.action = "${pageContext.request.contextPath }/addCal.action";
calForm.methodName.value = "add";
}else if(val == 2){
//calForm.action = "${pageContext.request.contextPath }/delCal.action";
calForm.methodName.value = "del";
}else if(val == 3){
//calForm.action = "${pageContext.request.contextPath }/chenCal.action";
calForm.methodName.value = "chen";
}else{
//calForm.action = "${pageContext.request.contextPath }/chuCal.action";
calForm.methodName.value = "chu";
}
calForm.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>
<input type="hidden" name="methodName">
<button onclick="doSub(1)" >+</button>
<button onclick="doSub(2)" >-</button>
<button onclick="doSub(3)" >*</button>
<button onclick="doSub(4)" >/</button>
</form>
</body>
</html>