用戶表創(chuàng)建好之后,接下來我們就可以編寫代碼了,首先第一步,我們需要實(shí)現(xiàn)AbstractUser抽象類,定義我們自己的用戶實(shí)體對象,其代碼如下:
DemoUser類源碼
import java.util.List;
import java.util.Map;
import com.bstek.bdf2.core.business.AbstractUser;
import com.bstek.bdf2.core.business.IDept;
import com.bstek.bdf2.core.business.IPosition;
import com.bstek.bdf2.core.model.Group;
import com.bstek.bdf2.core.model.Role;
public class DemoUser extends AbstractUser {
private static final long serialVersionUID = 4348475318698431153L;
private String username;
private String cname;
private String password;
private List<IDept> depts;
private List<IPosition> positions;
private List<Role> roles;
private List<Group> groups;
public String getCname() {
return cname;
}
public String getEname() {
return cname;
}
/**
* 當(dāng)前用戶是否為系統(tǒng)管理員,如果這個屬性返回true,那么就表示當(dāng)前用戶為系統(tǒng)管理員,
* 所有權(quán)限對其都不起作用,反之則不然。
* */
public boolean isAdministrator() {
return false;
}
/**
* 當(dāng)前用戶的手機(jī)號
* */
public String getMobile() {
return "13122112211";
}
/**
* 當(dāng)前用戶的email地址
* */
public String getEmail() {
return "test@sina.com";
}
/**
* 當(dāng)前用戶所在部門
* */
public List<IDept> getDepts() {
return depts;
}
/**
* 當(dāng)前用戶所擁有的崗位
* */
public List<IPosition> getPositions() {
return positions;
}
public void setPositions(List<IPosition> positions) {
this.positions = positions;
}
public void setDepts(List<IDept> depts) {
this.depts = depts;
}
/**
* 當(dāng)前用戶所擁有的角色,權(quán)限需要使用
* */
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
/**
* 當(dāng)前用戶所在群組
* */
public List<Group> getGroups() {
return groups;
}
public void setGroups(List<Group> groups) {
this.groups = groups;
}
/**
* 用戶的其它元數(shù)據(jù)信息,如果我們的應(yīng)用用不到,可直接返回null
* */
public Map<String, Object> getMetadata() {
return null;
}
public String getPassword() {
return password;
}
public String getUsername() {
return username;
}
/**
* 判斷當(dāng)前用戶是否可用,可以在用戶來源信息中判斷這里取值,如果返回false,那么該用戶將不能登錄
*/
public boolean isEnabled() {
return true;
}
/**
* 當(dāng)前用戶所在公司ID,如果當(dāng)前系統(tǒng)只給一家公司使用,這里返回一個固定值即可,
* 如果是基于SAAS系統(tǒng),那么這里需要根據(jù)公司信息返回一個值
* */
public String getCompanyId() {
return "bstek";
}
public void setUsername(String username) {
this.username = username;
}
public void setCname(String cname) {
this.cname = cname;
}
public void setPassword(String password) {
this.password = password;
}
}
在上面的代碼當(dāng)中,對于AbstractUser當(dāng)中的一些重要方法我們做了描述,AbstractUser當(dāng)中需要我們實(shí)現(xiàn)的方法都是必須的,而且都不能返回null(getMetadata方法除外),否則系統(tǒng)運(yùn)行時可能會產(chǎn)生空指針的異常,開發(fā)當(dāng)中,我們已盡量將AbstractUser類中需要實(shí)現(xiàn)的方法減到最少。
編寫好我們自定義的用戶實(shí)體對象后,接下來我們需要實(shí)現(xiàn)IUserService接口,在這個接口當(dāng)中定義了如何獲取用戶信息等相關(guān)操作,這個接口的源碼如下:
IUserService接口源碼
package com.bstek.bdf2.core.service;
import java.util.Collection;
import org.springframework.security.core.userdetails.UserDetailsService;
import com.bstek.bdf2.core.business.IUser;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
/**
* @since 2013-1-18
* @author Jacky.gao
*/
public interface IUserService extends UserDetailsService {
public static final String BEAN_ID="bdf2.userService";
/**
* 分頁加載用戶數(shù)據(jù)
* @param page
Dorado7分頁對象,其中包含pageNo,pageSize,分頁后的數(shù)據(jù)也填充到這個page對象當(dāng)中,該參數(shù)不可為空
* @param companyId 要加載哪個companyId下的用戶信息,該參數(shù)不可為空
* @param criteria Dorado7條件對象,可從中取到相應(yīng)的條件值,該參數(shù)可為空
*/
void loadPageUsers(Page<IUser> page,String companyId,Criteria criteria);
/**
* 加載指定部門ID下的用戶信息
* @param deptId 隸屬的部門ID,該參數(shù)不可為空
* @return 返回取到的用戶集合
*/
Collection<IUser> loadUsersByDeptId(String deptId);
/**
* 檢查用戶密碼是否正確,如果不正確返回錯誤消息,如正確則返回null
* @param username 用戶名
* @param password 要檢查未加密的密碼
* @return 不正確返回錯誤消息,如正確則返回null
*/
String checkPassword(String username,String password);
/**
* 修改指定用戶的密碼信息
* @param username 用戶名
* @param newPassword 新密碼
*/
void changePassword(String username,String newPassword);
/**
* 注冊一個系統(tǒng)管理員賬號
* @param username 用于登錄的用戶名
* @param cname 中文名
* @param ename 英文名
* @param password 密碼
* @param mobile 手機(jī)號
* @param email 電子郵件
* @param companyId 所在公司ID
*/
void registerAdministrator(String username,String cname,String ename,String password,String
email,String mobile,String companyId);
/**
* 根據(jù)用戶名,實(shí)現(xiàn)化一個空的用戶對象供系統(tǒng)使用,實(shí)例化的用戶對象,只需要將給定的用戶名填充進(jìn)去即可
* @param username 用戶名
* @return 實(shí)例化后的用戶對象
*/
IUser newUserInstance(String username);
}
接口中每個方法都有詳細(xì)的解釋,我們需要看理解它,接下來,我們來編寫基于DemoUser的IUserService接口實(shí)現(xiàn)類,來從之前定義的demo_user表中獲取用戶信息,實(shí)現(xiàn)類代碼如下:
IUserService接口實(shí)現(xiàn)類示例
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.orm.jdbc.JdbcDao;
import com.bstek.bdf2.core.service.IUserService;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
public class DemoUserService extends JdbcDao implements IUserService {
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
String sql="select username,password,cname from demo_user where username=?";
List<IUser> users=this.getJdbcTemplate().query(sql, new Object[]{username}, new UserMapper());
if(users.size()==0){
throw new UsernameNotFoundException("User ["+username+"] is not exist!");
}
return users.get(0);
}
public void loadPageUsers(Page<IUser> page, String companyId,
Criteria criteria) {
String sql="select username,password,cname from demo_user where username=?";
Collection<IUser> users=this.getJdbcTemplate().query(sql,new UserMapper());
page.setEntities(users);
}
public Collection<IUser> loadUsersByDeptId(String deptId) {
return Collections.EMPTY_LIST;
}
public String checkPassword(String username, String password) {
return null;
}
public void changePassword(String username, String newPassword) {
}
public void registerAdministrator(String username, String cname,
String ename, String password, String email, String mobile,
String companyId) {
}
public IUser newUserInstance(String username) {
DemoUser user=new DemoUser();
user.setUsername(username);
return user;
}
class UserMapper implements RowMapper<IUser>{
public DemoUser mapRow(ResultSet rs, int rowNum) throws SQLException {
DemoUser user=new DemoUser();
user.setCname(rs.getString("cname"));
user.setPassword(rs.getString("password"));
user.setUsername(rs.getString("username"));
return user;
}
}
}
在這個接口實(shí)現(xiàn)當(dāng)中,我們采用的是JdbcDao實(shí)現(xiàn)從demo_user表中獲取用戶信息,這其中我們保持checkPassword、changePassword與registerAdministrator三個方法為空,那么對應(yīng)頁面當(dāng)中用戶密碼修改及注冊系統(tǒng)管理員兩塊功能就不能正常使用,您可以去實(shí)現(xiàn)一把。
再次,我們還需要實(shí)現(xiàn)IFrameworkService接口,這個接口比較簡單,其中只有一個方法需要我們實(shí)現(xiàn),這個方法的作用是處理用戶登錄時用戶密碼驗(yàn)證的,我們的實(shí)現(xiàn)類代碼如下:
IFrameworkService實(shí)現(xiàn)類示例
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.service.IFrameworkService;
public class DemoFrameworkService implements IFrameworkService {
public void authenticate(IUser user,
UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
DemoUser u=(DemoUser)user;
String pwd=(String)authentication.getCredentials();
if(!u.getPassword().equals(pwd)){
throw new BadCredentialsException("The password is invalid");
}
}
}
可以看到,代碼比較簡單,就是判斷用戶密碼是否正確,如果不正確拋出一個BadCridentialsException即可。
上述三個接口實(shí)現(xiàn)完成之后,最后,我們需要將實(shí)現(xiàn)的DemoUserService及DemoFrameworkService配置到Spring當(dāng)中,以替換系統(tǒng)自帶的IUserService及IFrameworkService的默認(rèn)實(shí)現(xiàn)類,首先我們來看如何配置DemoUserService實(shí)現(xiàn)類。
打開位于WEB-INF/dorado-home目錄下的datasources.xml文件,在其中添加如下配置:
DemoUserService配置示例
<bean id="demoUserService" class="ext.DemoUserService"></bean>
<bdf:user-service ref="demoUserService"/>
第一行,我們將DemoUserService配置成一個bean,其id為demoUserService ,第二行我們利用BDF2提供的namespacescheam將系統(tǒng)默認(rèn)的IUserService實(shí)現(xiàn)用demoUserService bean替換,當(dāng)然如果您沒有引入BDF2提供的namespacescheam,可以用下面的配置來代碼上面兩行配置信息:
DemoUserService另一種配置
<bean id="bdf2.userService" class="ext.DemoUserService"></bean>
可以看到,這種配置更新簡單,只需要一行就可以搞定,但前提是這個bean的ID必須是bdf2.userService。接下來我們看看如何配置DemoFrameworkService類,同樣的方法,在datasources.xml當(dāng)中添加下面兩行配置:
DemoFrameworkService配置
<bean id="demoFrameworkService" class="ext.DemoFrameworkService"></bean>
<bdf:framework-service ref="demoFrameworkService"/>
同樣,如果您沒有引入BDF2提供的namespace scheam,可以用下面的一行替代上述配置:
DemoFrameworkService另一種配置
<bean id="bdf2.frameworkService" class="ext.DemoFrameworkService"></bean>
需要注意的是其ID必須為bdf2.frameworkService。
上述操作完成之后,就可以在demo_user中插入一個用戶,啟動我們應(yīng)用進(jìn)行登錄了。
更多建議: