1. 项目背景与核心需求
扬州作为中国历史文化名城,拥有丰富的旅游资源和文化底蕴。这个基于S2SH框架的旅游宣传网站项目,正是针对当前旅游信息化需求而设计的毕业设计解决方案。从技术角度来看,这类项目实际上包含了三个维度的价值:
对于计算机专业学生而言,S2SH(Struts2 + Spring + Hibernate)框架组合是Java Web开发中的经典技术栈,能够全面锻炼学生的系统设计能力和编码实践水平。这个技术组合在2010-2018年间被广泛应用于企业级应用开发,虽然现在有更多现代化框架可选,但作为教学项目仍然具有很好的学习价值。
从旅游行业需求侧来看,地方旅游宣传网站需要解决几个核心痛点:景点信息的可视化展示、旅游线路的智能推荐、用户互动体验的提升以及后台管理的便捷性。一个合格的旅游网站应该能够实现信息的动态更新、多维度展示和个性化推送。
技术实现上,S2SH框架的分层架构非常适合这类中型Web应用。Struts2负责表现层和控制流,Spring管理业务逻辑和依赖注入,Hibernate处理数据持久化。这种分工明确的架构使得系统具有较好的可维护性和扩展性。
提示:在实际开发中,很多同学容易陷入"为了用框架而用框架"的误区。建议先明确业务需求,再选择技术方案,而不是反过来。
2. 技术架构设计与实现
2.1 系统分层架构
典型的S2SH应用采用四层架构设计:
-
表现层:使用Struts2框架处理HTTP请求和响应
- 配置struts.xml定义action映射
- 采用JSP+EL+JSTL实现视图渲染
- 可配合Bootstrap等前端框架提升UI体验
-
业务层:Spring框架管理的Service组件
java复制@Service public class AttractionServiceImpl implements AttractionService { @Autowired private AttractionDAO attractionDAO; public List<Attraction> getTopAttractions(int limit) { return attractionDAO.findTop(limit); } } -
持久层:Hibernate实现的DAO组件
java复制@Repository public class AttractionDAOImpl extends HibernateDaoSupport implements AttractionDAO { public List<Attraction> findTop(int limit) { return getHibernateTemplate() .createQuery("FROM Attraction ORDER BY visitCount DESC") .setMaxResults(limit) .list(); } } -
数据库层:MySQL关系型数据库
- 设计规范的ER图
- 合理设置索引提升查询性能
2.2 核心功能模块实现
2.2.1 景点信息管理模块
这是系统的核心模块,需要实现:
- 景点CRUD操作
- 多条件组合查询
- 分页显示功能
- 图片上传与展示
Struts2配置示例:
xml复制<action name="attraction_*" method="{1}" class="attractionAction">
<result name="success">/WEB-INF/pages/attraction/{1}.jsp</result>
<interceptor-ref name="fileUpload">
<param name="maximumSize">5242880</param>
</interceptor-ref>
</action>
2.2.2 旅游路线推荐模块
实现智能推荐算法:
java复制public List<TourRoute> recommendRoutes(UserPreference preference) {
// 基于用户偏好和景点热度进行加权计算
Criteria criteria = sessionFactory.getCurrentSession()
.createCriteria(TourRoute.class)
.add(Restrictions.eq("season", preference.getSeason()))
.addOrder(Order.desc("popularity"))
.setMaxResults(5);
return criteria.list();
}
2.2.3 用户评论互动模块
采用AJAX实现无刷新提交:
javascript复制$('#comment-form').submit(function(e) {
e.preventDefault();
$.post('comment_add.action', $(this).serialize(), function(data) {
$('#comments-container').prepend(data);
});
});
3. 开发环境搭建与配置
3.1 基础环境准备
- JDK 1.8+ (建议使用Oracle JDK)
- Eclipse/IDEA开发工具
- Tomcat 8.5+应用服务器
- MySQL 5.7数据库
- Maven 3.6+项目管理
3.2 S2SH框架整合关键步骤
- 创建Maven项目并添加依赖:
xml复制<!-- Struts2核心 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.5.30</version>
</dependency>
<!-- Spring整合 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.18</version>
</dependency>
<!-- Hibernate核心 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.7.Final</version>
</dependency>
- 配置web.xml:
xml复制<!-- Spring监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Struts2过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
- Spring与Hibernate整合配置applicationContext.xml:
xml复制<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
注意:在实际配置中,数据库连接参数应放在单独的properties文件中,不要硬编码在XML里。
4. 典型业务场景实现
4.1 景点详情页的实现
这是一个综合性的功能点,涉及:
- Action处理请求:
java复制public class AttractionAction extends ActionSupport {
private Integer id;
private Attraction attraction;
public String execute() {
attraction = attractionService.getById(id);
if(attraction == null) {
return ERROR;
}
return SUCCESS;
}
// getters & setters
}
- Service层业务逻辑:
java复制@Override
@Transactional
public Attraction getById(Integer id) {
Attraction attraction = attractionDAO.get(id);
// 增加访问计数
attraction.setViewCount(attraction.getViewCount() + 1);
attractionDAO.update(attraction);
return attraction;
}
- JSP页面展示:
jsp复制<div class="attraction-header">
<h1>${attraction.name}</h1>
<div class="rating">
<c:forEach begin="1" end="${attraction.rating}">
<span class="star">★</span>
</c:forEach>
</div>
</div>
<div class="gallery">
<c:forEach items="${attraction.images}" var="image">
<img src="${ctx}/uploads/${image}" class="thumbnail">
</c:forEach>
</div>
4.2 旅游路线规划算法
基于用户选择的偏好参数(时间、预算、兴趣点等)生成个性化路线:
java复制public List<TourRoute> generateRoutes(RouteCriteria criteria) {
// 1. 基础过滤
Criteria hibernateCriteria = session.createCriteria(TourRoute.class)
.add(Restrictions.le("duration", criteria.getMaxDays()))
.add(Restrictions.le("totalCost", criteria.getMaxBudget()));
// 2. 兴趣点加权
if (!criteria.getInterests().isEmpty()) {
Disjunction or = Restrictions.disjunction();
for (String interest : criteria.getInterests()) {
or.add(Restrictions.like("tags", "%" + interest + "%"));
}
hibernateCriteria.add(or);
}
// 3. 排序策略
if ("cost".equals(criteria.getSortBy())) {
hibernateCriteria.addOrder(Order.asc("totalCost"));
} else {
hibernateCriteria.addOrder(Order.desc("popularity"));
}
return hibernateCriteria.list();
}
5. 项目部署与优化建议
5.1 生产环境部署要点
-
Tomcat优化配置:
- 调整server.xml中的连接器参数
- 配置JVM内存参数(-Xms512m -Xmx1024m)
- 启用GZIP压缩
-
数据库优化:
sql复制-- 为常用查询字段创建索引 CREATE INDEX idx_attraction_name ON attraction(name); CREATE INDEX idx_attraction_rating ON attraction(rating); -- 定期执行分析表 ANALYZE TABLE attraction; -
前端性能优化:
- 合并压缩CSS/JS文件
- 使用CDN托管静态资源
- 实现图片懒加载
5.2 常见问题解决方案
问题1:Struts2与Spring整合后Action无法注入Service
解决方案:
- 确保Action类在Spring配置中声明为prototype作用域
xml复制<bean id="attractionAction" class="com.yz.action.AttractionAction" scope="prototype">
<property name="attractionService" ref="attractionService"/>
</bean>
- 在struts.xml中配置action时使用Spring管理的bean
xml复制<action name="attraction_*" class="attractionAction" method="{1}">
问题2:Hibernate懒加载异常
解决方案:
- 在web.xml中添加OpenSessionInViewFilter
xml复制<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>
- 或者在Service层预先加载关联对象
java复制@Transactional
public Attraction getDetailById(Integer id) {
Attraction a = getById(id);
// 强制初始化代理对象
Hibernate.initialize(a.getComments());
return a;
}
6. 毕业设计扩展建议
-
技术扩展方向:
- 引入Redis缓存热门景点数据
- 增加Elasticsearch实现全文搜索
- 使用Quartz实现定时任务(如每日访问统计)
-
业务功能扩展:
- 增加虚拟旅游(3D全景展示)
- 实现智能客服系统
- 开发微信小程序端
-
文档完善建议:
- 绘制详细的系统架构图
- 补充数据库设计文档
- 编写完整的测试用例
我在指导类似项目时发现,很多同学在开发后期才考虑文档问题,导致答辩时准备不足。建议采用"开发即文档"的方式,使用Swagger等工具自动生成API文档,同时保持代码注释的及时更新。对于LW文档,要特别注意格式规范,包括目录结构、图表编号、参考文献等细节。
