自定义MVC框架编写

1.编写xml配置文件(mystruts.xml)保存action的信息

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mystruts[
<!ELEMENT mystruts (actions)>
<!ELEMENT actions (action*)>
<!ELEMENT action (result*)>
<!ATTLIST action
name CDATA #REQUIRED
class CDATA #REQUIRED>
<!ELEMENT result (#PCDATA)>
<!ATTLIST result
name CDATA #IMPLIED
redirect (true|false) "false">
]>
<mystruts>
<actions>
<action name="login" class="web.LoginAction">
<result name="success" redirect="true">welcome.jsp</result>
<result name="input">login.jsp</result>
</action>
</actions>
</mystruts>

2.编写Action接口,在Action接口中定义一个execute方法,并传入request,response两个参数,该方法返回一个字符串类型的返回值,表示执行完这个操作后跳转的页面

public interface Action {
/**
* 成功
*/
public String SUCCESS = "success";
/**
* 返回到输入页面
*/
public String INPUT = "input";
/**
* 失败
*/
public String FAILURE = "failure";
/**
* 登录 
*/
public String LOGIN = "login";
public String execute(HttpServletRequest request,HttpServletResponse response)
throws Exception;
}

3.保存Action信息,在配置文件中我们保存了详细的Action信息,这里使用一个JavaBean (ActionMapping)来保存Action的配置信息(类似于Hibernate中的实体类):

/**
 * 封装Action的映射信息
 * @author thinkpad
 *
 */
public class ActionMapping {
//action的请求名字
private String name;
//action的完整路径
private String className;
//action的返回值
private Map<String , Result> resultMap = new HashMap<String , Result>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public Map<String, Result> getResultMap() {
return resultMap;
}
public void setResultMap(Map<String, Result> resultMap) {
this.resultMap = resultMap;
}

}

4.有了保存信息的ActionMapping类之后,建立一个ActionMappingManager类(读取配置文件,保存信息)来管理ActionMapping,

public class ActionMappingManager {
private static Map<String, ActionMapping> actionMappingMap= new HashMap<String, ActionMapping>();
private static String confiLocation = "mystruts.xml";

//写在静态代码块内,使读取配置文件的操作只执行一次,提高性能
static{
if(actionMappingMap.size()==0){
InputStream is = ActionMappingManager.class.getResourceAsStream("/"+confiLocation);
//SAX是一种解析XML的技术
SAXReader sax = new SAXReader();
Document doc = null;
try {
doc = sax.read(is);
} catch (Exception e) {
e.printStackTrace();
}
List list = doc.selectNodes("mystruts/actions/action");
for (Object actionItem : list) {
if(actionItem instanceof DefaultElement){
Element actionElement = (Element) actionItem;
String name = actionElement.attribute("name").getValue();
String className = actionElement.attribute("class").getValue();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setName(name);
actionMapping.setClassName(className);
Iterator it = actionElement.elementIterator("result");
if(it!=null){
while(it.hasNext()){
Element result = (Element)it.next();
//取出是否重定向的属性
String isRedirect = result.attributeValue("isredirect");
//确保该属性为有效值
isRedirect = (null==isRedirect||"".equals(isRedirect))?"false":isRedirect;
Result rs = new Result(result.attribute("name").getValue(),result.getTextTrim(),Boolean.parseBoolean(isRedirect));
actionMapping.getResultMap().put(result.attributeValue("name"), rs);
}
}
actionMappingMap.put(actionMapping.getName(), actionMapping);
}
}
}

}
public static ActionMapping getActionMapping(String actionName){
return actionMappingMap.get(actionName);
}
}

5.通过ActionMappingManager的解析XML配置文件,已经得到Action的详细信息,下面通过java反射机制获取每一个Action实例

/**
 * 此方法通过反射来创建Action的实例并返回
 * @author thinkpad
 *
 */
public class ActionManager {
public static Action createAction(ActionMapping actionMapping){
String className = actionMapping.getClassName();
Class clazz = null;
try {
clazz = Thread.currentThread().getContextClassLoader().loadClass(
className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (clazz == null) {
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

if (clazz!=null)
try {
return (Action)clazz.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return null;

}
}

6编写控制器



public class ActionServlet extends HttpServlet {
private String getActionName(HttpServletRequest req){
String uri = req.getRequestURI();
String actionName = uri.substring(req.getContextPath().length());
actionName = actionName.substring(1,actionName.lastIndexOf("."));
return actionName;
}

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//1.解析请求的uri,从中取出需要的action名称
String actionName = getActionName(req);
//2.调用ActionMappingManager.xxx()方法获得这个名字对应的ActionMapping
ActionMapping actionMapping = ActionMappingManager.getActionMapping(actionName);
//3.调用ActionManager.xxx()创建Action实例
Action action = ActionManager.createAction(actionMapping);
//4.执行Action实例上的execute方法获得一个执行结果字符串[实际上是Result的name属性的值]
try {
String resultName = action.execute(req, resp);
//5.根据这个返回的字串得到Result对象
Result result = actionMapping.getResultMap().get(resultName);
//6.根据Result对象执行转发或者重定向
if (result.isRedirect())
resp.sendRedirect(result.getUrl());
else
req.getRequestDispatcher(result.getUrl()).forward(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值