- 目的
以项目为驱动,学习Struts2+Spring+Hibernate的基本知识点。
- 项目介绍
影视网demo网站,前端布局boostrap+js,后端Struts2+Spring,持久化层Hibernate、数据库mysql+redis;
实现功能:用户登录注册、我喜欢、搜索、分页、layui列表;
主要知识点:
- 拦截器,比如用户在未登录状态下点击“喜欢”,将会被拦截请求,通过判断来进一步后续操作;
- Spring的自动装配和注解,Spring的高效原因之一就是首次加载项目时就配置好所需的基本环境,比如Action类和组件;
- 使用getHibernateTemplate()实现对数据库对操作;
需要说明的是,“我喜欢”这个功能是用redis和mysql联合实现,原因是对于用户每次添加喜欢对影片,如果对每个用户都建立一张‘我喜欢’的表,或者建立一张所有用户‘我喜欢’的表,其效率将会大打折扣,而采用redis,每个用户只是一个key。
- 项目效果
- S2SH的整合说明
对于S2SH的整合,其关键就是spring和struts、spring和hibernate的整合。
对于hibernate来说,其所需要完成的只是加载所有bean映射,以及一些琐碎的属性设置,而数据库的连接交给spring;
对于Struts来说,它将所需要的action类交给spring加载,根据spring配置的id进行查找以便完成动作流程;
基本上剩下的工作都将交给spring,它的职责包括:数据库的连接、事务和session的创建和配置(以便dao类获取使用),action类的映射以及action、service和dao包内的各大组件的注解和自动装配;
- 主要的配置文件
包括bean.xml、struts.xml、hibernate.xml和web.xml;
- 比较重要的知识点
- Struts返回json,需要在action里配置有gettter方法的变量,在Struts.xml中要如此配置
<package name="movie" extends="json-default">
<action name="mListAction-findAll" class="mListAction" method="findAll" >
<result name="success" type="json">
<!-- 这里指定将被Struts2序列化的属性,该属性在action中必须有对应的getter方法 -->
<param name="root">jsonResult</param>
<!-- 指定是否序列化值为空的属性 -->
<param name="excludeNullProperties">true</param>
</result>
</action>
</package>
- 关于拦截器
所谓的拦截器,其实就是做这个action之前将其拦截下来,做身份验证之类,再根据其合法与否进行下一步动作;
public class loginStatusInterceptor extends AbstractInterceptor{
@Override
public String intercept(ActionInvocation invocation) throws Exception {
Map session=invocation.getInvocationContext().getSession();
if (session.get("username")==null) {
return Action.LOGIN;
}else {
//表示执行成功,继续下一个拦截器或action
return invocation.invoke();
}
}
}
在Struts中调用拦截器
<!-- 拦截器 -->
<interceptors>
<interceptor name="loginStatus" class="com.jackpon.interceptor.loginStatusInterceptor"></interceptor>
<!-- 拦截栈 -->
<interceptor-stack name="iloginStatus">
<!-- defaultStack一定要写,不然无法传参数 -->
<interceptor-ref name="defaultStack" />
<interceptor-ref name="loginStatus" />
</interceptor-stack>
</interceptors>
<action name="like-add" class="likeAction" method="add">
<result>/WEB-APP/like-success.jsp</result>
<!-- 调用拦截器 -->
<interceptor-ref name="iloginStatus"></interceptor-ref>
<result name="login">/WEB-APP/like-error.jsp</result>
</action>
- IoC
要实现自动装配,dao类就要获取到spring生成的session,要做到这一步,dao类只需要继承类SuperDao,当然要添加组件注解才能被spring扫描,代码如下
@Component
public class SuperDAO extends HibernateDaoSupport {
@Resource(name="sessionFactory")
public void setSuperSessionFactory(SessionFactory sessionFactory) {
super.setSessionFactory(sessionFactory);
}
}
接下来,你只需要在dao类添加’@Component(name)‘注解,在service和action里为需要的变量添加’@Autowired’。
完成这一系列的操作,其目的就是为了实现IoC(控制反转)或者叫做DI(依赖注入),什么是控制反转?简单来说就是:
在传统的程序设计中,当调用者需要被调用者的协助时,通常由调用者来创建被调用者的实例。但在spring里创建被调用者的工作不再由调用者来完成,因此控制反转(IoC);创建被调用者实例的工作通常由spring容器来完成,然后注入调用者,因此也被称为依赖注入(DI),依赖注入和控制反转是同一个概念。
- 分页实现
思路:
客户端每次传输当前page过来,后台action根据默认要获取的数量结合当前page,去数据库获取指定的数据;至于下方的页面跳转按钮,需要做进一步判断:- 计算页面总数
- 判断两边的前后按钮是否可按
- 如果是当前页面则不可按,其他可以
public String ilist() throws Exception{
int current_page=getPage();
List<Movies> list =hibernateDao.getAllMovies(current_page);
ActionContext context=ActionContext.getContext();
int pages=hibernateDao.MoviesCount();
if(pages%Movies.PAGE_SIZE==0){
pages=pages/Movies.PAGE_SIZE;
}else {
pages=pages/Movies.PAGE_SIZE+1;
}
StringBuffer s=new StringBuffer();
if(current_page==1){
s.append("<li class='page-item disabled'><a class='page-link' href='#' tabindex='-1'>Previous</a></li>");
}else {
s.append("<li class='page-item'><a class='page-link' href='mList-ilist?page="+(current_page-1)+"' tabindex='-1'>Previous</a></li>");
}
for(int i=1;i<=pages;i++){
if(i==current_page){
s.append("<li class='page-item disabled'><a class='page-link' href='mList-ilist?page="+i+"'>"+i+"</a></li>");
}
else{
s.append("<li class='page-item'><a class='page-link' href='mList-ilist?page="+i+"'>"+i+"</a></li>");
}
}
if(current_page==pages){
s.append("<li class='page-item disabled'><a class='page-link' href='#' tabindex='-1'>Next</a></li>");
}else {
s.append("<li class='page-item'><a class='page-link' href='mList-ilist?page="+(current_page+1)+"' tabindex='-1'>Next</a></li>");
}
context.put("s",s);
context.put("list", list);
return SUCCESS;
}