关闭

Struts2(四)---NETctoss资费列表

标签: javastruts2myeclipsejsp
939人阅读 评论(0) 收藏 举报
分类:

转载请注明http://blog.csdn.net/uniquewonderq

问题:

开发NetCTOSS项目中,资费模块的查询功能。要求查询全部的资费表数据并以列表的方式显示在页面上,其中分页功能先不实现。

方案:

查询功能只包含一个请求,即对资费数据的查询请求。在这次请求中,我们需要查询出资费所有的数据,然后将数据传递给查询列表页面,在页面上用表格显示出来。使用struts2处理这种请求的过程如下图:


在这个请求的过程中,我们需要编写的代码有:

1.Entity,封装资费表的实体类。

2.DAO,数据库访问代码的组件

3.Action,业务流程控制组件。

4.struts.xml,struts2的配置文件

5.JSP,负责内容的展现

这些代码的编写顺序,往往是按照他们的相互依赖关系来进行的,优先编写被依赖的代码,因为推荐代码的编写顺序是:Entity-->DAO-->Action-->struts.xml-->JSP。

注意:struts.xml写在JSP前面的原因是,开发完该配置文件,可以部署并启动项目,而在开发JSP时可以一边写一遍刷新看效果,不必重新启动服务了。NetCTOSS项目这里采用ORACLE数据库开发。

步骤一:项目搭建



项目搭建包括项目的创建以及框架等操作,目前NetCTOSS项目仅采用了struts2的框架,搭建过程只包含struts2框架的引入即可,因此这个和第一个struts2项目一样。




步骤二:Entity

创建com.netctoss.entity包,用于封装实体类。然后创建资费表对应的实体类Cost,代码如下:

package com.netctoss.entity;
import java.sql.Date;
//资费实体类
public class Cost {
		private Integer id;//主键
		private String name;//资费名称
		private Integer baseDuration;//在线时长
		private Double baseCost;//基本费用
		private Double unitCost;//单位费用
		private String status;//状态
		private String descr;//资费说明
		private Date creatTime;//创建日期
		private Date startTime;//启用日期
		private String costType;//资费类型
		public Integer getId() {
			return id;
		}
		public void setId(Integer id) {
			this.id = id;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public Integer getBaseDuration() {
			return baseDuration;
		}
		public void setBaseDuration(Integer baseDuration) {
			this.baseDuration = baseDuration;
		}
		public Double getBaseCost() {
			return baseCost;
		}
		public void setBaseCost(Double baseCost) {
			this.baseCost = baseCost;
		}
		public Double getUnitCost() {
			return unitCost;
		}
		public void setUnitCost(Double unitCost) {
			this.unitCost = unitCost;
		}
		public String getStatus() {
			return status;
		}
		public void setStatus(String status) {
			this.status = status;
		}
		public String getDescr() {
			return descr;
		}
		public void setDescr(String descr) {
			this.descr = descr;
		}
		public Date getCreatTime() {
			return creatTime;
		}
		public void setCreatTime(Date creatTime) {
			this.creatTime = creatTime;
		}
		public Date getStartTime() {
			return startTime;
		}
		public void setStartTime(Date startTime) {
			this.startTime = startTime;
		}
		public String getCostType() {
			return costType;
		}
		public void setCostType(String costType) {
			this.costType = costType;
		}
		
}

步骤三:DAO

DAO是数据库访问组件,用于封装对数据库的增删改查操作。当前请求中查询全部资费数据的方法,需要写在DAO中。

首先,我们要创建DAO组件并编写本案例中需要使用的查询全部资费数据的代码。但是通常情况下,我们并不是直接写一个DAO的类,在类中直接编写这样的代码,而是先定义接口。

定义接口的原因在于,一般情况下业务是比较固定的,针对这些业务我们需要提供的数据库访问方法也相对稳定,而通过接口哦我们是可以描述出这些固定的业务。那么定义接口的目的在于,实际项目中,随着技术的革新和性能的要求,我么你可能会改变实现这种业务的手段,比如当前我们使用JDBC来时西安DAO,可能过一段时间,我们又想使用Hibernate替换JDBC来实现DAO。

对于这种场景,如果DAO仅仅是一个类,直接实现业务,那么业务代码中会大量的调用他,我们很难再去进行修改了。而使用接口的话,我们的业务代码可以通过工厂调用接口,修改时只需要重新写一个实现类,来替换工厂中原有的实现类即可,对业务代码没有任何的影响。简单来说,定义接口是为了提高代码的复用率,降低代码维护的成本。

因此我们需要穿件一个DAO接口,并定义查询全部资费的方法,代码如下:

package com.netctoss.dao;

import java.util.List;
//资费DAO接口

import com.netctoss.entity.Cost;
public interface ICostDao {
	//查询全部资费数据
	List<Cost> findAll();
}


然后,要实现这个接口,目前我们可以使用JDBC/MyBatis 来访问数据库,实现这个接口,由于本案例侧重点在struts2的使用,因此就简化DAO的实现,这里简单的模拟一下这个查询方法的实现。即创建一个实体类CostDaoImpl实现接口IcostDao,并使用模拟的方式来实现查询方法,代码如下:

package com.netctoss.dao;

import java.util.ArrayList;
import java.util.List;

import javax.crypto.Cipher;

import sun.security.krb5.internal.crypto.crc32;

import com.netctoss.entity.Cost;
//当前阶段终点是struts2,对于DAO的实现就模拟实现了
public class CostDaoImpl implements ICostDao {

	public List<Cost> findAll() {//模拟查询全部资费数据
			List<Cost> list=new ArrayList<Cost>();
			
			Cost c1=new Cost();
			c1.setId(95);
			c1.setName("6元套餐");
			c1.setBaseDuration(66);
			c1.setBaseCost(6.6);
			c1.setUnitCost(0.6);
			c1.setDescr("6元的套餐~");
			c1.setStatus("0");
			c1.setCostType("2");
			list.add(c1);
			
			Cost c2=new Cost();
			c2.setId(96);
			c2.setName("8元套餐");
			c2.setBaseDuration(88);
			c2.setBaseCost(8.8);
			c2.setUnitCost(0.8);
			c2.setDescr("8元的套餐~");
			c2.setStatus("0");
			c2.setCostType("2");
			list.add(c2);
			
			Cost c3=new Cost();
			c3.setId(97);
			c3.setName("10元套餐");
			c2.setBaseDuration(99);
			c2.setBaseCost(9.9);
			c2.setUnitCost(0.9);
			c2.setDescr("10元的套餐~");
			c2.setStatus("0");
			c2.setCostType("2");
			list.add(c3);
			
			return list;
	}

}

步骤四:Action

Aciton是业务控制器,需要调用DAO组织业务流程,并将计算出的结果传递给页面显示。其中对DAO的调用,不要直接在Action中实例化CostDaoImpl,避免业务代码中大量的引用该实现类,如果将来更换DAO方式时不好修改。


这种情况,我们通常情况是使用工厂类来创建DAO实例,并返回其接口类型即可。那么Aciton中通过工厂获取到接口,其依赖的仅仅是这个接口,当DAO实现方式变更时,只需要修改工厂即可,项目中所有的Action类都不需要做任何的修改。

因此,首先我么创建这个工厂类,使用工厂方法来创建DAO的实例,即在com.netctoss.dao包下创建DAOFactory,代码如下:

package com.netctoss.dao;

import com.sun.org.apache.bcel.internal.generic.NEW;

//DAO工厂,负责统一的创建DAO实例
public class DAOFactory {
	//资费DAO实例
	private static ICostDao costDao=new CostDaoImpl();
	//返回资费DAO实例
	public static ICostDao getCostDao(){
		return costDao;
	}
}

接下来,我们要创建业务控制器Action,并在其中处理查询请求。即创建包com.netctoss.action,用于封装所有的Action类,然后在此包下创建类FindCostAction,并在Action的业务方法中调用DAO查询出所有的资费,然后通过属性将结果传递给JSP。代码如下,

package com.netctoss.action;

import java.util.List;

import com.netctoss.dao.DAOFactory;
import com.netctoss.dao.ICostDao;
import com.netctoss.entity.Cost;

//资费查询Action
public class FindCostAction {
	private List<Cost> costs;
	//业务方法,配置action时如果不指定method属性,
	//那么struts2会自动调用execute方法
	public String execute(){
		//获取DAO实例
		ICostDao dao=DAOFactory.getCostDao();
		try{
			costs=dao.findAll();
		}catch (Exception e) {
			e.printStackTrace();
			//捕获到异常时,跳转到错误页面
			return "error";
		}
		//正常执行时,跳转到资费列表页面
		return "success";
	}
	public List<Cost> getCosts() {
		return costs;
	}
	public void setCosts(List<Cost> costs) {
		this.costs = costs;
	}
	
}

需要注意的是,Acito是业务控制器,它的作用是根据用户的输入来计算输出,并将结果返回给页面显示给用户看,简单说就是根据输入计算输出。因此,在实现Aciton时,我么首先分析当前请求的输入和输出分别是什么,然后在Action中定义成员变量来封装输入和输出,之后在业务方法中根据输入属性计算输出属性的值即可。

步骤五:struts.xml

struts.xml下,配置acton以及JSP。由于目前还没有创建JSP,因此我们先预先想好JSP的名称加以配置,后面创建JSP是要使用配置中指定的名称,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
    "http://struts.apache.org/dtds/struts-2.1.7.dtd">
    <struts>
    <!--资费模块配置信息:
    	一般情况下,一个模块的配置单独封装在一个package下,
    	并且以模块名来命名package的name和namespace 
     -->
     <package name="cost" namespace="/cost" extends="struts-default">
     	<!-- 查询资费数据 -->
     	<action name="findCost" class="com.netctoss.action.FindCostAction">
     	<!-- 正常情况下跳转到资费列表页面,一般一个模块的页面要打包在一个文件夹下,并且文件名以模块名命名 -->
     	<result name="success">
     		/WEB-INF/cost/find_cost.jsp
     	 </result>
     	 <!-- 错误情况下, 跳转到错误页面
     	 	错误页面可以被所有模块服用,因此放在main下
     	 	该文件夹用于存放公用的页面
     	  -->
     	<result name="error">
     		/WEB-INF/main/error.jsp
     	 </result>
     	</action>
     </package>
    </struts>


步骤六:JSP

......后序继续。。。



















0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:284210次
    • 积分:5261
    • 等级:
    • 排名:第5473名
    • 原创:240篇
    • 转载:29篇
    • 译文:2篇
    • 评论:30条
    最新评论