用戶表創(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;
}
public boolean isAdministrator() {
return false;
}
public String getMobile() {
return "13122112211";
}
public String getEmail() {
return "test@sina.com";
}
public List<IDept> getDepts() {
return depts;
}
public List<IPosition> getPositions() {
return positions;
}
public void setPositions(List<IPosition> positions) {
this.positions = positions;
}
public void setDepts(List<IDept> depts) {
this.depts = depts;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public List<Group> getGroups() {
return groups;
}
public void setGroups(List<Group> groups) {
this.groups = groups;
}
public Map<String, Object> getMetadata() {
return null;
}
public String getPassword() {
return password;
}
public String getUsername() {
return username;
}
public boolean isEnabled() {
return true;
}
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)行時(shí)可能會(huì)產(chǎn)生空指針的異常,開發(fā)當(dāng)中,我們已盡量將AbstractUser類中需要實(shí)現(xiàn)的方法減到最少。
編寫好我們自定義的用戶實(shí)體對象后,接下來我們需要實(shí)現(xiàn)IUserService接口,在這個(gè)接口當(dāng)中定義了如何獲取用戶信息等相關(guān)操作,這個(gè)接口的源碼如下:
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;
public interface IUserService extends UserDetailsService {
public static final String BEAN_ID="bdf2.userService";
void loadPageUsers(Page<IUser> page,String companyId,Criteria criteria);
Collection<IUser> loadUsersByDeptId(String deptId);
String checkPassword(String username,String password);
void changePassword(String username,String newPassword);
void registerAdministrator(String username,String cname,String ename,String password,String
email,String mobile,String companyId);
*/
IUser newUserInstance(String username);
}
接口中每個(gè)方法都有詳細(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;
}
}
}
在這個(gè)接口實(shí)現(xiàn)當(dāng)中,我們采用的是JdbcDao實(shí)現(xiàn)從demo_user表中獲取用戶信息,這其中我們保持checkPassword、changePassword與registerAdministrator三個(gè)方法為空,那么對應(yīng)頁面當(dāng)中用戶密碼修改及注冊系統(tǒng)管理員兩塊功能就不能正常使用,您可以去實(shí)現(xiàn)一把。
再次,我們還需要實(shí)現(xiàn)IFrameworkService接口,這個(gè)接口比較簡單,其中只有一個(gè)方法需要我們實(shí)現(xiàn),這個(gè)方法的作用是處理用戶登錄時(shí)用戶密碼驗(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");
}
}
}
可以看到,代碼比較簡單,就是判斷用戶密碼是否正確,如果不正確拋出一個(gè)BadCridentialsException即可。
上述三個(gè)接口實(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配置成一個(gè)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>
可以看到,這種配置更新簡單,只需要一行就可以搞定,但前提是這個(gè)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中插入一個(gè)用戶,啟動(dòng)我們應(yīng)用進(jìn)行登錄了。
更多建議: