Spring MVC、Spring Security 和 Hibernate 无法在上下文之间自动装配属性

发布于 2024-12-18 19:21:19 字数 2948 浏览 1 评论 0原文

我正在使用 Spring MVC 3.0.6 和 Spring security 3.0.7。在安全上下文中时,我无法将 RoleDao 类 @Autowire 到我的用户类。

我的 web.xml 文件:

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/root-context.xml
        /WEB-INF/security-app-context.xml
    </param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Processes application requests -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>



<filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

security-app-context.xml:

<beans:bean id="chineseCheckersEntryPoint" class="com.nike.golf.security.ChineseCheckersAuthenticationEntryPoint" />

<beans:bean id="chineseCheckersFilter" class="com.nike.golf.security.ChineseCheckersAuthenticationFilter">
    <beans:property name="authenticationManager" ref="authenticationManager"/>
</beans:bean>

<http use-expressions="true" auto-config="false" entry-point-ref="chineseCheckersEntryPoint">
    <intercept-url pattern="/secure/extreme/**" access="hasRole('supervisor')" />
    <intercept-url pattern="/user/**" access="permitAll" />
    <intercept-url pattern="/profile/**" access="isAuthenticated()" />
    <intercept-url pattern="/secure/**" access="isAuthenticated()" />
    <custom-filter position="PRE_AUTH_FILTER" ref="chineseCheckersFilter" />
</http>

<authentication-manager alias="authenticationManager">
    <authentication-provider ref="chineseCheckersAuthenticationProvider" />
</authentication-manager>

<beans:bean id="chineseCheckersAuthenticationProvider" class="com.nike.golf.security.ChineseCheckersAuthenticationProvider" />

在我使用 roleDao 的用户对象中,它为空。它尚未自动连接。从我在网上完成的所有研究来看,它似乎与不同的上下文有关,并且无法在它们之间自动连接。

有人可以帮助我理解这些上下文以及如何让它们进入相同的上下文吗?

I am using Spring MVC 3.0.6 and Spring security 3.0.7. I cannot @Autowire the RoleDao class to my user class when in the security context.

my web.xml file:

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/root-context.xml
        /WEB-INF/security-app-context.xml
    </param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Processes application requests -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>



<filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

The security-app-context.xml:

<beans:bean id="chineseCheckersEntryPoint" class="com.nike.golf.security.ChineseCheckersAuthenticationEntryPoint" />

<beans:bean id="chineseCheckersFilter" class="com.nike.golf.security.ChineseCheckersAuthenticationFilter">
    <beans:property name="authenticationManager" ref="authenticationManager"/>
</beans:bean>

<http use-expressions="true" auto-config="false" entry-point-ref="chineseCheckersEntryPoint">
    <intercept-url pattern="/secure/extreme/**" access="hasRole('supervisor')" />
    <intercept-url pattern="/user/**" access="permitAll" />
    <intercept-url pattern="/profile/**" access="isAuthenticated()" />
    <intercept-url pattern="/secure/**" access="isAuthenticated()" />
    <custom-filter position="PRE_AUTH_FILTER" ref="chineseCheckersFilter" />
</http>

<authentication-manager alias="authenticationManager">
    <authentication-provider ref="chineseCheckersAuthenticationProvider" />
</authentication-manager>

<beans:bean id="chineseCheckersAuthenticationProvider" class="com.nike.golf.security.ChineseCheckersAuthenticationProvider" />

In my user object where it uses the roleDao, it's null. It has not been autowired. From all the research I have done online it seems to be related to the different contexts, and not being able to autowire between them.

Can someone help me understand these contexts and how I can get them into the same context?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

那支青花 2024-12-25 19:21:19

谢谢大家的帮助。我设法弄清楚了这一点。

这个问题与我的类似,让我朝着正确的方向前进:
在父上下文与子上下文中声明 Spring Bean

论坛帖子确实简化了我的想法。

在 web.xml 文件中,您定义 servlet 上下文和应用程序上下文。
应用程序上下文是通过这些 XML 片段进行配置的:

<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/root-context.xml
        /WEB-INF/security-app-context.xml
    </param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

传递到 context-param > 的任意数量的 *context.xml 文件。 contextConfigLocation 位于应用程序上下文中。这是父上下文。

servlet 上下文是通过以下 xml 在 web.xml 文件中创建的:

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

servlet 上下文作为子上下文可以访问应用程序上下文(父上下文)。

这是我理解的关键。因此,我将 servlet 上下文中的所有配置移至应用程序上下文。

就像我上面链接的另一个问题的答案一样,@Autowired 仍然不起作用。有人知道其中的原因吗?
因此,为了解决这个问题,我在 xml 中定义了从我关心的属性到 sessionFactory 的 bean 和属性。

现在的问题是,我可以将 xml 中所需的 bean 沿着层次结构一直连接到 sessionFactory,因为它位于相同的上下文中,因为我将它从之前所在的 servlet 上下文移至应用程序上下文。

在我的问题中,我什至没有发布 servlet-context.xml 文件,因为我认为不需要触及它,但事实上,如果我想将东西连接到,我需要将配置移动到应用程序上下文我的安全豆。

我希望这是有道理的。

Thank you everyone for your help. I managed to figure this out.

This question was similar to mine and got me moving in the right direction:
Declaring Spring Bean in Parent Context vs Child Context

This forum post really simplified the idea for me.

In your web.xml file you define the servlet context and the application context.
The application context is configured through these pieces of XML:

<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/root-context.xml
        /WEB-INF/security-app-context.xml
    </param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

any number of *context.xml files you pass into the context-param > contextConfigLocation are in the application context. This is the parent context.

The servlet context gets created in the web.xml file by this bit of xml:

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

The servlet context as the child context has access to the application context (parent).

This was the key thing for me to understand. So I moved all configuration I had in the servlet context, up to the application context.

Like the answer in the other question I linked to above says @Autowired still does not work. Anyone know the reason for that?
So to get around this I defined the beans and the properties in the xml all the way from the property I was concerned with down to the sessionFactory.

The thing is now I could wire up the beans I needed in xml all the way up the hierarchy to sessionFactory because it was in the same context, since I moved it up to the application context from the servlet context where it was before.

In my question I didn't even post the servlet-context.xml file because I didn't think it needed to be touched, but in fact I needed to move the configuration up to the app context if I wanted to wire things up to my security beans.

I hope that makes sense.

如痴如狂 2024-12-25 19:21:19

您可以将上下文想象为一组 Spring bean。

上下文可以嵌套,以便外部上下文可以从内部上下文访问 bean,但反之则不行。典型的 Web 应用程序就是一个示例,它有两个上下文:内部上下文使用 contextConfigLocation 指定并由 ContextLoaderListener 加载,外部上下文使用 配置DispatcherServlet

将两个 xml 文件合并到一个上下文的一种方法是引入第三个应用程序配置 xml 文件,该文件仅通过 bean:include 包含其他 xml 文件。然后您只需为加载程序指定第三个 xml 文件。 但我不确定您是否真的为 ContextLoaderListener 配置了 2 个应用程序上下文。 -- 无论如何,您可以尝试使用 3.xml 文件的技巧。

You can imagine a context as a set of Spring beans.

Contexts can be nested, so that the outer context can access the beans from the inner one, but not the other way around. An example for this are typical web application, the have two contexts: the inner one specified with the contextConfigLocation and loaded by ContextLoaderListener, and the outer one configured with the DispatcherServlet.

One way to merge two xml files to one context, is introducing a third apllication configuration xml file, that only include then other xml files via bean:include. And then you have only to specify this third xml files for the loader. But I am not sure if you really have 2 application contexts configured for ContextLoaderListener. -- Anyway you can try the trick with the 3. xml file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文