mvc(二)

本文是对上一次自定义mvc模式的补充与增强,主要通过XML对自定义mvc框架进行优化。包括将Action信息配置到xml、用结果码控制页面跳转、把相关操作放一个Action中、利用接口对Java对象赋值,还使框架配置文件可变,以满足客户需求。

上节课我们完成了自定义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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值