(本故事除了部分點明道姓并具有故事詳細發生的具體時間點地等部分情節以外,其它內容純屬虛構,若有雷同,純屬巧合。)
談到B/S,談到J2EE,特別涉及到Java Web的部分,我們就會想到三層或多層構架,為什么要多層,肯定是因為一兩層已經無法達到用戶的需求,技術進步了,三層或多層很多時候其系統的健壯性、可維護性等都較之提升了很多。
在本系列文章的前兩篇中,我們基本上沒有涉及到Spring技術的部分,因此,今天換換味,主要給出一個比較簡單、實用,也是最庸俗的spring示例。也即實現一個數據表的添刪改查操作,筆者采用struts+hibernate+spring黃金庸俗組合來實現。示例比較簡單,因此spring的高手及高高手可以忽略示例中的技術細節部分,當然,也請有時間的前輩不吝賜教有關代碼的書寫方法及技術。
?
?
主演:Spring、系統設計師、數據庫開發工程師、Web開發工程師、主程序員、系統集成及部署工程師。
配角:數據庫管理員、美工及頁面設計MM、html,JSP、Struts、My Sql、hibernate。
?
下面就是直殺正題吧!
?
第一步:系統設計
現在你扮演的是系統設計師角色,系統設計師通常都不用管也不想知道你要用什么方法去實現他的東西,他只給你畫出草圖,制訂規矩、條款等,他甚至可以不用知道Java中還有Class這個東西存在。他也不用管你用什么方式存放數據,用什么數據庫中間件來操作數據。
但他站得高,看得遠,為了以后的可維護性、靈活性,考慮到會使用多種數據庫,以及多種數據庫中間件等,因此會先對系統設計建模,通過UML等方式來描述系統流程、組織結構等。同時還會通過使用接口定義出相應的商業邏輯。下面是本例子中的兩個業務邏輯層的接口。
第一個是“用戶”這一實體的描述,IUser.java,代碼如下:
package com.easyjf.example.business;
public interface IUser {?
?public String getBirthday();//生日
?public void setBirthday(String birthday);
?public String getCid();//主鍵cid
?public void setCid(String cid);
?public String getEmail();//用戶郵件email
?public void setEmail(String email);
?public String getIntro();//用戶簡介intro
?public void setIntro(String intro);
?public String getPassword();//用戶密碼password
?public void setPassword(String password);
?public String getTel() ;//用戶電話tel
?public void setTel(String tel);
?public String getUserName();//用戶名userName
?public void setUserName(String userName);
}
第二個是圍繞“用戶”這一實體所提供的有關服務描述,IUserService.java,代碼如下:
package com.easyjf.example.business;
import java.util.Collection;
import java.util.List;
public interface IUserService {
?public IUser newUser();?//創建一個新的用戶
?public IUser read(String cid);//根據主鍵cid讀取一個用戶
?public List query(String scope,Collection paras);//用戶查詢
?public IUser readByName(String userName);//根據用戶名讀取一個用戶
?public IUser login(String userName,String password,String ip);//用戶登錄?
?public boolean save(IUser user);//保存用戶
?public boolean update(IUser user);//修改用戶
?public boolean del(IUser user);//刪除用戶
}
?
除了上面這些,系統設計師還會根據系統需求給出一些具體的設計方法,對系統各層之間的接口規范,Action層使用的框架或模式等。他的工作就算完成了,下面就該程序員、數據庫管理員以及頁面設計人員等表演了。這些角色在我們實際項目中很多時候是同步進行的,可謂花開N朵。然而本文為了能讓新同學把這個示例能跑起來,所以就簡單分了一下步驟,以便新同學按步驟進行。
?
第二步:數據庫設計及建表(數據庫管理員)
隨便選擇一個數據庫My SQL,MS SQL或Oracle均可,先建設一張表,表名叫User,字段如下:
cid,代表主鍵,username-用戶名,password-密碼,email-電子郵件,tel-電話,birthday-生日,intro-簡介,為了演示方便,我們全部字段設置成字符型。
下面是在My SQL中的表結構腳本:
CREATE TABLE `user` (
? `cid` char(16) NOT NULL,
? `username` char(30) NOT NULL,
? `password` char(30) NOT NULL,
? `email` varchar(50) default NULL,
? `tel` varchar(50) default NULL,
? `birthday` varchar(20) default NULL,
? `intro` varchar(500) default NULL,
? PRIMARY KEY? (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
?
?
第三步:隨便選擇一種MVC框架寫Web部份(Web開發工程師)
暈,類Class都沒看見一個就要寫Action了啊?
新手別叫,這里演示的是一種現代、先進、高雅、華麗、貴族式的編程及設計方法!(暈,不準吐!),J2EE中提倡的是面向接口編程,所以,系統設計師都給了你UML圖,甚至連詳細的Java接口都給你了,已經夠多了,快動手吧。
本例MVC使用的Struts框架,因此整個開發流程大致有下面的幾個步驟。
1、?先根據IUser接口,寫一個ActionForm,代碼如下:
package com.easyjf.struts.form;
import org.apache.struts.action.ActionForm;
public class UserForm extends ActionForm {
?private String cid;
?private String userName;
?private String password;
?private String email;
?private String tel;
?private String birthday;
?private String intro;
?
?public String getCid() {
??return cid;
?}
?public void setCid(String cid) {
??this.cid = cid;
?}
?…
??? //其它的getter、stter方法在此略過。
}
?
2、寫Action
根據用戶的需求說明及設計師的相關模式或規范建議等,寫一個處理“添刪改查”等操作的Action,本文全部寫到一個UserManageAction.java 中,代碼如下:
package com.easyjf.struts.action;
import java.util.ArrayList;
import java.util.Collection;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.easyjf.example.business.IUser;
import com.easyjf.example.business.IUserService;
import com.easyjf.struts.form.UserForm;
import com.easyjf.util.CommUtil;
import com.easyjf.web.tools.IPageList;
import com.easyjf.web.tools.ListQuery;
import com.easyjf.web.tools.PageList;
public class UserManageAction extends Action {
?private IUserService userService;?
?public IUserService getUserService() {
??return userService;
?}
?public void setUserService(IUserService userService)
?{
??this.userService=userService;
?}
?public ActionForward execute(ActionMapping mapping,
???ActionForm form,
???HttpServletRequest request,
???HttpServletResponse response) throws Exception {
??WebApplicationContext wac =WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServlet().getServletContext());
??this.userService = (IUserService) wac.getBean("userService");
??String command=request.getParameter("easyJWebCommand");
??if(command==null || "".equals(command)||"list".equals(command)||"query".equals(command))
??{
???return doQuery(mapping,form,request,response);
??}
??else if("new".equals(command))
??{
???return mapping.findForward("edit");
??}
??else if("add".equals(command))
??{
???return doAdd(mapping,form,request,response);
??}
??else if("edit".equals(command))
??{
???return doEdit(mapping,form,request,response);
??}
??else if("update".equals(command))
??{
???return doUpdate(mapping,form,request,response);
??}
??else if("del".equals(command))
??{
???return doDel(mapping,form,request,response);
??}??
??return super.execute(mapping,form,request,response);
?}
?public ActionForward doEdit(ActionMapping mapping,
???ActionForm form,
???HttpServletRequest request,
???HttpServletResponse response)
?{??
??? UserForm vo=(UserForm)form;????
???IUser user=null;
???if(vo.getCid()!=null && (!vo.getCid().equals("")))user=userService.read(vo.getCid());
???if(user==null)user=userService.newUser();
???? if(user!=null)
???? {???? ?
???? ? vo.setCid(user.getCid());
???? ? vo.setUserName(user.getUserName());
???? ? vo.setPassword(user.getPassword());
???? ? vo.setTel(user.getTel());
???? ? vo.setEmail(user.getEmail());
???? ? vo.setIntro(user.getIntro());
???? ? vo.setBirthday(user.getBirthday());
???? ? return mapping.findForward("edit");
???? }
???? else
???? {
???? ?request.setAttribute("msg","找不到數據!");?
???? ?return doQuery(mapping,form,request,response);
???? }
?}
?public ActionForward doUpdate(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)
?{
??IUser? obj=(IUser)form2Po(form);
???? if(userService.update(obj))
???? {
???? ?request.setAttribute("msg","數據修改成功!");
???? ?return doQuery(mapping,form,request,response);
???? }
???? else
???? {
???? ?request.setAttribute("msg","數據修改失敗");?
???? ?return mapping.getInputForward();
???? }
?}
?public ActionForward doAdd(ActionMapping mapping,
???ActionForm form,
???HttpServletRequest request,
???HttpServletResponse response)
?{
??IUser? obj=form2Po(form);
??if(obj==null)
??{
???request.setAttribute("msg","無法創建要保存的對象,添加失敗!");
???return mapping.getInputForward();
??}????????
???? if(userService.save(obj))
???? {
???? ?request.setAttribute("msg","數據添加成功!");
???? ?return doQuery(mapping,form,request,response);
???? }
???? else
???? {
???? ?request.setAttribute("msg","數據添加失敗");?
???? ?return mapping.getInputForward();
???? }???
?}
?public ActionForward doQuery(ActionMapping mapping,
???ActionForm form,
???HttpServletRequest request,
???HttpServletResponse response)
?{
??int currentPage=CommUtil.null2Int(request.getParameter("page"));
??int pageSize=CommUtil.null2Int(request.getParameter("pageSize"));
??if(currentPage<1)currentPage=1;
??if(pageSize<1)pageSize=15;
??String scope="1=1";
??Collection paras=new ArrayList();??
??String orderType=CommUtil.null2String(request.getParameter("orderType"));
??String orderField=CommUtil.null2String(request.getParameter("orderField"));??
??String userName=CommUtil.null2String(request.getParameter("queryUserName"));
??String tel=CommUtil.null2String(request.getParameter("queryTel"));????
??if(!userName.equals(""))
??{
???scope+=" and userName like ?";
???paras.add("%"+userName+"%");
??}
??if(!tel.equals(""))
??{
???scope+=" and tel like ?";
???paras.add("%"+tel+"%");
??}??
??if(orderField.equals(""))//默認按用戶名排序
??{
??orderField="userName";
??orderType="desc";????
??}?
??if(!orderField.equals(""))
??{
??scope +=" order by "+orderField;
??if(!orderType.equals(""))scope+=" "+orderType;
??}?
??IPageList pList=new PageList(new ListQuery(userService.query(scope,paras)));
??pList.doList(pageSize,currentPage,"","");
??if(pList!=null){
???request.setAttribute("list",pList.getResult());
???request.setAttribute("pages",new Integer(pList.getPages()));
???request.setAttribute("rows",new Integer(pList.getRowCount()));
???request.setAttribute("page",new Integer(pList.getCurrentPage()));??
???request.setAttribute("gotoPageHTML",CommUtil.showPageHtml(pList.getCurrentPage(),pList.getPages()));
???}
??request.setAttribute("orderType",orderType);
??request.setAttribute("orderField",orderField);
??return mapping.findForward("list");
?}
?public ActionForward doDel(ActionMapping mapping,
???ActionForm form,
???HttpServletRequest request,
???HttpServletResponse response)
?{
??UserForm vo=(UserForm)form;????
??IUser user=null;
??if(vo.getCid()!=null && (!vo.getCid().equals("")))user=userService.read(vo.getCid());?
???? if(user!=null && userService.del(user))
???? {
???? ?request.setAttribute("msg","數據刪除成功!");???? ?
???? }
???? else
???? {
???? ?request.setAttribute("msg","數據修改失敗");?
???? }????
???? return doQuery(mapping,form,request,response);
?}
?public IUser form2Po(ActionForm form) {
???? UserForm vo=(UserForm)form;????
??IUser user=null;
??if(vo.getCid()!=null && (!vo.getCid().equals("")))user=userService.read(vo.getCid());
??if(user==null)user=userService.newUser();
??user.setUserName(vo.getUserName());
??user.setBirthday(vo.getBirthday());
??user.setEmail(vo.getEmail());
??user.setTel(vo.getTel());
??user.setPassword(vo.getPassword());
??user.setIntro(vo.getIntro());
??return user;
?}??
}
注意了,Action中使用的都是IUser,IUsrService等接口,其中execute方法中有一句有點不一樣:
?WebApplicationContext wac =WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServlet().getServletContext());
??this.userService = (IUserService) wac.getBean("userService");
這就是傳說中強大的Spring IOC的使用。因為有了他,我們的Web開發人員也不用知道這個IUserService究竟是什么東西了,有時候也無法知道。你想想,你在做這一步的時候,可能另外分工做后臺商業邏輯層的伙伴還沒有把IUserService的實現寫出一個來呢。Web開發人員需要用的IUserService的時候,直接通過類似的方法找Spring取就是了。Spring一個角色是扮演IOC容器中間件嘛,他都沒有誰還有呢?
本例中有關com.easyjf.web.tools、com.easyjf.util等包只是使用了EasyJWeb的分頁業務引擎及一些實用工具,沒有其它功能,否則代碼就會更多了。大家可以下載EasyJWeb的源碼看到詳細實現方式。
?
3、美工及設計制作人員做界面,完成后交由我們Web開發人員加JSP代碼。
?
JSP部分主要有兩個頁面,userEdit.jsp主要是一個用戶信息錄入表單。userList.jsp是用戶信息列表頁面。這一部分大家一定都輕車熟路了吧,由于篇幅、頁面、版面等都有限,就不把詳細代碼扔出來污染環境了。請新手直接到EasyJF開源團隊官網下載完整的示例代碼,其中包括了這兩個JSP頁面。下載地址:
?
4、配置Struts配置文件struts-config.xml
struts-config.xml的內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "
<struts-config>
? <data-sources />
? <form-beans >
? <form-bean name="userForm" type="com.easyjf.struts.form.UserForm" />
? </form-beans>
? <action-mappings >
??? <action attribute="userForm" input="/userEdit.jsp" name="userForm"
????? path="/userManage"? scope="request"
????? type="com.easyjf.struts.action.UserManageAction">
????? <forward? name="edit" path="/userEdit.jsp" />
????? <forward? name="list" path="/userList.jsp" />
??? </action>???
? </action-mappings>
? <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
??<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml" />
?</plug-in>?
</struts-config>
?
5、最后還差一步,就是配置web.xml文件。
Web.xml文件內容如下
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
?<context-param>
??<param-name>contextConfigLocation</param-name>
??<param-value>/WEB-INF/applicationContext.xml</param-value>
?</context-param>?
?<listener>
??<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
?</listener>?
?<servlet>
??<servlet-name>action</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>???
?</servlet>
?<servlet-mapping>
??<servlet-name>action</servlet-name>
??<url-pattern>*.do</url-pattern>
?</servlet-mapping>
</web-app>
工作都完了,自己在檢查檢查,可以作一些單元測試等工作,并把接口用說明文檔寫好交給老大吧。
下面我們再看看其它角色的表演!
posted on 2006-08-07 14:30
SIMONE 閱讀(262)
評論(0) 編輯 收藏 所屬分類:
JSP