U8Framework4SSH ——開源了一套SSH2(Struts2+Spring+Hibernate)整合框架
U8Framework4SSH
U8Server中使用的SSH2(Struts2+Spring3+Hibernate4)框架,包括U8Server整合好的配置檔案,以及抽象出來的一些通用元件,使得基於J2EE框架開發的同學可以快速展開工作。
U8Server是U8SDK統一渠道SDK接入框架的伺服器端。U8Server採用成熟的SSH2(J2EE框架)研發。效能可靠,結構簡單。
採用SSH2框架研發的專案,開發其實很簡單。主要就是框架的整合和搭建,需要花費點時間。問題主要集中在配置方式和框架的使用。
之前很多同學在問U8Server採用的配置和整個框架,往往就敗在了框架整合上面。這裡,我們將U8Server採用的框架和配置開源出來。需要採用SSH2研發的專案,可以直接在該框架基礎上進行,免去了從頭配置的繁瑣。
整個框架,基於MVC思想模式,同時所有配置通過註解進行。避免通過配置檔案配置帶來的繁瑣和複雜。
依賴Jar包:
lib/jars目錄下為SSH2框架所依賴的一些jar包。新增新的jar包注意,不要導致jar包衝突。
框架配置說明:
applicationContext.xml:Spring容器的配置,所有的元件管理和依賴注入(IOC)都由Spring管理,基本固定,不用修改
jdbc.properties:資料庫相關配置,在這裡修改資料庫連線資訊即可
log4j.properties:日誌配置,基本固定,不用修改
struts.xml:struts2的配置,因為我們採用註解配置方式,所以該檔案配置很少,而且固定
WEB-INF\web.xml:這個是web專案的固定配置,需要配置struts2,spring,hibernate等的過濾器和監聽器等。基本固定,不用修改
原始碼目錄(根目錄為com.u8.server):
- cache/ :快取相關類目錄。U8Server中對遊戲物件,渠道物件,渠道商物件進行了快取
- common/ :該目錄下為U8Server對SSH2框架的一個簡單封裝
- dao/ :MVC模式典型的DAO層(資料訪問層)
- data/ :資料物件
- filters/:struts2過濾器,比如後臺管理操作,需要登入使用者和擁有相關許可權的使用者才能進行,通過過濾器來攔截
- log/ :日誌目錄
- service/:MVC模式典型的Service層(業務邏輯層)
- utils/ :常用輔助工具類
- web/ :MVC模式典型的Web層,這裡寫struts2的Action
框架使用:
比如現在需要開發一個使用者管理系統,
1、我們會抽象出來一個User物件。那麼在data目錄下,新建一個UUser物件:
/**
* 使用者資料物件
* 約定:所有欄位的名稱,都需要和資料庫表格中的欄位名稱一致
*/
@Entity //說明該物件為一個數據類
@Table(name = "uuser") //該資料庫和資料庫中某張表格一一對應。name為資料庫表的名稱
public class UUser {
@Id //說明該欄位為主鍵
@GeneratedValue(strategy = GenerationType.IDENTITY) //主鍵生成方式,這裡自動遞增。具體其他方式,自行查閱資料瞭解
private int id;
private int appID;
private int channelID;
private String name;
private String channelUserID;
private String channelUserName;
private String channelUserNick;
private Date createTime;
private Date lastLoginTime;
private String token;
public JSONObject toJSON(){
JSONObject json = new JSONObject();
json.put("id", id);
json.put("appID", appID);
json.put("channelID", channelID);
json.put("name", name);
json.put("channelUserID", channelUserID);
json.put("channelUserName", channelUserName);
json.put("channelUserNick", channelUserNick);
return json;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAppID() {
return appID;
}
public void setAppID(int appID) {
this.appID = appID;
}
public int getChannelID() {
return channelID;
}
public void setChannelID(int channelID) {
this.channelID = channelID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getChannelUserID() {
return channelUserID;
}
public void setChannelUserID(String channelUserID) {
this.channelUserID = channelUserID;
}
public String getChannelUserName() {
return channelUserName;
}
public void setChannelUserName(String channelUserName) {
this.channelUserName = channelUserName;
}
public String getChannelUserNick() {
return channelUserNick;
}
public void setChannelUserNick(String channelUserNick) {
this.channelUserNick = channelUserNick;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getLastLoginTime() {
return lastLoginTime;
}
public void setLastLoginTime(Date lastLoginTime) {
this.lastLoginTime = lastLoginTime;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}
2、有了UUser物件之後,我們需要對該物件進行一些操作。首先就是資料訪問,我們需要從資料庫中獲取到該物件對應的資料表,所以,我們在dao目錄下新建一個UUserDao類,作為UUser物件的資料訪問類。所有Dao資料訪問類都繼承UHibernateTemplate。這個抽象類有兩個泛型引數。第一個是當前資料訪問類需要訪問的資料物件,第二個引數是當前資料物件的主鍵型別
注意:所有資料訪問類,都需要使用@Repository註解來宣告,括號裡面的名稱為後面其他地方申明該類的物件時所必須使用的名稱。
/**
* 使用者資料訪問類
*/
@Repository("userDao")
public class UUserDao extends UHibernateTemplate<UUser, Integer>{
//data operate
}
3、有了UUserDao,我們還需要在service目錄下新建一個UUserManager作為UUser物件的業務操作類。
注意:所有業務操作類,都必須使用@Service註解來宣告,括號裡面的名稱為後面其他地方申明該類的物件時所必須使用的名稱。
/**
* 這裡處理UUser相關的邏輯操作
*/
@Service("userManager")
public class UUserManager {
@Autowired //使用Autowired註解來宣告,採用Spring依賴注入來自動例項化該物件。
private UUserDao userDao; //這裡變數的名稱必須為userDao和上面@Repository宣告該類時,指定的名稱一致
//根據渠道使用者ID獲取使用者資訊
public UUser getUserByCpID(int appID, int channelID, String cpUserID){
String hql = "from UUser where appID = ? and channelID = ? and channelUserID = ?";
return (UUser)userDao.findUnique(hql, appID, channelID, cpUserID);
}
//獲取指定渠道下的所有使用者
public List<UUser> getUsersByChannel(int channelID){
String hql = "from UUser where channelID = ?";
return userDao.find(hql, new Object[]{channelID}, null);
}
//分頁查詢
public Page<UUser> queryPage(int currPage, int num){
PageParameter page = new PageParameter(currPage, num, true);
OrderParameters order = new OrderParameters();
order.add("id", OrderParameter.OrderType.DESC);
String hql = "from UUser";
return userDao.find(page, hql, null, order);
}
public UUser getUser(int userID){
return userDao.get(userID);
}
public void saveUser(UUser user){
userDao.save(user);
}
public void deleteUser(UUser user){
userDao.delete(user);
}
}
4、有了UUser相關的資料物件和業務操作之後,我們需要一個控制器,來控制URL的訪問,引數解析驗證,呼叫業務層的邏輯進行處理,然後返回給客戶端對應的結果。我們在web目錄下,新建一個UserAction類。
注意:所有的Action類,都必須繼承UActionSupport類。UActionSupport是common目錄下,對struts2的一個簡單的封裝。
如果需要該Action採用資料驅動方式傳遞引數,那麼還要實現ModelDriven介面。
建議,將同一個業務的方法寫在一個Action類中。比如這裡User物件的操作。增刪改查等操作,都在該類中
@Controller //所有Action都加上Controller註解
@Namespace("/users") //根據業務區分Namespace,用Namespace主要防止命名衝突,並格式規範URL
public class UserAction extends UActionSupport implements ModelDriven<UUser>{
private int page; //當前請求的頁碼
private int rows; //當前每頁顯示的行數
private UUser user;
private int currUserID;
@Autowired
private UUserManager userManager;
//http://localhost:8080/users/showUsers
//訪問這個地址,會訪問到WEB-INF/admin/users.jsp
@Action(value = "showUsers",
results = {@Result(name = "success", location = "/WEB-INF/admin/users.jsp")})
public String showUsers(){
return "success";
}
//http://localhost:8080/users/getAllUsers
@Action("getAllUsers")
public void getAllUsers(){
try{
Page<UUser> currPage = this.userManager.queryPage(page, rows);
JSONObject json = new JSONObject();
json.put("total", currPage.getTotalCount());
JSONArray users = new JSONArray();
for(UUser m : currPage.getResultList()){
users.add(m.toJSON());
}
json.put("rows", users);
renderJson(json.toString());
}catch(Exception e){
e.printStackTrace();
}
}
//新增或者編輯
//http://localhost:8080/users/saveUser
@Action("saveUser")
public void saveUser(){
try{
userManager.saveUser(this.user);
renderState(true);
return;
}catch(Exception e){
e.printStackTrace();
}
renderState(false);
}
//http://localhost:8080/users/removeUser
@Action("removeUser")
public void removeUser(){
try{
Log.d("Curr userID is " + this.currUserID);
UUser user = userManager.getUser(this.currUserID);
if(user == null){
renderState(false);
return;
}
userManager.deleteUser(user);
renderState(true);
return;
}catch(Exception e){
e.printStackTrace();
}
renderState(false);
}
private void renderState(boolean suc){
JSONObject json = new JSONObject();
json.put("state", suc? 1 : 0);
json.put("msg", suc? "操作成功" : "操作失敗");
renderText(json.toString());
}
@Override
public UUser getModel() {
if(this.user == null){
this.user = new UUser();
}
return this.user;
}
public UUser getUser() {
return user;
}
public void setUser(UUser user) {
this.user = user;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getCurrUserID() {
return currUserID;
}
public void setCurrUserID(int currUserID) {
this.currUserID = currUserID;
}
}
開發SSH2專案,建議使用IntelliJ IDEA ,該框架也是基於該IDE開發的。如果是其他IDE,可能需要手動轉換並重新配置下。