上节课我们完成了自定义mvc模式这一次就是对上一次的补充与增强了最主要的还是优化代码
通过XML对自定义mvc框架进行增强
1.将Action的信息配置到xml(反射实例化)
解决了在框架代码中去改动,以便于完成客户需求,这个是不合理的
现在的init方法:
private ConfigModel configModel;
public void init() {
// actionMap.put("/addCal", new AddCalAtion());
// actionMap.put("/delCal", new DelCalAtion());
// actionMap.put("/chengCal", new ChengCalAtion());
// actionMap.put("/chuCal", new ChuCalAtion());
try {
configModel=ConfigModelFactory.newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
通过重写dopost方法来获取
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
init();
String url=req.getRequestURI();
// T226_mvc/addCal.action
// addCal
url=url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
ActionModel actionModel = configModel.get(url);
if(actionModel==null) {
throw new RuntimeException("你没有配置acticon标签,找不到对应的子控制器来处理浏览器发送的请求!!");
}
try {
// Action action=(Action) Class.forName("com.chenkang.web.AddCalAtion").newInstance();
// Action action=(Action) new AddCalAtion();
Action action=(Action) Class.forName(actionModel.getType()).newInstance();
action.execute(req, resp);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
//
}
xml文件的配置
<?xml version="1.0" encoding="UTF-8"?>
<!--
config标签:可以包含0~N个action标签
-->
<config>
<action path="/addCal" type="com.chenkang.web.AddCalAtion">
<forward name="res" path="/res.jsp" redirect="false" />
</action>
<action path="/delCal" type="com.chenkang.web.DelCalAtion">
<forward name="res" path="/res.jsp" redirect="false" />
</action>
</config>
2.通过结果码控制页面的跳转
req.getRequestDispatcher(“res.jsp”).forward(req, resp);
在跳界面的过程中这段代码始终都是重复的
接下来使用简单的调用节点的方式来实现
package com.chenkang.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.chenkang.entity.Cal;
import com.chenkang.framework.Action;
public class AddCalAtion implements Action{
@Override
public String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
String num1=req.getParameter("num1");
String num2=req.getParameter("num2");
Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
req.setAttribute("res", cal.getNum1()+cal.getNum2());
// req.getRequestDispatcher("res.jsp").forward(req, resp);
return "res";
}
}
实现:
ForwardModel forwardModel = actionModel.get(code);
if(forwardModel!=null) {
String jsppath = forwardModel.getPath();
if("false".equals(forwardModel.getRedirect())) {
// 做转发的处理
req.getRequestDispatcher(jsppath).forward(req, resp);
}else {
resp.sendRedirect(req.getContextPath()+jsppath);
}
记住在开发的时候重定向一定要写上绝对路径不然会找不到!!
3.将一组相关的操作放到一个Action中(反射调用方法)
我们需要新建一个ActionSupport
通过反射来一个方法来调用几个方法
package com.chenkang.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中
* @author Administrator
*
*/
public class ActionSupport implements Action {
@Override
public final String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
// add/del
String methodName=req.getParameter("methodName");
String code=null;
//class CalAction extends ActionSupport
// this在这里指的是CalAction它的一个实列
try {
Method m=this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
try {
code=(String) m.invoke(this, req,resp);
m.setAccessible(true);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return code;
}
}
CalAction类
package com.chenkang.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.chenkang.entity.Cal;
import com.chenkang.framework.ActionSupport;
public class CalAction extends ActionSupport {
public String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
String num1=req.getParameter("num1");
String num2=req.getParameter("num2");
Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
req.setAttribute("res", cal.getNum1()+cal.getNum2());
// req.getRequestDispatcher("res.jsp").forward(req, resp);
return "res";
}
public String del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
String num1=req.getParameter("num1");
String num2=req.getParameter("num2");
Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
req.setAttribute("res", cal.getNum1()-cal.getNum2());
// req.getRequestDispatcher("res.jsp").forward(req, resp);
return "res";
}
}
4 利用ModelDriver接口对Java对象进行赋值(反射读写属性)
String num1=req.getParameter("num1");
String num2=req.getParameter("num2");
如果jsp页面有多个参数需要拿值一个一个的拿比较麻将所以需要优化代码
先创建一个接口
package com.chenkang.framework;
/**
* 模型驱动接口
* 作用是将sjp所有传递过来的参数以及参数值都自动封装到浏览器所要操作的实体类中
* @author Administrator
*
*/
public interface ModelDriwern <T>{
T getModel();
}
然后实现这个接口
package com.chenkang.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.chenkang.entity.Cal;
import com.chenkang.framework.ActionSupport;
import com.chenkang.framework.ModelDriwern;
public class CalAction extends ActionSupport implements ModelDriwern<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");
// Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
req.setAttribute("res", cal.getNum1()+cal.getNum2());
// req.getRequestDispatcher("res.jsp").forward(req, resp);
return "res";
}
public String del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// String num1=req.getParameter("num1");
// String num2=req.getParameter("num2");
// Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
req.setAttribute("res", cal.getNum1()-cal.getNum2());
// req.getRequestDispatcher("res.jsp").forward(req, resp);
return "res";
}
@Override
public Cal getModel() {
// TODO Auto-generated method stub
return cal;
}
}
现在我们是要在他去CalAction类前面的时候要拿到值并且让他传过去
if(action instanceof ModelDriwern) {
ModelDriwern msDriwern=(ModelDriwern) action;
// 此时model的所有的属性值是null的
Object model = msDriwern.getModel();
try {
BeanUtils.populate(model, req.getParameterMap());
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 我们可以将req.getparameterMap()的值通过反射方式将其塞进model实列中
// Map<String, String[]> parameterMap = req.getParameterMap();
// Set<Entry<String, String[]>> entrySet = parameterMap.entrySet();
// Class<? extends Object> clz = model.getClass();
// for (Entry<String, String[]> entry : entrySet) {
// Field field = clz.getField(entry.getKey());
// field.setAccessible(true);
// field.set(model, entry.getValue());
// }
}
String code = action.execute(req, resp);
5.使得框架的配置文件可变
public void init() {
// actionMap.put("/addCal", new AddCalAtion());
// actionMap.put("/delCal", new DelCalAtion());
// actionMap.put("/chengCal", new ChengCalAtion());
// actionMap.put("/chuCal", new ChuCalAtion());
try {
String xmlPath=this.getInitParameter("xmlPath");
if(xmlPath==null || "".equals(xmlPath)) {
configModel=ConfigModelFactory.newInstance();
}else {
configModel=ConfigModelFactory.newInstance(xmlPath);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
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>mvc</display-name>
<servlet>
<servlet-name>dispatcherSerlvet</servlet-name>
<servlet-class>com.chenkang.framework.DispatcherSerlvet</servlet-class>
<init-param>
<param-name>xmlPath</param-name>
<param-value>/mvc3.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherSerlvet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
本文是对上一次自定义mvc模式的补充与增强,主要通过XML对自定义mvc框架进行优化。包括将Action信息配置到xml、用结果码控制页面跳转、把相关操作放一个Action中、利用接口对Java对象赋值,还使框架配置文件可变,以满足客户需求。
3425

被折叠的 条评论
为什么被折叠?



