專案結構規範
src/main/java
├── com.example.common // 通用層:基類、工具、異常、常量
├── com.example.entity // 實體類(POJO),對應數據庫表
├── com.example.dao // DAO 接口
├── com.example.dao.impl // DAO 實現 (extends HibernateDaoSupport)
├── com.example.service // Service 接口
├── com.example.service.impl // Service 實現 (事務邊界)
├── com.example.action // Struts2 Action (控制層)
├── com.example.interceptor // 自定義攔截器 (權限、日誌)
├── com.example.util // 工具類 (JSON、分頁、文件)
└── com.example.listener // Spring 監聽器、Servlet 監聽器
src/main/resources
├── spring
│ ├── applicationContext.xml // 總配置,引入子配置
│ ├── applicationContext-dao.xml // DataSource、SessionFactory、事務管理器
│ ├── applicationContext-service.xml // Service Bean、事務屬性 (AOP)
│ └── applicationContext-action.xml // Action Bean (prototype)
├── struts
│ ├── struts.xml // 總配置,引入模塊配置
│ ├── struts-default.xml
│ └── struts-action.xml // Action 映射
├── hibernate
│ ├── hibernate.cfg.xml // 可選,Spring 管理 SessionFactory 時可省略
│ └── mapping/*.hbm.xml // 實體映射文件(或註解)
└── log4j.properties / logback.xml
核心配置模塊化
<!-- applicationContext.xml -->
<import resource="applicationContext-dao.xml"/>
<import resource="applicationContext-service.xml"/>
<import resource="applicationContext-action.xml"/>
通用基類封裝(減少樣板代碼 80%+)
// DAO 基類
public class BaseDaoImpl extends HibernateDaoSupport implements BaseDao {
private Class entityClass;
public BaseDaoImpl() {
this.entityClass = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public void save(T entity) { getHibernateTemplate().save(entity); }
public void update(T entity) { getHibernateTemplate().update(entity); }
public void delete(Serializable id) { getHibernateTemplate().delete(get(id)); }
public T get(Serializable id) { return getHibernateTemplate().get(entityClass, id); }
public List findAll() { return getHibernateTemplate().loadAll(entityClass); }
// 分頁、HQL 條件查詢封裝...
}
// Service 基類
public abstract class BaseServiceImpl implements BaseService {
@Autowired protected BaseDao baseDao;
@Transactional(readOnly = true) public T get(Serializable id) { return baseDao.get(id); }
@Transactional public void save(T entity) { baseDao.save(entity); }
// 通用 CRUD 事務屬性統一聲明
}
// Action 基類
public class BaseAction extends ActionSupport implements ModelDriven {
protected T model = (T) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0].newInstance();
@Autowired protected BaseService baseService;
@Override public T getModel() { return model; }
// 通用 list/save/delete/input 跳轉方法
}
關鍵最佳實踐
| 領域 | 建議 |
| 事務管理 | Service 層聲明 @Transactional,DAO 無事務;使用 tx:annotation-driven + HibernateTransactionManager |
| Session 管理 | OpenSessionInViewFilter 解決懶加載異常,web.xml 配置 |
| 分頁 | 通用 PageBean + DAO 分頁方法,Action 接收 page/pageSize 參數 |
| 異常處理 | 全局異常攔截器 → 統一返回 JSON 錯誤碼/頁面 |
| 驗證 | Struts2 Validation + Hibernate Validator 註解雙重保障 |
| 配置外部化 | 數據庫連接、文件路徑、第三方 Key 放入 .properties,PropertyPlaceholderConfigurer 注入 |
避坑指南
- Action 必須
prototype 作用域,Service/Dao singleton。
- Hibernate 映射優先用註解 (
@Entity),複雜關係用 XML。
- Struts2
struts.devMode=false 生產環境。
- 定期
mvn dependency:analyze 清理無用依賴。
遵循分層解耦、配置模塊化、基類封裝三大原則,SSH 專案結構清晰、擴展性強、新人上手快。
- 上一篇文章: WCF MSMQ 服務動態添加端點無需重啟服務器:Self-Host 與配置熱加載
- 下一篇文章: 前端爬蟲數據獲取與入庫:AJAX 獲取 JSON → 後端 Controller 入庫完整鏈路
Copyright ©
程式碼之家 All Rights Reserved