你在action中可以得到session是因为是servlet-config这个拦截器给它注入的 因为你的action实现了SessionAware接口,实现它是为了在执行action的execute或其它方法之前,用setSession()方法注入。就是说是servlet-config这个拦截器调用的action,并在调用之前注入了。 而你的dao之所以获取不到session,是因为你的dao是直接new出来的,不是由那个拦截器调用的,即使实现了接口,但没有人会通过setSession()方法注入session,而且这个session必须是tomcat容器给过来的,而你的dao跟servlet没有一点关系,action却有。所以获取不到session。 看源码: org.apache.struts2.interceptor.ServletConfigInterceptor if (action instanceof SessionAware) { ((SessionAware) action).setSession(context.getSession()); }这里调用了SessionAware接口里的setSession方法public class ServletConfigInterceptor extends AbstractInterceptor implements StrutsStatics { private static final long serialVersionUID = 605261777858676638L; /** * Sets action properties based on the interfaces an action implements. Things like application properties, * parameters, session attributes, etc are set based on the implementing interface. * * @param invocation an encapsulation of the action execution state. * @throws Exception if an error occurs when setting action properties. */ public String intercept(ActionInvocation invocation) throws Exception { final Object action = invocation.getAction(); final ActionContext context = invocation.getInvocationContext(); if (action instanceof ServletRequestAware) { HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST); ((ServletRequestAware) action).setServletRequest(request); } if (action instanceof ServletResponseAware) { HttpServletResponse response = (HttpServletResponse) context.get(HTTP_RESPONSE); ((ServletResponseAware) action).setServletResponse(response); } if (action instanceof ParameterAware) { ((ParameterAware) action).setParameters((Map)context.getParameters()); } if (action instanceof ApplicationAware) { ((ApplicationAware) action).setApplication(context.getApplication()); }
if (action instanceof SessionAware) { ((SessionAware) action).setSession(context.getSession()); }
if (action instanceof RequestAware) { ((RequestAware) action).setRequest((Map) context.get("request")); } if (action instanceof PrincipalAware) { HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST); if(request != null) { // We are in servtlet environment, so principal information resides in HttpServletRequest ((PrincipalAware) action).setPrincipalProxy(new ServletPrincipalProxy(request)); } } if (action instanceof ServletContextAware) { ServletContext servletContext = (ServletContext) context.get(SERVLET_CONTEXT); ((ServletContextAware) action).setServletContext(servletContext); } return invocation.invoke(); } } 再看struts.xml里面的BasicStack <!-- Basic stack --> <interceptor-stack name="basicStack"> <interceptor-ref name="exception"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="prepare"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> </interceptor-stack> <interceptor-ref name="servletConfig"/>这个就是对刚才那个拦截器的引用 看struts.xml的声明 <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/> 所以你的action的方法总能由这个拦截器控制 在调用之前对当前action对象注入session打字不易 望给分
Dao继承BaseAction却不行,难道struts2用反射的方式调用setSession方法的时候还能判断出哪些是Action类哪些是其他类吗?
因为你的action实现了SessionAware接口,实现它是为了在执行action的execute或其它方法之前,用setSession()方法注入。就是说是servlet-config这个拦截器调用的action,并在调用之前注入了。
而你的dao之所以获取不到session,是因为你的dao是直接new出来的,不是由那个拦截器调用的,即使实现了接口,但没有人会通过setSession()方法注入session,而且这个session必须是tomcat容器给过来的,而你的dao跟servlet没有一点关系,action却有。所以获取不到session。
看源码:
org.apache.struts2.interceptor.ServletConfigInterceptor if (action instanceof SessionAware) {
((SessionAware) action).setSession(context.getSession());
}这里调用了SessionAware接口里的setSession方法public class ServletConfigInterceptor extends AbstractInterceptor implements StrutsStatics { private static final long serialVersionUID = 605261777858676638L; /**
* Sets action properties based on the interfaces an action implements. Things like application properties,
* parameters, session attributes, etc are set based on the implementing interface.
*
* @param invocation an encapsulation of the action execution state.
* @throws Exception if an error occurs when setting action properties.
*/
public String intercept(ActionInvocation invocation) throws Exception {
final Object action = invocation.getAction();
final ActionContext context = invocation.getInvocationContext(); if (action instanceof ServletRequestAware) {
HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
((ServletRequestAware) action).setServletRequest(request);
} if (action instanceof ServletResponseAware) {
HttpServletResponse response = (HttpServletResponse) context.get(HTTP_RESPONSE);
((ServletResponseAware) action).setServletResponse(response);
} if (action instanceof ParameterAware) {
((ParameterAware) action).setParameters((Map)context.getParameters());
} if (action instanceof ApplicationAware) {
((ApplicationAware) action).setApplication(context.getApplication());
}
if (action instanceof SessionAware) {
((SessionAware) action).setSession(context.getSession());
}
if (action instanceof RequestAware) {
((RequestAware) action).setRequest((Map) context.get("request"));
} if (action instanceof PrincipalAware) {
HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
if(request != null) {
// We are in servtlet environment, so principal information resides in HttpServletRequest
((PrincipalAware) action).setPrincipalProxy(new ServletPrincipalProxy(request));
}
}
if (action instanceof ServletContextAware) {
ServletContext servletContext = (ServletContext) context.get(SERVLET_CONTEXT);
((ServletContextAware) action).setServletContext(servletContext);
}
return invocation.invoke();
}
}
再看struts.xml里面的BasicStack <!-- Basic stack -->
<interceptor-stack name="basicStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
</interceptor-stack>
<interceptor-ref name="servletConfig"/>这个就是对刚才那个拦截器的引用
看struts.xml的声明
<interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
所以你的action的方法总能由这个拦截器控制 在调用之前对当前action对象注入session打字不易 望给分