`
runfeel
  • 浏览: 902617 次
文章分类
社区版块
存档分类
最新评论

Struts学习第三步 之 自己写Struts框架

 
阅读更多

上次我们已经讲解分析了一下Struts原理,这次我们来自己构建一个简单的Struts框架,通过构建Struts框架来了解Struts是如何实现MVC的。

1、回顾Struts原理分析

不解释,接上篇博客,链接地址如下:

Struts学习第二步 之 Struts原理分析

http://blog.csdn.net/zs15932616453/article/details/8919349

2、解析XML文件

在上篇博客中,我们已经看出Struts做的就是将MVC中的每一层进行联系,而这些联系其实就是由XML配置文件进行关联的,所以这里我们自己写的Struts框架的第一步就是XML文件的解析。我们使用Struts框架默认的名称struts-config.xml,如下图所示。

计算机生成了可选文字: ‘公WebRoot卜仑META一INF‘臼WEB一INF今子丐!ib尸今struts一con6g.xmi卜罗欲忠新尸--才index.jsp才Iogin一rror.jsp团loginjuccessj、p。才Ioginjsp

解析xml文件,我们用dom4j解析。步骤如下

1)拷贝jar

计算机生成了可选文字: ‘公WebRoot卜公,META一INF‘公,WEB一INF团web·xml

2)编写代码,代码比较简单,不做多余解释

计算机生成了可选文字: ‘吟strutsTest沙src‘田control,囚Action.java。囚ArtionFo,ardjaVa。囚ActionMappingjava。囚Actionservlet.java。囚ActionFormjava。囚LoginActionForm.java。翻JREsystemLibrary〔dkl·7·0-17]卜氢JZ〔〔1.4Libraries卜翻ReferencedLibrarles‘它,WebRoot

package control;

import java.io.InputStream;

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

public class XmlConfigReader {
	
	private static XmlConfigReader instance = new XmlConfigReader();
	
	private XmlConfigReader() {		
	}
	
	public static XmlConfigReader getInstance() {
		return instance;
	}
	
	/**
	 * 将XML文档转换成为Document对象
	 * @param filepath XML文档对象路径
	 * @return 转换之后的Document对象
	 */
	public Document XML2Document(String filepath){
		
		SAXReader reader = new SAXReader();   
	    Document document = null;  
	    InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(filepath);
		
		try {
			document = reader.read(in);
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		
		return document;
	} 	
	
}


注意事项:在Java程序中使用dom4j解析xml文件需要注意路径问题,因为web项目发布之后,有些xml文件是不会发布到项目中的,所以就造成了一些文件无法解析在发布的时候找不到。另外web项目发布之后,一些xml文件的相对位置会发生变化,所以在项目中执行很对的xml文件解析也会出现文件未找到错误。具体内容,我们以后专门进行分析。

3、分析结构

上一步我们已经能够将xml文件进行解析,接下来我们分析一下XML文件中各个部分分别对应MVC中的那些部分和各个部分之间如何联系,这一点在上一篇中已经做了相依的解释,这里我们不做多余的解释。

MVC对应关系部分

计算机生成了可选文字: 一}23乙咨51111·吟struts丁est‘沙src币1.甲日口p国Adion.java国Act;onFo,ardjava国ActionMappingjava因Actionservlet.java国LoginAction.java国XmICon6gReader.java属靡尸-.国ActionForm.java,压{LoainActionForm.iavaprivatexlnlConfi仁}泛}/**叫不St己t1CXm二tUrni刀5tdl7〔匕q}OJ土IJ--LC乙一之谧昌。JRESystemLlbra甲-邑JZEE1.4Libraries酬ReferencedLibraries‘公WebRoot卜匕,META一INF卜公WEB一INF阵夏170_1刀乙文档转换成为D酬filepat.二:n转换之后p**/IJb工iCDOCUrnen七)2工J乙孟亡」2222份二彰}}彰〕奔〕类}共}效}共}份:::份}SAXReaderre乏DOCllmentd0CI几put"tream二6勺户O曰2ZC乙葬〕骂〕彩〕券〕秦}共}共二一一工try{O,1qJ3娜二澎〕澎〕券〕朱

各部分联系,参见博客,链接如下:

Struts学习第一步 之 HelloWord

http://blog.csdn.net/zs15932616453/article/details/8901418

4、基础类编写。

了解了各个部分对应关系之后,我们来看一下一些基础类的代码,这些代码与真正的Struts代码基本雷同,所以我们这里不做多余的解释代码如下:

Action.java代码如下:

package control;
 
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
 
importmodel.ActionForm;
 
publicclass Action {
 
    public ActionForward execute(
        ActionMapping mapping,
        ActionForm form,
        ServletRequest request,
        ServletResponse response)
        throws Exception {
 
        try {
            return execute(
                mapping,
                form,
                (HttpServletRequest) request,
                (HttpServletResponse)response);
 
        } catch (ClassCastException e) {
            return null;
        }
 
    }
   
    public ActionForward execute(
        ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response)
        throws Exception {
 
        return null;
 
    }
   
}
 

LoginAction.java代码如下:

package control;

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

import model.ActionForm;
import model.LoginActionForm;
 
public class LoginAction extends Action {

	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		String name=((LoginActionForm)form).getUserName();
		String forward="";
		//业务处理部分,我们仅作简单的判断是否是“hello”
		if("hello".equals(name)){
			forward="success";
		}else{
			forward="error";	
		}
		 
		return mapping.getActionForwards(forward);
	}
	
}

ActionForward.java代码如下:

package control;

public class ActionForward {

	private String name;
	private String path;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	
}

ActiionMapping.java代码如下:

package control;

import java.util.HashMap;

public class ActionMapping {
	
	private String path;
	private String type;
	private String name;
	private String scope;

	private HashMap<String,ActionForward> actionForwardMap=new HashMap<String,ActionForward>(); 

	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public String getScope() {
		return scope;
	}
	
	public void setScope(String scope) {
		this.scope = scope;
	}

	public ActionForward getActionForwards(String ActionForwardName) {		
		ActionForward actionforward=actionForwardMap.get(ActionForwardName);
		return actionforward;
	}

	public void addActionForward(ActionForward actionForward) {
		actionForwardMap.put(actionForward.getName(), actionForward);
	}	

}

ActionForm.java代码如下:

package model;
 
public abstract class ActionForm {
 
}

LoginActionForm.java代码如下:

package model;

public class LoginActionForm extends ActionForm {

	private String userName;
	
	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}
}

5、初始化

了解一些基础类之后,我们接下来重点将一些Strtus框架的核心类ActionServlet。首先我们分析Struts初始化工作,Struts初始化执行工作大致分为几个部分,我们这里只讲我们自己写的Struts都执行哪些工作,真正的Struts框架初始化是比较复杂的,我们等到以后再具体分析这些。

ActionServlet中的init()方法中,我们主要将配置文件中的各个部分读取到Map中,代码如下:

package control;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;

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

import model.ActionForm;

import org.dom4j.Document;
import org.dom4j.Element;

 
public class ActionServlet extends HttpServlet {
	
	private String config;
	private HashMap<String,ActionMapping> actionMappingMap=new HashMap<String,ActionMapping>();
	private HashMap<String,String> actionFormMap=new HashMap<String,String>();
	
	@Override
	public void init(){	
		//初始化配置文件
		initConfig();
	}	

	/**
	 * 将struts-config.xml文件中的各个部分初始化到Map中
	 * 
	 */
	private void initConfig(){	
		
		//获取struts-config.xml文件位置,这里我们不错处理,取默认即可
		config=getServletConfig().getInitParameter("config");
		 
		String filePath="../.."+config;		
		//读取XML文件,存储到document中
		Document doc=XmlConfigReader.getInstance().XML2Document(filePath); 		
		//读取配置信息到列表中,
		List<?> actionFormList=doc.selectNodes("struts-config/form-beans/form-bean");
		List<?> actionList=doc.selectNodes("struts-config/action-mappings/action"); 
		List<?> actionForwardList=doc.selectNodes("struts-config/action-mappings/action/forward");
		
		//遍历ActionForm列表,将配置信息中的ActionForm信息保存到Map中
		for(int i=0;i<actionFormList.size();i++){
			String actionFormName=((Element)actionFormList.get(i)).attributeValue("name");
			String actionFormType=((Element)actionFormList.get(i)).attributeValue("type");
			actionFormMap.put(actionFormName, actionFormType);
		}
		
		//遍历ActionMapping列表,将配置信息中的ActionMapping信息保存到Map中
		for(int i=0;i<actionList.size();i++){
			String actionName = ((Element)actionList.get(i)).attributeValue("name");
			String actionType = ((Element)actionList.get(i)).attributeValue("type");
			String actionPath = ((Element)actionList.get(i)).attributeValue("path");
			String actionScope = ((Element)actionList.get(i)).attributeValue("scope");
			ActionMapping actionMapping=new ActionMapping();

			//将配置信息加载到ActionMapping中			
			actionMapping.setName(actionName);
			actionMapping.setPath(actionPath);
			actionMapping.setType(actionType);
			actionMapping.setScope(actionScope);
			
			//遍历ActionForward配置部分,将该部分保存到Action中
			for(int j=0;j<actionForwardList.size();j++){				
				ActionForward actionForward=new ActionForward();
				//将配置的ActionForward信息添加到ActionForwar对象中
				String actionForwardName=((Element)actionForwardList.get(j)).attributeValue("name");
				String actionForwardPath=((Element)actionForwardList.get(j)).attributeValue("path");
				actionForward.setName(actionForwardName);
				actionForward.setPath(actionForwardPath);
				//将ActionFormWard对象添加到Action中
				actionMapping.addActionForward(actionForward);
			}
			//将Action对象添加到ActionMapping中
			actionMappingMap.put(actionMapping.getPath(),actionMapping);
				
		}		
	}	
	
}

6、处理客户端请求

ActionServlet初始化完成之后,我们就可以接受客户请求了,具体的执行代码如下:

package control;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;

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

import model.ActionForm;

import org.dom4j.Document;
import org.dom4j.Element;

 
public class ActionServlet extends HttpServlet {
	
	private String config;
	private HashMap<String,ActionMapping> actionMappingMap=new HashMap<String,ActionMapping>();
	private HashMap<String,String> actionFormMap=new HashMap<String,String>();
		
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		process(request, response);
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		process(request, response);
	}
	
	protected void process(HttpServletRequest request, HttpServletResponse response)
	 		throws IOException, ServletException {
		try {
			
			//取得URL
			String url=request.getRequestURL().toString();//http://192.168.24.170:8080/StrutsTest/login.do
			int start=url.lastIndexOf("/");
			int end=url.lastIndexOf(".");		
			String actionDo=url.substring(start,end);//  /login
			
			
			//获取指定的ActionMapping
			ActionMapping actionMapping=(ActionMapping)actionMappingMap.get(actionDo);
			//实例化ActionForm
			String actionFormType=actionFormMap.get(actionMapping.getName());
			ActionForm actionForm=(ActionForm)Class.forName(actionFormType).newInstance();
  
			//获取所有ActionForm中的方法名
			Method[] methods=actionForm.getClass().getDeclaredMethods();
			//遍历所有方法,将调用所有setter方法初始化
			for(int i=0;i<methods.length;i++){
				String methodName=methods[i].getName();
				if(methodName.contains("set")== true){					 				
					String attributeName=methodName.toLowerCase().charAt(3)+methodName.substring(4,methodName.length());
					actionForm.getClass().getMethod( methodName,new Class[]{String.class}).invoke(actionForm, new Object[]{request.getParameter(attributeName)});
				}
			}
			
			//实例化Action
			Action action = (Action)Class.forName(actionMapping.getType()).newInstance();
			//获取指定的ActionForward对象
			ActionForward actionForward=action.execute(actionMapping, actionForm, request, response);
			//转发到指定的页面
			request.getRequestDispatcher(actionForward.getPath()).forward(request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}	
}


整合ActionServlet的初始化和客户端请求之后,我们自己写的Struts框架基本就编写完毕了,当然,这只是一个非常简单的实例,很多地方我们都可以进行一些优化。这里主要为了演示,我们就不做过多的工作了。

本文我们主要演示了一个自己写的Struts框架,实例比较简单,下次我们分析一下本篇文章中的XML文件读取的路径相关问题。

分享到:
评论

相关推荐

    Struts框架的学习

    5、 在调用Biz 时 Entity实体对象将请求参数做了第三次封装处理 6、 Action副控制器获得请求信息再调用符合要求Biz去实现功能 7、 在此前Biz将Entity实体对象传入Dao 8、 Biz在通过业务需要调用Dao对数据进行相应的...

    Struts2接口文档

    Struts2的开发文档,学习Struts2时可以用来查阅API相关接口说明,便于分析框架原理

    struts2写的电子商城系统

    根据网上的资源实现了一个登陆时邮箱验证的功能,前台的页面比较明确,后台使用开源的第三方框架,有点乱。由于交作业比较着急,后台有些功能只有显示没有代码的具体实现,不过功能也足够交作业了。

    struts2框架搭建

    2、第二、三种方式主要增加的是动态调用(第三种方式推荐使用),struts.xml放在src下 3、第四种方式struts.xml放在src下某一目录的子目录下面,方便管理(推荐使用,可仔细学习,如果是放在WEB-INF下面,亦可参考此...

    STRUTS 2完全学习手册.pdf

    《Struts 2完全学习手册》全面讲述Struts 2开发框架的知识,包括Struts 2中配置文件的详细讲解、国际化与异常处理、数据类型的转换、数据的输入校验、Struts 2强大的标签库、Struts 2中文件的上传与下载、Struts 2对...

    北大青鸟ACCP6.0 第三学期 Y2 JAVA方向 struts2框架

    北大青鸟ACCP6.0 第三学期 Y2 JAVA方向 struts2框架 基础教学 上课示例

    开发自己一套struts框架

    此项目是为了更深入的理解MVC模式以及Struts的工作流程而开发的,运用了第三方commons组件, commons-digester来解析xml文件,把配置信息全部封装成类,然后运用MVC的思想去做相应的操作.

    精通Struts基于MVC的Java Web设计与开发 孙卫琴 光盘

    本书第1章到第3章为入门篇,通过两个Struts应用实例,引导读者把握设计、开发和部署Struts应用的整体流程,充分体会Struts框架在开放大型、可扩展的Web应用方面发挥的优势。第4章到第7章深入探讨了Struts框架的核心...

    Java Web整合开发实战:基于Struts 2+Hibernate+Spring(PDF)

    2篇 表现层框架Struts技术 4章 Struts快速上手 5章 解密Struts之核心文件 6章 Struts之数据校验与GJ化 7章 详解Struts之标签库 8章 Struts之拦截器使用技巧 9章 在Struts中应用Ajax技术 10章 Struts之项目实战...

    struts2总结第一章

    Struts2第一章 一、 介绍: a) Struts2是以web work优秀的设计思想为核心,吸收了struts1的部分优点,建立了一个基于webwork和struts1的MVC框架。 二、 优点: a) 结构清晰,使开发者只关注业务逻辑实现即可。 b) ...

    struts-2.0.14-lib Struts2开发包

    包含Struts2框架的核心类库,以及Struts2的第三方插件类库 struts2-core-2.0.14 xwork-2.0.7 ognl-2.6.11 commons-logging-1.0.4 freemarker-2.3.8 等等。

    (3.0版本)自己写的struts2+hibernate+spring实例

    也有时间开始写struts2的第三个框架版本了.主要是针对写了第二个版本之后的一些问题做一些回答才做得第三个版本.中间加一些小技巧之类的.不过我觉得还是值得一些关注的朋友期待的. 如果没有意外.这个版本应该是...

    精通 Struts:基于 MVC 的 JavaWeb 设计与开发(PDF)

    本书第1章到第3章为入门篇,通过两个Struts应用实例,引导读者把握设计、开发和部署Struts应用的整体流程,充分体会Struts框架在开放大型、可扩展的Web应用方面发挥的优势。第4章到第7章深入探讨了Struts框架的核心...

    spring,mybatis,struts2框架jar包

    java web框架应用的第三方jar包,包括spring,mybatis及struts2三大框架搭建需要用到的jar包,java连接oracle,mysql数据的jar包等等。

    Struts2教程

    上来说 Struts2 是全新的框架,那么就让我们来学习一下这个新的框架的使用方法。 如果大家使用过 Struts1.x ,应该对建立基于 Struts1.x 的 Web 程序的基本步骤非常清楚。 让我们先来回顾一下建立基于 Struts1.x 的 ...

    Struts2 in action中文版

    第3章 使用Struts 2动作 36 3.1 Struts 2动作简介 36 3.2 打包动作 39 3.2.1 Struts 2公文包示例应用程序 39 3.2.2 组织你的包 39 3.2.3 使用struts-default包中的组件 41 3.3 实现动作 43 3.3.1 可选的Action接口 ...

    struts&Spring&Hibernate框架小例子

    ssh框架整合小例子 struts&Spring&Hibernate第三阶段框架 struts1.0,spring2.0,hibernate3.0

    Struts2+Spring3+Hibernate框架技术精讲与整合案例 光盘勘误文件

    (1) 在光盘的“\第3篇 Struts2框架篇\第14章 代码\”路径下添加一个“书稿修改说明”文件夹中的“user.sql”的数据库脚本文件。 (2)将原光盘中第27章“网上订餐系统”源代码文件Restrant.zip,用“书稿修改说明”...

    精通struts:基于mvc的java web设计与开发part3

    本书第1章到第3章为入门篇,通过两个Struts应用实例,引导读者把握设计、开发和部署Struts应用的整体流程,充分体会 Struts框架在开放大型、可扩展的Web应用方面发挥的优势。第4章到第7章深入探讨了Struts框架的核心...

    开发者突击:Java Web主流框架整合开发(J2EE+Struts+Hibernate+Spring)(第2版) 带封面和目录、前言(3/6)

    开发者突击:Java Web主流框架整合开发(J2EE+Struts+Hibernate+Spring)(第2版)的完整版本,带封面和目录、前言,一共六个压缩文件,这是第3个。

Global site tag (gtag.js) - Google Analytics