既然是说SSH,那就少不了WEB层的struts.我们以前做过一个小型的HRMS,采用的是Spring自己的MVC框架。这一次,我们还是用老牌的Struts。这是一个非常简单而且容易学习的框架,如果大家对它还不是非常了解,请先参考我的相关文章。这里我们用MyEclipse开发,加入Struts的支持后,我们开发人员最主要的工作就是编写Action和ActionForm类,然后再在struts-config.xml上配置Action和ActionForm。我们来看看应用中主要的Action和ActionForm:
1. 首先是执行增加/编辑操作的Action要用到的ActionForm:HouseForm。这里有个很重要的技巧,我们使用实体DTO类来做我们ActionForm的属性。这样我们在表现层和业务逻辑层之间传递数据的时候就可以非常轻松。
package org.leno.houseHire.action;
import org.apache.struts.action.ActionForm;
import org.leno.houseHire.service.HouseDTO;
public class HouseForm extends ActionForm {
private HouseDTO house = new HouseDTO();
public HouseDTO getHouse() {
return house;
}
public void setHouse(HouseDTO house) {
this.house = house;
}
}
2. 接着是执行查询列表操作用到的ActionForm:SearchForm。它也同样使用实体类作为自己的属性开简化表现层和业务逻辑层之间的传值工作。
package org.leno.houseHire.action;
import org.apache.struts.action.ActionForm;
public class SearchForm extends ActionForm {
private Condition cond = new Condition();
private int start=0;
private int limit = 5;
public Condition getCond() {
return cond;
}
public void setCond(Condition cond) {
this.cond = cond;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
}
package org.leno.houseHire.action;
public class Condition {
private String title;
private int room;
private int ting;
private int areaId;
private int streetId;
private double priceStart;
private double priceEnd=10000;
private String booktime;
private String sortCond = "asc";
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getRoom() {
return room;
}
public void setRoom(int room) {
this.room = room;
}
public int getTing() {
return ting;
}
public void setTing(int ting) {
this.ting = ting;
}
public int getAreaId() {
return areaId;
}
public void setAreaId(int areaId) {
this.areaId = areaId;
}
public double getPriceStart() {
return priceStart;
}
public void setPriceStart(double priceStart) {
this.priceStart = priceStart;
}
public double getPriceEnd() {
return priceEnd;
}
public void setPriceEnd(double priceEnd) {
this.priceEnd = priceEnd;
}
public void setBooktime(String booktime) {
this.booktime = booktime;
}
public String getBooktime() {
return booktime;
}
public String getSortCond() {
return sortCond;
}
public void setSortCond(String sortCond) {
this.sortCond = sortCond;
}
public int getStreetId() {
return streetId;
}
public void setStreetId(int streetId) {
this.streetId = streetId;
}
@Override
public String toString() {
return "标题"+title+" room:"+room+" ting "+ting+" areaId: "+areaId+" streetId "+streetId+" booktime "+booktime+" sort "+sortCond;
}
}
3. 这是我们房屋查询列表的Action,瞧瞧,代码是不是非常简洁。注意,这里和我们平常写的Action有个很大的不同:我们并没有返回指定的JSP视图或是跳转到下一个Action处理,而是直接利用网络输出流写出一个JSON数组。因为JSON是JS的原生格式,我们的ExtJS对它的支持是非常好的。
package org.leno.houseHire.action;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
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.leno.houseHire.service.HouseDTO;
import org.leno.houseHire.service.IHouseService;
public class HouseSearchAction extends Action {
private IHouseService houseService;
public void setHouseService(IHouseService houseService) {
this.houseService = houseService;
}
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
SearchForm hForm = (SearchForm) form;
response.setCharacterEncoding("utf-8");
//****用实体对象做form的属性,能够大幅度减少代码量****
Condition cond = hForm.getCond();
List<HouseDTO> list = houseService.findAllHouse(cond,hForm.getStart(),hForm.getLimit());
JSONObject json = new JSONObject();
json.put("totalProperty", houseService.getTotalNums(cond));
JSONArray arr = JSONArray.fromObject(list);
json.put("root", arr);
response.getWriter().print(json);
return null;
}
}
4. 这是我们房屋信息发布或者修改的Action,它也是直接利用网络输出流写出数据。具体主要是根据客户端传过来的操作参数来调用Service层做事。
package org.leno.houseHire.action;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
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.leno.houseHire.service.HouseDTO;
import org.leno.houseHire.service.IHouseService;
import org.leno.houseHire.service.LoginDTO;
public class HouseHandlerAction extends Action {
private IHouseService houseService;
public void setHouseService(IHouseService houseService) {
this.houseService = houseService;
}
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.setCharacterEncoding("utf-8");
PrintWriter pw = response.getWriter();
String action = request.getParameter("action");
HouseForm hForm = (HouseForm) form;
HouseDTO house = hForm.getHouse();
LoginDTO user = (LoginDTO) request.getSession().getAttribute("USER_INFO");
house.setUserId(user.getUid());
house.setBooktimeInfo(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
if("addHouse".equals(action)){
pw.print(1);
houseService.addHouse(house);
}else if("editHouse".equals(action)){
pw.print(1);
houseService.editHouse(house);
}
return null;
}
}
最后来看看我们Struts框架的核心配置文件struts-config.xml吧!
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<data-sources />
<form-beans>
<form-bean name="loginForm"
type="org.leno.houseHire.action.LoginForm">
</form-bean>
<form-bean name="searchForm"
type="org.leno.houseHire.action.SearchForm">
</form-bean>
<form-bean name="houseForm"
type="org.leno.houseHire.action.HouseForm">
</form-bean>
</form-beans>
<global-exceptions />
<global-forwards />
<action-mappings>
<action path="/login"
type="org.springframework.web.struts.DelegatingActionProxy"
name="loginForm">
</action>
<action path="/house"
type="org.springframework.web.struts.DelegatingActionProxy"
name="searchForm" scope="session">
<forward name="test" path="/index.jsp"></forward>
</action>
<action path="/houseExport"
type="org.springframework.web.struts.DelegatingActionProxy"
name="searchForm" scope="session">
</action>
<action path="/houseHandler"
type="org.springframework.web.struts.DelegatingActionProxy"
name="houseForm" scope="session">
</action>
</action-mappings>
<message-resources
parameter="org.leno.houseHire.action.ApplicationResources" />
</struts-config>
注意,我们这里Action配置元素的type属性节点,以前我们不是直接配置类的完整名字吗?现在的这个类型是什么?我们回想我们的Spring的核心配置里面好像已经配置了这些Action的Bean,也就是说,struts框架里面最重要的类Action都委托给Spring去管理了。(当然主要是为了借助它强大的IOC和AOP的能力!),这里要注意的是Action的path属性要和applicationContext.xml中配置的bean的name属性一致!