当传入的属性有重复时,Struts2 会报
No result defined for action and result input
错误
Struts2 取得ServletContext环境
//ServletContext servletContext = (ServletContext) ActionContext.getContext().get(StrutsStatics.SERVLET_CONTEXT);
ServletContext servletContext=ServletActionContext.getServletContext();
ActionInvocation invocation=ActionContext.getContext().getActionInvocation();
System.out.println("Action:"+invocation.getAction().getClass().getName());
System.out.println("Struts2 中配置的Action:"+invocation.getProxy().getActionName());
System.out.println("Struts2 中配置的Action namespace :"+invocation.getProxy().getNamespace());
System.out.println("调用的方法:"+invocation.getProxy().getMethod();
取得Spring管理的applicationContext
ServletContext sc=sce.getServletContext();
ApplicationContext ac=WebApplicationContextUtils.getWebApplicationContext(sc);
PrivilegeService privilegeService = (PrivilegeService) ac.getBean("privilegeServiceImpl");
<!-- 解决Hibernate懒加载问题 --><filter><filter-name>hibernate4Filter</filter-name><filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class></filter><filter-mapping><filter-name>hibernate4Filter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
监听器是在服务器部署的时候进行实例化
<!-- Spring 容器初始化 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
自定义监听器代码
package david.oa.listener;import java.util.List;import javax.servlet.ServletContext;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import org.springframework.context.ApplicationContext;import org.springframework.web.context.support.WebApplicationContextUtils;import david.oa.domain.Privilege;import david.oa.service.PrivilegeService;public class InitServletContextListener implements ServletContextListener{ @Override public void contextDestroyed(ServletContextEvent arg0) { // TODO Auto-generated method stub } @Override public void contextInitialized(ServletContextEvent sce) { // 得到Service的实例对象 //确保是初始化时同一个Spring容器 ServletContext sc=sce.getServletContext(); ApplicationContext ac=WebApplicationContextUtils.getWebApplicationContext(sc); PrivilegeService privilegeService = (PrivilegeService) ac.getBean("privilegeServiceImpl"); List<Privilege> topPrivilegeList = privilegeService.findTopList(); sc.setAttribute("topPrivilegeList", topPrivilegeList); System.out.println("-- 已准备好顶级权限的数据 --"); List<String> allPrivilegeUrls = privilegeService.getAllPrivilegeUrls(); sc.setAttribute("allPrivilegeUrls", allPrivilegeUrls); System.out.println("-- 已准备好所有权限的URL数据 --"); }}
Hibernate中,当通过session取得的对象,一般属性会自动加载,无论是否设置为懒加载 lazy=“true”
例如
<
property name="name"
/> 这个属性会默认 加载
而对于关联属性例如 <many-to one > 或者<set> 这些属性当
lazy=“true”时是不会立刻加载的,只有当调用bean.getXxx()时才会加载
但是要注意调用getXxx()时是否还是同一个Hibernate session
例如User 中有Roles 这个属性,我把它设置为懒加载时
<set name="roles" table="user_role" lazy="true" > <key column="userId"></key> <many-to-many class="Role" column="roleId" order-by="id DESC"></many-to-many> </set>
然后我通过下面的Action 查询到一个user时 ,把它存到session作用域中,
public String list() throws Exception{ User user=(User)ActionContext.getContext().getSession().get("user"); if(user ==null){ user =userService.getById(3l); ActionContext.getContext().getSession().put("user",user); } return METHOD; }
然后在另外一个页面中用EL表达式取出,发现会报懒加载错误。因为此时的对象已经是托管状态。
Struts2 自定义表达式 ,把原来的源码复制出来,新建一个包名和类名一样的类,就可以覆盖原来的类,然后重写 doStartTag() 和doEenTag();
Struts2 拦截器
在struts.xml中
<interceptors><interceptor name="myStack" class="david.oa.intercetor.PrivilegeIntercetor"></interceptor><interceptor-stack name="defaultStack"><interceptor-ref name="defaultStack"/><interceptor-ref name="myStack"/></interceptor-stack></interceptors>
david.oa.intercetor.PrivilegeIntercetor 要继承
AbstractInterceptor
并重写
intercept方法
package david.oa.intercetor;import javax.annotation.Resource;import javax.servlet.Servlet;import javax.servlet.ServletContext;import org.apache.struts2.ServletActionContext;import org.apache.struts2.StrutsStatics;import org.springframework.context.ApplicationContext;import org.springframework.web.context.support.WebApplicationContextUtils;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.AbstractInterceptor;import david.oa.domain.User;import david.oa.service.UserService;import david.oa.service.impl.UserServiceImpl;public class PrivilegeIntercetor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { User user = (User) ActionContext.getContext().getSession().get("user"); String actionName = invocation.getProxy().getActionName(); String namespace = invocation.getProxy().getNamespace(); String url = actionName; if (namespace.endsWith("/")) { url = namespace + actionName; } else { url = namespace + "/" + actionName; } // 要去掉开头的'/' if (url.startsWith("/")) { url = url.substring(1); } if (user == null) { if (url.startsWith("userAction_login")) { // 正在登陆的路上 return invocation.invoke(); } else { return "toLogin"; } } if (url.startsWith("userAction_login")) { return "homeIndex"; } //ServletContext servletContext = (ServletContext) ActionContext.getContext().get(StrutsStatics.SERVLET_CONTEXT); ServletContext servletContext=ServletActionContext.getServletContext(); ApplicationContext ac=WebApplicationContextUtils.getWebApplicationContext(servletContext); UserService userService=(UserService) ac.getBean("userServiceImpl"); user = userService.getById(user.getId()); if (user.hasPrivilege(url)) { // 已经登陆,则判断权限 return invocation.invoke(); } return "noPrivilege"; }}
hibernate.xml 中
<property name
=
"format_sql">
true
</property>
可以格式化生成的sql语句
本文详细阐述了如何解决Struts2框架与Hibernate持久层框架集成时出现的错误,包括配置ServletContext环境、获取Spring管理的ApplicationContext、处理权限服务与监听器的初始化。同时讨论了在使用Hibernate时遇到的懒加载问题及其解决方案,以及Struts2自定义表达式的实现方法。此外,还介绍了如何在Struts2中配置拦截器以实现权限检查。
402

被折叠的 条评论
为什么被折叠?



