gpt4 book ai didi

java - spring web, security + web.xml + mvc dispatcher + Bean 创建两次

转载 作者:IT老高 更新时间:2023-10-28 13:58:04 25 4
gpt4 key购买 nike

我的 Web.xml 如下:

 <servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</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>/api/secure/*</url-pattern>
</filter-mapping>

[编辑]

在我添加了 Spring 安全之后,我得到了错误!

java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?

然后我添加了

 <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

然后它似乎工作正常,但随后1)问题是bean被创建了两次!

如果我只删除它:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml
</param-value>
</context-param>

但留下 <listener>那么 Web 应用程序根本不会运行

[额外]

完整的 Web.xml 如下:

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>Spring MVC Application</display-name>

<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</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>/api/secure/*</url-pattern>
</filter-mapping>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml
</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

</web-app>

这是我的 mvc-dispatcher-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

<mvc:annotation-driven/>
<context:annotation-config/>
<context:component-scan base-package="com.ge.wtracker"/>
<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>

<!--Java Persistence API config-->
<jpa:repositories base-package="com.ge.wtracker.repository"/>

<!--JPA and Database Config-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="defaultPersistenceUnit"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="1800000"/>
<property name="numTestsPerEvictionRun" value="3"/>
<property name="minEvictableIdleTimeMillis" value="1800000"/>
<property name="validationQuery" value="SELECT 1"/>
</bean>

<!--Spring Security-->
<security:http create-session="stateless" entry-point-ref="restAuthenticationEntryPoint" authentication-manager-ref="authenticationManager">
<security:intercept-url pattern="/api/secure/**" access="ROLE_USER" />
<security:custom-filter ref="customRestFilter" position="BASIC_AUTH_FILTER" />
</security:http>
<!-- Configures the authentication entry point that returns HTTP status code 401 -->
<bean id="restAuthenticationEntryPoint" class="com.ge.wtracker.web.security.RestAuthenticationEntryPoint">
<property name="realmName" value="Not Authorized" />
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="restAuthenticationProvider" />
</security:authentication-manager>

<!--The customRestFilter responsibles for retrieving and manipulating any request data to pass to the authentication
provider to authenticate.-->
<bean id="customRestFilter" class="com.ge.wtracker.web.security.RestSecurityFilter">
<constructor-arg name="authenticationManager" ref="authenticationManager" />
<constructor-arg name="authenticationEntryPoint" ref="restAuthenticationEntryPoint" />
</bean>
<bean id="restAuthenticationProvider" class="com.ge.wtracker.web.security.RestAuthenticationProvider" />

</beans>

最佳答案

在 servlet 容器生命周期中,容器首先初始化 ServletContextListener ,然后是 FilterServlet实例。

Spring Web 应用程序通常加载两个上下文:根上下文和调度程序 servlet 上下文。 ContextLoaderListener类是 ServletContextListener它加载应用程序(或根)上下文。它通过context-param 标识要加载的文件。名称为 contextConfigLocation如下所示的 web.xml

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml
</param-value>
</context-param>

或者,默认情况下,通过在 /WEB-INF/applicationContext.xml 处查找文件.由于您已指定 /WEB-INF/mvc-dispatcher-servlet.xml作为contextConfigLocation ,该上下文将被加载。

完成后,容器将初始化 DispatcherServlet ,它也加载一个上下文。它通过 init-param 标识文件加载。名称为 contextConfigLocation 的元素在下面的 web.xml 中给出

<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/some-random-location.xml</param-value>
</init-param>
</servlet>

或者,默认情况下,通过在 /WEB-INF/name-of-your-servlet-servlet.xml 处查找文件.换句话说,它采用 <servlet-name> 的值。元素和附加 -servlet.xml到它并在 WEB-INF 中寻找它.

由于您没有指定 init-param姓名 contextConfigLocation , DispatcherServlet/WEB-INF/mvc-dispatcher-servlet.xml 加载上下文文件, 因为它的名字是 mvc-dispatcher . DispatcherServlet 加载的上下文可以访问 ContextLoaderListener 加载的 bean ,这就是为什么我们称其为根上下文(以及其他子上下文)。

所有这一切都表明您的ContextLoaderListener和您的DispatcherServlet正在创建自己的 ApplicationContext 的副本通过每次加载 XmlWebApplicationContext来自 /WEB-INF/mvc-dispatcher-servlet.xml 的同一文件.

确定您认为应该对整个应用程序可用的 bean 或配置,并将它们放入将由 ContextLoaderListener 加载的文件中.确定您认为 DispatcherServlet 应该可用的 bean 或配置并将它们放入其上下文文件中。

关于java - spring web, security + web.xml + mvc dispatcher + Bean 创建两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19826228/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com