1、子控制器灵活配置、结果跳转灵活配置
1.1 将Action的信息配置到xml(反射实例化)
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
init();
String url = req.getRequestURI();
url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
ActionModel actionModel = configModel.pop(url);
if(actionModel==null) {
throw new RuntimeException("你没有配置对应的子控制器Action~~~");
}
try {
//原来子控制器的来源是map集合,这样的话子控制器会被写死在map容器中,代码不够灵活
//想在将子控制器以配置的方式存放在config.xml中,未来可以通过改变config.xmlde中的类容
//随意给中央控制器添加子控制器
Action action = (Action)Class.forName(actionModel.getType()).newInstance();
// 调用模型驱动接口,获取所要操作的实体类,然后将jsp传递过来的参数,封装到实体类中
if(action instanceof ModelDriven) {
ModelDriven modelDriven = (ModelDriven)action;
Object model = modelDriven.getModel();
BeanUtils.populate(model, req.getParameterMap());
}
// 每个字控制器,都需要对结果进行对应的处理,页就是说要么转发,要么重定向,代码重复量较大
// 针对这一现象,将其交给配置文件来处理
// 调用了增强版的子控制器来处理业务逻辑
String code = action.execute(req, resp);
ForwardMode forwardMode = actionModel.pop(code);
if(forwardMode==null) {
throw new RuntimeException("你没有配置对应的子控制器Action的处理方式Forward~~~");
}
String jspPath = forwardMode.getPath();
if(forwardMode.isRedirect()) {
resp.sendRedirect(jspPath);
}else {
req.getRequestDispatcher(jspPath).forward(req, resp);
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.2通过结果码控制页面的跳转
<?xml version="1.0" encoding="UTF-8"?>
<config>
<action path="/addCal" type="com.zrh.web.AddCalAction">
<forward name="calRes" path="/calRes.jsp" redirect="false" />
</action>
<action path="/delCal" type="com.zrh.web.DelCalAction">
<forward name="calRes" path="/calRes.jsp" redirect="false" />
</action>
<action path="/cCal" type="com.zrh.web.CCalAction">
<forward name="calRes" path="/calRes.jsp" redirect="false" />
</action>
<action path="/chuCal" type="com.zrh.web.ChuCalAction">
<forward name="calRes" path="/calRes.jsp" redirect="false" />
</action>
</config>
2、将处理实体类的一组操作放到增强的子控制器中
增强版的子控制器:
作用:凡是这个实体类的操作,对应方法都可以写在当前增强版的子控制器来完成
/**
* 之前的Action只能处理一个实体类的一个业务
*
* ~~~~现在这个增强版的子控制器
* 凡是这个实体类的操作,对应方法都可以写在当前增强版的子控制器来完成
* @author zrh
*
*/
public class ActionSupport implements Action {
@Override
public 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 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;
}
}
对加减乘除的改造:
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()));
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()));
return "calRes";
}
public String c(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()));
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()));
return "calRes";
}
@Override
public Cal getModel() {
return cal;
}
}
对config的改造
<config>
<action path="/cal" type="com.zrh.web.CalAction">
<forward name="calRes" path="/calRes.jsp" redirect="false" />
</action>
</config>
3、模型驱动接口及框架配置文件重命名
3.1利用ModelDriver接口对Java对象进行赋值(反射读写方法)
BeanUtils.populate(calBean, parameterMap);
ModelDriver接口返回的对象不能为空
先写一个模型驱动接口
/**
* 作用
* 模型驱动接口
* 使用来处理jsp'页面传递过来的参数,将所有的参数自动封装到实体类T中
*
* @author zrh
*
* @param <T>
*/
public interface ModelDriven<T> {
T getModel();
}
它该怎么封装呢有以下代码决定:
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()));
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()));
return "calRes";
}
public String c(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()));
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()));
return "calRes";
}
@Override
public Cal getModel() {
return cal;
}
}
在DispatcherServlet.java写
Action action = (Action)Class.forName(actionModel.getType()).newInstance();
// 调用模型驱动接口,获取所要操作的实体类,然后将jsp传递过来的参数,封装到实体类中
if(action instanceof ModelDriven) {
ModelDriven modelDriven = (ModelDriven)action;
Object model = modelDriven.getModel();
BeanUtils.populate(model, req.getParameterMap());
}
3.2使得框架的配置文件可变
0.1、重命名一个conf配置文件
我想让我的框架读这里面mvc.xml文件,好处为了避免重复读同一个文件
这次之前同样是针对DispatcherServlet.java
代码如下:
try {
// 将原有的读取框架的默认配置文件转变成读取可配置路径的配置文件
String xmlPath = this.getInitParameter("xmlPath");//把路径配到servlet里去
if(xmlPath == null ||"".equals(xmlPath))
configModel = ConfigModelFactory.build();
else
configModel = ConfigModelFactory.build(xmlPath);
} catch (Exception e) {
e.printStackTrace();
}
}
好了之后那么xmlPath该去web.xml里去配置
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>com.zrh.framework.DispatcherServlet</servlet-class>
<init-param>
<param-name>xmlPath</param-name>
<param-value>/mvc.xml</param-value>
</init-param>
</servlet>