01-Struts1.3 CRUD

 Struts作为MVC模式的典型实现,对ModelViewController都提供了对应的实现组件如图:

01-Struts1.3 CRUD_第1张图片

 

 

根据上图,总结Struts架构的工作原理

          Model部分:

                  StrutsModel部分由ActionForm JavaBean组成,其中,ActionForm用于封装用户请求参数,所有的用户请求参数由系统自动封装成ActionForm对象;该对象被ActionServlet转发给Action;然后Action根据ActionForm里的请求参数处理用户请求;JavaBean封装了底层的业务逻辑,包括数据库访问等等,在更复杂的应用中,JavaBean所代表的绝非一个简单的JavaBean,可能是EJB组件或者其他的业务逻辑组件;

         View部分:

                   StrutsView部分采用JSP实现,Struts提供了丰富的标签库,通过这些标签库可以最大限度地减少脚本的使用,这些自定义的标签库可以实现与Model的有效交互,并增加了显示功能;

                   整个应用由客户端请求驱动,当客户端请求被ActionServlet拦截时,ActionServlet根据请求决定是否需要调用Model处理用户请求,当用户请求处理完成后,其处理结果通过JSP呈现给用户;

        Controller部分

                   StrutsController由两部分组成,一是系统核心控制器,另一个是业务逻辑控制器

                   系统核心控制器对应上图的ActionServlet,该控制器由Struts框架提供,继承HttpServlet类,因此可以配置一个标准的Servlet。该控制器负责拦截所有HTTP请求,然后根据用户请求决定是否需要调用业务逻辑控制器,如果需要调用业务逻辑控制器,则将请求转发给Action处理,否则直接转向请求的JSP页面;

                   业务逻辑控制器负责处理用户请求,但其本身不具有处理功能,而是调用Model来完成处理,他对应上图的Action部分;

 

Struts1的流程:

01-Struts1.3 CRUD_第2张图片

 

Struts框架中所使用的组件: 

       1ActionServlet: 核心控制器(工作构建数据结构流程)  

       2Action.Class 包含事务逻辑  

       3ActionForm :ActionForm:封装用户请求的参数  (显示模块数据)  

       4ActionMapping: 用于封装请求处理流程的关系(帮助控制器将请求映射到操作)   

       5ActionForward :封装响应(用来指示操作转移的对象)  

       6ActionError: 用来存储和回收错误  

       7Struts标记库: 可以减轻开发显示层次的工作

 

Struts1的开发步骤:

         1、将Struts1下的包添加到lib

         2、在web.xml中配置核心控制器

         3、生成Struts的配置文件

         4、生成相应的actionmodel以及jsp

下面我们先来以Struts1.2+JDBC CRUD Demo为例

整体目录结构为:

 01-Struts1.3 CRUD_第3张图片

 

 一、web.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	version="2.5"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	<servlet>
		<servlet-name>actionServlet</servlet-name>
		<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
		<init-param>
			<param-name>config</param-name>
			<param-value>/WEB-INF/struts-config.xml</param-value>
		</init-param>
		<init-param>
			<param-name>debug</param-name>
			<param-value>3</param-value>
		</init-param>
		<init-param>
			<param-name>detail</param-name>
			<param-value>3</param-value>
		</init-param>
		<load-on-startup>0</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>actionServlet</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>

	<!-- 过滤器 -->
	<filter>
		<filter-name>encoding</filter-name>
		<filter-class>com.iflytek.filter.EncodingFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>encoding</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

说明:

web.xml中,所有.do结尾的请求都将有ActionServelt拦截,同时该Servlet还有加载Struts配置文件的责任ActionServelt默认加载web-inf路径下,或者改变了文件名,则应采用下方式配置:

 

<servlet>
<servlet-name>actionServelt</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/myConfig.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>actionServelt</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

这样指定了ActionServlet的配置文件myConfig.xml文件,最为init-param参数载入,载入时指定了参数名config,为固定值,configStruts固定的参数名,struts负责解析该参数,并加载该参数指定的配置文件。当有多个Struts配置文件时,只需添加init-param元素即可

<init-param>
	<param-name>config</param-name>
	<param-value>/WEB-INF/myConfig1.xml</param-value>
</init-param>
<init-param>
	<param-name>config/first</param-name>
	<param-value>/WEB-INF/myConfig2.xml</param-value>
</init-param>

 

二、ActionFrom

 

package com.iflytek.struts.form;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.upload.FormFile;

import com.iflytek.vo.User;

/**
 * @author xudongwang 2011-10-20
 * 
 */
@SuppressWarnings("serial")
public class UserForm extends ActionForm {
	private int cp = 1;
	private int ls = 5;

	// user.do?status=list
	private String status;

	// 这里使用对象接受,这里必须new出来,否则设不上值
	private User user = new User();

	// 当使用struts需要进行文件上传操作时,需要在Struts的ActionForm通过一个类型为FormFile的对象来接受文件的内容
	private FormFile img;

	/**
	 * Method validate
	 * 
	 * @param mapping
	 * @param request
	 * @return ActionErrors
	 */
	public ActionErrors validate(ActionMapping mapping,
			HttpServletRequest request) {
		// 注意需要判断状态,并不是所有情况都需要验证

		ActionErrors errors = new ActionErrors();
		if ("insert".equals(status)) {
			if (this.user.getAccount() == null
					|| this.user.getAccount().trim().equals("")) {
				errors.add("accout", new ActionMessage("account.null"));
			}
			if (this.img == null || this.img.getFileSize() == 0) {
				errors.add("img", new ActionMessage("img.null"));
			} else if (this.img.getFileSize() > 1024000) {
				errors.add("img", new ActionMessage("img.size"));
			} else {
				this.user.setPostDate(new Date());
				String fileName = new Date().getTime() + "";
				// 文件扩展名,从最后一个点开始截取字符串
				String kz = this.img.getFileName().substring(
						this.img.getFileName().lastIndexOf("."));
				this.user.setPhoto(fileName + kz);
			}
		}
		return errors;
	}

	/**
	 * Method reset
	 * 
	 * @param mapping
	 * @param request
	 */
	public void reset(ActionMapping mapping, HttpServletRequest request) {
	}

	public int getCp() {
		return cp;
	}

	public void setCp(int cp) {
		this.cp = cp;
	}

	public int getLs() {
		return ls;
	}

	public void setLs(int ls) {
		this.ls = ls;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public FormFile getImg() {
		return img;
	}

	public void setImg(FormFile img) {
		this.img = img;
	}
}

 说明:

配置ActionForm,需要包含ActionForm类才可以,Struts1要求ActionForm必须继承Struts的基类org.apache.struts.action.ActionFormActionForm的实现非常简单,该类只是一个普通的JavaBean,只要为每个属性提供对应的gettersetter方法即可。

ActionForm用于封装用户的请求参数,而请求参数是通过JSP页面的表单域传递过来的,所以要保证ActionForm的参数属性的gettersetter后缀名字与表单域的名字相同,而与属性名无关,可以随意取(即客户端请求中有个属性名为name,则在JavaBean中需要getNamesetName,而该JavaBean属性名可以任意,因为属性为private的,所以是通过构造器取的);

 

三、Action

 

package com.iflytek.struts.action;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

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

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import com.iflytek.factory.DAOFactory;
import com.iflytek.struts.form.UserForm;
import com.iflytek.vo.User;

/**
 * DispatchAction:分发Action用来解决在Action中需要判断当前操作状态的问题,
 * 使用分发Action后可以根据传递状态参数自动调用对应的方法
 * 
 * @author xudongwang 2011-10-20
 * 
 */
public class UserAction extends DispatchAction {

	/**
	 * Method list 方法名list根据页面传入的status=list
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return ActionForward
	 */
	public ActionForward list(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		UserForm userForm = (UserForm) form;
		List<User> users = null;
		int allRecorders = 0;
		try {
			users = DAOFactory.getUserDAOInstance().findAll(userForm.getCp(),
					userForm.getLs());
			allRecorders = DAOFactory.getUserDAOInstance().getAllCount();
		} catch (Exception e) {
			e.printStackTrace();
		}
		request.setAttribute("cp", userForm.getCp());
		request.setAttribute("ls", userForm.getLs());
		request.setAttribute("users", users);
		request.setAttribute("allRecorders", allRecorders);
		return mapping.findForward("userlist");
	}

	public ActionForward insert(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		UserForm userForm = (UserForm) form;
		boolean flag = false;
		try {
			flag = DAOFactory.getUserDAOInstance().doCreate(userForm.getUser());
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (flag) {
			// 开始保存文件
			// 使用字节流FileOutputStream来输出上传的文件
			try {
				FileOutputStream os = new FileOutputStream(new File(this
						.getServlet().getServletContext().getRealPath("/")
						+ "upload/" + userForm.getUser().getPhoto()));
				os.write(userForm.getImg().getFileData());
				os.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

	    request.setAttribute("message", flag ? "添加成功!" : "添加失败!");
		request.setAttribute("path", "user.do?status=list");
		//return mapping.findForward("forward");
		
		//这里不使用struts进行页面的跳转
		ActionForward forward = new ActionForward();
		forward.setPath("/forward.jsp");
		return forward;	}
}

 说明:

         Action负责管理与之关联的ActionForm,它不仅需要配置实现类,还需要配置Acitonpath属性,用于被用户请求。

         1Action需要继承Aciton,并且重写execute方法

         2、通过ActionForm,可使Action无须从HTTP请求中解析参数,而直接从ActionForm中取

         Action的实现:

                   Action从转发过来的ActionForm中解析请求参数,对应的ActionForm则由ActionServlet在接受到用户请求时,负责实例化

                   实际过程是,ActionServlet拦截到用户请求后,根据用户的请求,在配置文件中查找对应的ActionAction         name属性指定了用于封装请求参数的ActionForm,然后ActionServlet将创建默认的ActionForm实例,并调用对应的         setter方法完成ActionForm的初始化;

         在上面的过程中,ActionServlet采用反射机制来完成对象的创建以及初始化等过程;

 

四、struts-config.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd">
	<!-- 业务逻辑控制器,处理用户请求,但其本身不具有处理功能,而是调用Model来完成处理 -->
<struts-config>
	<!-- 以下配置是针对ActionForm,form-beans中包含多个form-bean -->
	<form-beans>
		<form-bean name="userForm" type="com.iflytek.struts.form.UserForm" />
	</form-beans>

	<!-- 公共异常的处理,开发中使用不多 -->
	<global-exceptions>
		<exception key="num" type="java.lang.NumberFormatException" path="excep"></exception>
	</global-exceptions>

	<!-- 公共的跳转路径 -->
	<global-forwards>
		<forward name="excep" path="error.jsp"></forward>
	</global-forwards>

<!--
		以下配置是针对于Action,
		action-mappings用于封装请求处理流程的关系(帮助控制器将请求映射到操作)可以包含多个Action
	-->
	<action-mappings>
		<action attribute="userForm" input="/error.jsp" name="userForm"
			parameter="status" path="/user" scope="request"
			type="com.iflytek.struts.action.UserAction" cancellable="true"  unknown="true">
			<forward name="userlist" path="/UserList.jsp"></forward>
			<forward name="forward" path="/forward.jsp"></forward>
		</action>
	</action-mappings>
	<!-- 资源文件 所在的路径,资源文件的后缀名必须为properties-->
	<message-resources parameter="com.iflytek.struts.Resources" />
</struts-config>
说明:

1parameter名表示页面传参的名称status=list

2、一个action只能对应一个actionform,而一个actionform可以有多个action使用;

3input用来作错误页的,当validate方法执行后有错误,则自动跳转到该页;

4、所有struts-config.xml中配置的路径必须先加/,表示路径从webroot下开始定义

         5path表示该action的虚拟路径,必须加/,而不需要加.do的后缀

         6scope表示Action的属性方法,request表示每次请求都重新建立新的action

         7type表示Action的包.类名;

8、在action中可以包含多个不同的forward路径,而Forward分局部和全局两种,前者是在Action里配置,仅对该Action有效,后者单独配置,对所有的Action都有效,当每个Action在转发时,首先在局部Forward中查找与之对应的Forward,如果没找到,则才会到全局中查找,所以局部Forward可以覆盖全局Forward

         9forward中的nameforward的唯一标识,在action代码中执行跳转时需要通过该name来查找对应的路径,path表示真正跳转的路径;

         10redirect:设置是否使用重定向,只能是truefalse两个值;

         11unknown="true"表示如果没有xx.do则会跳转到错误页面

 

五、JSP

insert.jsp

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<title>添加人员</title>
		<meta http-equiv="pragma" content="no-cache">
		<meta http-equiv="cache-control" content="no-cache">
		<meta http-equiv="expires" content="0">
		<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
		<meta http-equiv="description" content="This is my page">
	</head>
	<body>
		<center>
			<form action="user.do" method="post" enctype="multipart/form-data">
				用户名:
				<input type="text" name="user.account" />
				<br />
				密码:
				<input type="text" name="user.password" />
				<br />
				性别:
				<input type="radio" name="user.sex" value="男" checked="checked" />
				男
				<input type="radio" name="user.sex" value="女" />
				女
				<br />
				真实姓名:
				<input type="text" name="user.realName" />
				<br />
				照片:
				<input type="file" name="img" />
				<br />
				<input type="hidden" name="status" value="insert">
				<input type="submit" value="添加">
			</form>
		</center>
	</body>
</html>


UserList.jsp

 

<%@ page language="java" pageEncoding="UTF-8"%>

<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic"%>
<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html:html lang="true">
<head>

	<title>用户列表</title>

	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">

</head>

<body>
	<center>
	<a href="insert.jsp">添加人员</a><br/>
		<table border="1" width="60%">
			<tr>
				<td>
					用户名
				</td>
				<td>
					性别
				</td>
				<td>
					注册日期
				</td>
				<td>
					照片
				</td>
				<td>
					操作
				</td>
			</tr>
			<logic:present name="users" scope="request">
				<logic:iterate id="user" name="users" scope="request">
					<tr>
						<td>
							${user.account }
						</td>
						<td>
							${user.sex }
						</td>
						<td>
							<bean:write name="user" property="postDate" format="yyyy-MM-dd" />
						</td>
						<td>
							<img alt="${user.account }" src="upload/${user.photo }" width="80px" height="60">
						</td>
						<td>
							<a href="#">修改</a>  <a href="#">删除</a>
						</td>
					</tr>
				</logic:iterate>
			</logic:present>
		</table>

		<jsp:include page="split_page.jsp">
			<jsp:param name="currentPage" value="${cp}" />
			<jsp:param name="lineSize" value="${ls}" />
			<jsp:param name="allRecorders" value="${allRecorders}" />
			<jsp:param name="searchFlag" value="FALSE" />
			<jsp:param name="lineSizeFlag" value="TRUE" />
		</jsp:include>
	</center>
</body>
</html:html>

 

你可能感兴趣的:(Struts1.3)