上一篇文章介紹了在Netbeans6.1中使用SSH框架的準備工作及OR映射的方法,這篇文章則繼續介紹如何構建視圖層和業務邏輯層以及在此過程中整合Struts和Spring框架。
1、建立業務邏輯。在service包中創建業務接口UserService,代碼如下:
package service;
importdao.UserDaoImpl;
import po.User;
/**
*
* @author Administrator
*/
public interface UserServive {
void addUser(String userName, String password, int admin) throws Exception;
User getUser(long userId);
User getUser(String userName);
void setUserDao(UserDaoImpl userDao);
}
創建實現類UserServiceImp,代碼如下:
package service;
import po.User;
/**
*
* @author Administrator
*/
public class UserServiceImpl implements UserServive {
private dao.UserDaouserDao;
public void addUser(String userName, String password, int admin) throwsException{
po.User user = new User();
//user.setId(10);
user.setAdmin(admin);
user.setName(userName);
user.setPassword(password);
try
{
userDao.save(user);
}
catch(Exception err)
{
throw err;
}
}
public User getUser(long userId)
{
return userDao.getUser(userId);
}
public void setUserDao(dao.UserDaoImpl userDao) {
this.userDao = userDao;
}
public User getUser(String userName) {
returnthis.userDao.getUser(userName);
}
}
注意紅色部分代碼,爲了訪問數據庫,必須引入userDao的對象,生成set的方法,並通過Spring IoC容器注入該屬性,在applicationContext.xml中增加以下配置:
<beanid="userService" class="service.UserServiceImpl">
<propertyname="userDao">
<refbean="userDao"></ref>
</property>
</bean>
userDao的配置已經在上一篇文章描述過,引用的是以下這段配置:
<beanid="userDao" class="dao.UserDaoImpl">
<propertyname="sessionFactory">
<refbean="sessionFactory"></ref>
</property>
</bean>
service的方法就是通過調用dao的實體方法來操作的,如上面代碼第二段紅色的部分。
2、建立視圖。在web頁面的example目錄下新建JSP頁面,命名爲Login。在文件頭部添加Struts2.0的標籤引入:
<%@ taglibprefix="s" uri="/struts-tags" %>
在網頁body標籤中加入以下代碼:
<s:form. action="login" method="POST">
<s:textfield name="username"label="%{getText('username')}"/>
<s:password name="password"label="%{getText('password')}"/>
<s:submitvalue="%{getText('submit')}"/>
</s: form>
Struts2.0的標籤庫功能很強大,網上有很多例程,在這裏就不詳述了。關鍵的地方是lable屬性裏面的表達式,在這裏,是爲了國際化而設的。要在Struts2.0中使用i18N,我們首先要在源包-缺省包中新建一個屬性文件(點擊新建-其他-屬性文件),命名爲struts。在struts.properties中添加定義:
struts.custom.i18n.resources=globalMessages
這條語句指定資源文件的前綴,例如中文的資源文件可以命名爲globalMessages_zh_CN,英文的可以命名爲globalMessages_en_US。我們在缺省包中分別創建這兩個屬性文件。在中文的資源文件中加入以下:
username=用戶名
password=密碼
submit=提交
英文的資源文件加入:
username=Username
password=Password
submit=Submit
然後就可以在JSP頁面中用%{getText('username')}的表達式來指定要讀出的字符串了。在Struts2.0中,我們不必再手動地把中文轉換爲Unicode碼,框架會自動轉換。
3、創建Action。在action包中點擊右鍵-新建-其他-Struts2-Struts2Action,命名爲LoginAction。Struts2.0中不再需要創建ActionForm,只要生成屬性的get和set方法,就能夠獲取到頁面標籤name屬性對應的值。在這裏,LoginAction繼承com.opensymphony.xwork2.ActionSupport。代碼如下:
package action;
importcom.opensymphony.xwork2.ActionSupport;
import java.util.Locale;
import org.springframework.context.support.ResourceBundleMessageSource;
import po.User;
import service.UserServiceImpl;
/**
*
* @author mg
*/
public classLoginAction extends ActionSupport{
private UserServiceImpl userService;
private String message;
private String username;
private String password;
private ResourceBundleMessageSource messageSource;
public LoginAction() {
}
@Override
public String execute() throws Exception {
User usr =userService.getUser(username);
if(usr != null){
if(usr.getPassword().equals(password)){
message = messageSource.getMessage("loginSuccess",null,Locale.CHINA);
}else{
message = messageSource.getMessage("pswError", null,Locale.CHINA);
}
}else{
message =messageSource.getMessage("usrError",null,Locale.CHINA);
}
return SUCCESS;
}
public void setUserService(UserServiceImpl userService) {
this.userService = userService;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public void setMessageSource(ResourceBundleMessageSource messageSource) {
this.messageSource = messageSource;
}
}
注意紅色代碼的屬性。其中ResourceBundleMessageSource是Spring 2.5中處理國際化信息的類,UserServiceImp是操作User實體的業務邏輯類。這兩個類的實例都是通過Spring IoC容器管理和注入的。因此,必須在applicationContext.xml中添加配置:
<bean id="messageSource"class="org.springframework.context.support.ResourceBundleMessageSource">
<propertyname="basename" value="messages"/>
</bean>
<bean id="loginAction" class="action.LoginAction">
<propertyname="userService">
<refbean="userService"></ref>
</property>
<propertyname="messageSource" ref="messageSource"/>
</bean>
在缺省包中添加屬性文件messages.properties,注意文件名要以messageSource的bean定義的basename屬性一致。在該資源文件中加入以下信息:
loginSuccess=登錄成功
pswError=密碼錯誤,請重新登錄
usrError=用戶名錯誤,請檢查輸入
然後即可以通過messageSource.getMessage("pswError",null,Locale.CHINA)的方法來取得相應的字符串了。
LoginAction中的返回值SUCCESS是ActionSupport中預定義的跳轉字符串,在struts.xml的package標籤中如下配置:
<struts>
<include file="example.xml"/>
<!-- Configuration for the default package. -->
<package name="default"extends="struts-default">
<action name="login"class="loginAction">
<result>/message/message.jsp</result>
</action>
</package>
</struts>
Struts2.0的配置文件精簡了很多,但這裏有一個問題要注意的,就是login這個action的class,這裏寫的是loginAction。而這個bean是在SpringIoC容器裏面管理的,見上一段Spring的配置文件。這樣,Struts的Action全部由Spring容器來管理,在適當的時候纔會實例化和銷燬。而這種整合需要struts2-spring-plugin-2.0.11.1.jar這個工具包。
在web頁面中新建路徑message,在message路徑下新建JSP頁面message.jsp,用以下代碼覆蓋:
<%@page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:property value="message"/>
注意message是從LoginAction中設置而得的。
至此,這個登陸的例程就完成了,點擊example目錄下的Login.jsp選擇運行文件(注意,不要直接運行工程),得到如下結果:
把瀏覽器的默認語言改爲en_US,刷新一下頁面,得到以下結果:
輸入正確的用戶名和密碼,跳轉到以下頁面:
輸入密碼錯誤則提示:
特別鳴謝:
Sun SITE開發組組員Ruby (Tan Jiazhang) 提供demo的架構整合方案