您的位置:首页 > 编程语言 > Java开发

【SSH进阶之路】一步步重构MVC实现Struts框架——完善转向页面,大功告成(六)

2014-09-12 08:13 375 查看
目录:

【SSH进阶之路】Struts基本原理 + 实现简单登录(二)

【SSH进阶之路】一步步重构MVC实现Struts框架——从一个简单MVC开始(三)

【SSH进阶之路】一步步重构MVC实现Struts框架——封装业务逻辑和跳转路径(四)

【SSH进阶之路】一步步重构MVC实现Struts框架——彻底去掉逻辑判断(五)

【SSH进阶之路】一步步重构MVC实现Struts框架——完善转向页面,大功告成(六)

第四篇博客【SSH进阶之路】一步步重构MVC实现Struts框架——封装业务逻辑和跳转路径(四),我们解决了第一个问题:封装业务逻辑和跳转路径。第五篇博客【SSH进阶之路】一步步重构MVC实现Struts框架——彻底去掉Servlet中的逻辑判断(五),我们解决了第二个问题:彻底去掉Servlet中的逻辑判断。这篇我们解决最后一个问题,完善转向页面,显示和控制分离。

比如添加用户逻辑,成功不仅仅可以返回成功页面,失败也可以返回失败页面,代码如下:

AddUserAction

package com.liang.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.liang.manager.UserManager;

public class AddUserAction implements Action {

@Override
public String execute(HttpServletRequest req, HttpServletResponse resp)
throws Exception {
//获取参数
String username = req.getParameter("username");

//调用业务逻辑
UserManager userManager = new UserManager();
try{
//添加的业务逻辑
userManager.add(username);
}catch(Exception e){
//返回添加失败的界面
return "/add_error.jsp";//转向路径可以通过配置文件读取
}
//返回添加成功的界面
return "/add_success.jsp";//转向路径可以通过配置文件读取
}

}


从上篇博客中,我们知道,若想系统变的灵活,所有变化都配置到配置文件中,修改时,修改配置文件即可。因此,我们只需要在struts-config.xml中配置转向页面,不仅仅要有成功的转向页面,而且要有失败的转向页面。

我们修改一下struts-config.xml,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<action-config>
<action-mappings>
<!--根据不同的path路径,访问各自的Action  -->
<action path="/servlet/addUser" type="com.liang.action.AddUserAction">
<!-- 转向页面 -->
<forward name="success" path="/add_success.jsp"></forward>
<forward name="error" path="/add_error.jsp"></forward>
</action>

<action path="/servlet/delUser" type="com.liang.action.DelUserAction">
<forward name="success" path="/del_success.jsp"></forward>
<forward name="error" path="/del_error.jsp"></forward>
</action>

<action path="/servlet/modifyUser" type="com.liang.action.ModifyUserAction">
<forward name="success" path="/modify_success.jsp"></forward>
<forward name="error" path="/modify_error.jsp"></forward>
</action>

<action path="/servlet/queryUser" type="com.liang.action.QueryUserAction">
<forward name="success" path="/query_success.jsp">/</forward>
<forward name="error" path="/query_error.jsp"></forward>
</action>
</action-mappings>
</action-config>


我们修改了配置文件,使用dom4j读取配置,配置信息也需要放到一个map结构中,我们需要一个存储转向信息的map,因此,在ActionMapping中增加一个map。

ActionMapping

package com.liang.action;

import java.util.HashMap;
import java.util.Map;

public class ActionMapping {

private String path;
private String type;
//存储转向信息的map
Map forward = new HashMap();

public Map getForward() {
return forward;
}
public void setForward(Map forward) {
this.forward = forward;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}


读取配置需要发生相应的变化,但是我们有了上篇博客的例子,修改起来并不难。

ConfigInit

package com.liang.servlet;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.liang.action.*;

public class ConfigInit {

public static void init(String config) {
// 创建saxReader对象
SAXReader reader = new SAXReader();
File f = new File(config);
try {
// 通过read方法读取xml文件, 转换成Document对象
Document doc = reader.read(f);
// 得到配置文件的根结点
Element root = doc.getRootElement();
Element actionmappings = (Element) root.element("action-mappings");
// 解析action结点的所有参数
for (Iterator j = actionmappings.elementIterator("action"); j
.hasNext();) {
Element am = (Element) j.next();
ActionMapping actionMapping = new ActionMapping();

// 设置actionMapping的path和type
actionMapping.setPath(am.attributeValue("path"));
actionMapping.setType(am.attributeValue("type"));

Map forward = new HashMap();
// 解析forward结点的所有参数
for (Iterator k = am.elementIterator("forward"); k.hasNext();) {
Element fo = (Element) k.next();
forward.put((String) fo.attributeValue("name"), (String) fo
.attributeValue("path"));
}
// 设置forward
//如果是添加ActionMapping的存储如下;
/*
* actionMapping{ path="/servlet/addUser";
* type="com.liang.action.AddUserAction"
<span style="white-space:pre">				</span> *forwardMap{
* <span style="white-space:pre">	</span>key="success",value="/add_success.jsp"
* <span style="white-space:pre">	</span>key="error",value="/add_error.jsp" }
<span style="white-space:pre">				</span> *}
*/
actionMapping.setForward(forward);
/*
* 上面Mappings.actions的存储结构相当于将配置信息与映射一一对应
* map.put("/servlet/delUser", actionMapping);
* map.put("/servlet/addUser", actionMapping);
* map.put("/servlet/modifyUser", actionMapping);
* map.put("/servlet/queryUser", actionMapping);
*/
Mappings.actions.put((String) am.attributeValue("path"),
actionMapping);

}
} catch (Exception e) {
e.printStackTrace();
}
}
}


我们的TestServlet只需要增加一句话,如下所示:

TestServlet

package com.liang.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.liang.action.Action;
import com.liang.action.ActionMapping;
import com.liang.action.Mappings;

/**
* 使用servlet做相关的控制,转向多个(V)视图
* @author liang
*
*/
public class TestServlet extends HttpServlet {

//需要读取的文件名
protected static String config = "/WEB-INF/struts-config.xml";

public void init() throws ServletException {
//获得文件的路径
//initialize();
//根据web.xml中映射的目录获得文件在对应服务器中的真实路径
config = getServletContext().getRealPath("/")+ getInitParameter("config");
//解析struts-config.xml配置文件
ConfigInit.init(config);
}

//根据web.xml中映射的目录获得文件在对应服务器中的真实路径
//	private void initialize() {
//		try {
//			config = getServletContext().getRealPath("/")
//					+ getInitParameter("config");
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//	}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

//取得访问的URI
String reqeuestURI = request.getRequestURI();
//截取URI,获得路径
String path = reqeuestURI.substring(reqeuestURI.indexOf("/",1), reqeuestURI.indexOf("."));

Mappings mapings = new Mappings();
// 根据截取的URL请求,到Map中取得本次请求对应的Action类
ActionMapping actionMapping = (ActionMapping)mapings.actions.get(path);
//取得本请求对应的Action类的完整路径
String type = actionMapping.getType(); //com.liang.action.DelUserAction
//采用反射,动态实例化Action
try {
Action action = (Action)Class.forName(type).newInstance();
// 采用多态的机制,动态调用Action中的execute方法,返回转向路径
String result = action.execute(request, response);

//获得真实转向页面
String forward =(String)actionMapping.getForward().get(result);

//根据转向路径完成转向
request.getRequestDispatcher(forward).forward(request, response);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}

}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}

}


最后,我们看一下AddUserAction已经变得非常灵活了。

package com.liang.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.liang.manager.UserManager;

public class AddUserAction implements Action {

@Override
public String execute(HttpServletRequest req, HttpServletResponse resp)
throws Exception {
//获取参数
String username = req.getParameter("username");

//调用业务逻辑
UserManager userManager = new UserManager();
try{
//添加的业务逻辑
userManager.add(username);
}catch(Exception e){
//返回添加失败的界面
return "error";//和配置文件的配置一致
}
//返回添加成功的界面
return "success";//和配置文件的配置一致

}

}


大功告成,如果我们想换一个视图显示,我们只需要修改一个配置文件即可。我们用一张类图回顾一下我们重构和封装的历程。



到此刻为止,我们重构MVC实现Struts框架的所有步骤都做完了。不难发现,其实框架并不难,只是咋一看特别神秘,当我们一步步重构,不断封装,不断完善,Struts的雏形已经展现在我们的面前了。框架就是封装的高度化,抽象的高度化。

当然,它既然是一个雏形就绝对还有不完美的地方,比如,我们没有像Struts一样封装ActionForm,自动完成数据类型的转化,当然我们也可以从现在的基础上进一步完善,但是我们就不再往下做了,我们了解它的基本思想就好,况且我们后面还有更加艰巨的任务。

经过几篇博客的重构,我们实现了一个Struts的雏形,它可以让我们认识mvc和struts的异同点,以及struts的封装过程,对我们更加深入struts埋下了伏笔。下篇博客【SSH进阶之路】Struts详细实现流程,深入Struts(七),通过学习Struts的流程,进一步深入Struts。下篇博客见!

源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐