目录
- 前言
- mvc之xml配置相应实现类
- mvc之xml提供返回路径
- mvc之一个超类自动调用方法(需传method)
- mvc之自动获取参数值
- mvc之使得导入的xml可选择
- 总结
前言
在之前已经完成了一个自定义mvc模式
此次就是对上一个的补充与增强。
这是上次的图解、
重点:通过XML对自定义mvc框架进行增强
mvc之xml配置相应实现类
我们之前是用map集合来进行存储一个类的信息。
这样是有弊端的:比如你想添加一个东西的时候,必定要对这个集合的内容进行修改。
但是我们可以用到xml文件来对应每一个类,只需要修改xml文件就可以动态调用到某个类
现在的init()方法:
public void init() {
config = configModelFactory.build();//调用默认的xml文件
}
可以用doPost获得
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
init();//使得map里有值
String requestURI = req.getRequestURI(); //获取请求的路径
System.out.println("截取前:"+requestURI);
String url = requestURI.substring(requestURI.lastIndexOf("/"), requestURI.lastIndexOf("."));//截取
System.out.println("截取后:"+url);
actionModel actionModel = config.pop(url);
if(actionModel==null) {
throw new RuntimeException("你没有配置相关的action");
}
action action = (action)Class.forName(actionModel.getType()).newInstance();//实列化xml中type里面的内容地址
String code = action.execute(req, resp);
}
xml文件的配置
<config>
<action path="/add" type="com.liwangwang.web.addAction">//这个的type就是一个类的路径
<forward name="calres" path="/calres.jsp" redirect="false" />
</action>
<action path="/del" type="com.liwangwang.web.delAction">
<forward name="calres" path="/calres.jsp" redirect="false" />
</action>
</config>
mvc之xml提供返回路径
在方法中有这样的req.getRequestDispatcher("calres.jsp").forward(req, resp);
可能需要多次运用,所以可以在从xml中获取到返回的路径
所以简单的调用节点.
public String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String num1 = req.getParameter("num1");
String num2 = req.getParameter("num2");
req.setAttribute("res", Integer.parseInt(num1)+Integer.parseInt(num2));
//req.getRequestDispatcher("calres.jsp").forward(req, resp);//我们要优化这行代码
return "calres";
}
实现
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
init();//使得map里有值
String requestURI = req.getRequestURI(); //获取请求的路径
System.out.println("截取前:"+requestURI);
String url = requestURI.substring(requestURI.lastIndexOf("/"), requestURI.lastIndexOf("."));//截取
System.out.println("截取后:"+url);
actionModel actionModel = config.pop(url);
if(actionModel==null) {
throw new RuntimeException("你没有配置相关的action");
}
try {
action action = (action)Class.forName(actionModel.getType()).newInstance();//实列化xml中type里面的内容地址
if(action instanceof ModelDirven) {
ModelDirven modeldirven = (ModelDirven)action;
Object model = modeldirven.getModel();
BeanUtils.populate(model, req.getParameterMap());
}
String code = action.execute(req, resp);//获取返回路径的名字
forwardModel forwardModel = actionModel.pop(code);
if(forwardModel==null) {
throw new RuntimeException("你没有配置对应子控制器action的处理方式");
}
String jsppath = forwardModel.getPath();//获取返回的路径
if(forwardModel.isRedirect()) {//判断是否要重定向
resp.sendRedirect(req.getContextPath()+jsppath);
}
else {//判断是否要转发
req.getRequestDispatcher(req.getContextPath()+jsppath).forward(req, resp);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
mvc之一个超类自动调用方法(需传method)
我们需要用一个方法来调用相对应的方法。
那么就需要用到了反射的机制。
将其全放入到calAction
public class CalAction extends actionSupper{
public String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String num1 = req.getParameter("num1");
String num2 = req.getParameter("num2");
req.setAttribute("res", Integer.parseInt(cal.getNum1())+Integer.parseInt(cal.getNum2()));
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.parseInt(cal.getNum1())-Integer.parseInt(cal.getNum2()));
return "calres";//返回的路径名字
}
}
一个超类,
public class actionSupper implements action {
public final String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String code = null;
try {
Method Method = this.getClass().getDeclaredMethod(req.getParameter("method"), HttpServletRequest.class,HttpServletResponse.class);
Method.setAccessible(true);
code = (String) Method.invoke(this, req,resp);//调用相对应的方法
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return code;
}
}
mvc之自动获取参数值
因为如果有多个参数的话就比较麻烦,所以需要优化
比如这行:
String num1 = req.getParameter("num1");
String num2 = req.getParameter("num2");
创建一个接口
public interface ModelDirven<T>{
T getModel();
}
然后继承
public class CalAction extends actionSupper implements ModelDirven<Cal> {
private Cal cal =new Cal();
public String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("res", Integer.parseInt(cal.getNum1())+Integer.parseInt(cal.getNum2()));
return "calres";
}
public String del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("res", Integer.parseInt(cal.getNum1())-Integer.parseInt(cal.getNum2()));
return "calres";
}
@Override
public Cal getModel() {
return cal;
}
}
mvc之使得导入的xml可选择
大家大概也看到了,在之前init()方法是这样的:
public void init() {
config = configModelFactory.build();
}
优化后
public void init() {
try {
//使得调用指定位置的xml文件
String xmlpath = this.getInitParameter("xmlpath");
if(xmlpath==null||"".equals(xmlpath)) {
config = configModelFactory.build();
}
else {
config = configModelFactory.build(xmlpath);
}
} catch (Exception e) {
e.printStackTrace();
}
}
需要在web.xml中配置
总结
在继承和实现的流程中,我还是有点没搞明白
Thanks♪(・ω・)ノ希望对大家有所帮助