spring web, security + web.xml + mvc dispatcher + Bean is created twice - java

I have the Web.xml as below:
<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>
[Edit]
After I added the spring security, then I get the error!
java.lang.IllegalStateException: No WebApplicationContext found: no
ContextLoaderListener registered?
then I added
<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>
then it seems working fine, but then
1) The problem is the bean are created twice!
if I only remove that:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml
</param-value>
</context-param>
but leave the <listener> then the web application doesn't run at all
[Extra]
The full Web.xml is below:
<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>
here is my 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>

During the servlet container lifecycle, the container first initializes the ServletContextListener, then the Filter and Servlet instances.
A Spring Web application typically loads two contexts: the root context and the dispatcher servlet context. The ContextLoaderListener class is a ServletContextListener which loads the application (or root) context. It identifies the file to load either through the context-param with the name contextConfigLocation as given in the web.xml like below
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml
</param-value>
</context-param>
or, by default, by looking for a file at /WEB-INF/applicationContext.xml. Since you've specified /WEB-INF/mvc-dispatcher-servlet.xml as the contextConfigLocation, that context will be loaded.
Once this is done, the container initializes the DispatcherServlet, which also loads a context. It identifies the file load either through an init-param element with the name contextConfigLocation as given in the web.xml below
<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>
or, by default, by looking for a file at /WEB-INF/name-of-your-servlet-servlet.xml. In other words, it takes the value of the <servlet-name> element and appends -servlet.xml to it and looks for it in WEB-INF.
Since you haven't specified an init-param with name contextConfigLocation, the DispatcherServlet loads the context file at /WEB-INF/mvc-dispatcher-servlet.xml, since its name is mvc-dispatcher. The context loaded by the DispatcherServlet has access to the beans loaded by the ContextLoaderListener, that's why we call that the root context (and the others children).
All this to say that both your ContextLoaderListener and your DispatcherServlet are creating their own copy of an ApplicationContext by each loading a XmlWebApplicationContext from the same file at /WEB-INF/mvc-dispatcher-servlet.xml.
Identify what beans or configuration you think should be available to the whole application and put them in the file that will be loaded by the ContextLoaderListener. Identify the beans or configuration you think should be available to the DispatcherServlet and put them in its context file.

http://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch16s02.html
The framework will, on initialization of a DispatcherServlet, look for
a file named [servlet-name]-servlet.xml in the WEB-INF directory of
your web application and create the beans defined there (overriding
the definitions of any beans defined with the same name in the global
scope).
So you can remove the context-param:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml
</param-value>
</context-param>

Spring MVC then create a new any-name.xml and place context specific beans like
Spring-security.xml and for your security bean to load.
New xml will be like this
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="com"/>
<task:annotation-driven/>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.
config.PropertyPlaceholderConfigurer">
<property name="location" value=""/>
<property name="locations">
<list>
<value>/WEB-INF/jdbc.properties</value>
</list>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.databaseurl}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
and now include this in web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/login-security.xml,
/WEB-INF/application-context.xml
</param-value>
</context-param>
hope this will help you.

Related

Thymeleaf template/ view not found - Spring 4

I'm setting up a new SPring4 app using Thymeleaf and keep encountering the same issue when it comes to returning the view. I've searched don here and followed some online tutorials but the same error so I'm thinking it may be due to configuration, any help is appreciated, thanks.
The error : org.thymeleaf.exceptions.TemplateInputException: Error resolving template "index", template might not exist or might not be accessible by any of the configured Template Resolvers
And then my config is:
Web.xml:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Use the simplified configuration by default. -->
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>simple</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<init-param>
<param-name>spring.profiles.default</param-name>
<param-value>simple</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<display-name>Test Web Application</display-name>
mcv.xml:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<mvc:annotation-driven/>
<!--Allows for static content to easily be served up without needing a controller etc-->
<mvc:resources mapping="/images/**" location="/assets/img/"/>
<mvc:resources mapping="/css/" location="/assets/css/"/>
<mvc:resources mapping="/assets/**" location="/assets/"/>
<!--taken from the thymeleaf site-->
<bean id="templateResolver"
class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".html" />
<property name="templateMode" value="HTML5" />
<property name="cacheable" value="false" />
</bean>
<bean id="templateEngine"
class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
</bean>
<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine" />
</bean>
</beans>
rootcontext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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"
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">
<import resource="mvc.xml" />
<!--double asterisk allows for recursive search - load all under the pacakge-->
<context:component-scan
base-package="
com.example.*"/>
<context:property-placeholder location="classpath:application.properties"/>
</beans>
Edit:
Controller:
#Controller //restcontroller is not meant to be for returning view, but instead the data http://stackoverflow.com/questions/33062509/returning-view-from-spring-mvc-restcontroller
#EnableAutoConfiguration
public class EmrController {
#Autowired EmrService emr;
#ModelAttribute("emrClusterList")
private List<EmrCluster>getAllClusters(){ return emr.getRunningClusters(); }
#RequestMapping(value = "/EmrClusters", method = RequestMethod.GET)
public String displayEmrList(Model model){
model.addAttribute("emrClusterList", emr.getRunningClusters());
return "index";
}

Datasource bean definition in applicationContext.xml

I am building a Spring MVC Web application. I have created applicationContext.xml file. I am trying to connect to mysql database. But when I define datasource bean in applicationContext.xml the tomcat server starts and it says 404- resource not found.
If I remove all the beans from the applicationContext.xml the project runs properly.
What am I doing wrong? It is said that datasources should be defined in the applicationContext.xml but is there other way to define datasource?
Here is my applicationContext.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:component-scan base-package="com.cinema.repository" />
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="userDao" class="com.cinema.repository.UserDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<context:property-placeholder location="jdbc.properties" />
</beans>
And this is my web.xml file
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Cinema Booking</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Can you please point out what am I doing wrong here?
san your problem is most likely to be in <context:property-placeholder location="jdbc.properties" /> it should be like this <context:property-placeholder location="classpath:/jdbc.properties" /> i am assuming that the application can not start because there is an error in the listener (the listener can not find the jdbc.properties)i think that you have put jdbc.properties in your classpath because you probably wont put jdbc.properties in the web folder making it accessible to every one can access to your application

Why #Component Spring Filter is not found ?

I have implement COrs Filter to handle the CORS. But the Filter is not found by Spring. So i still have the following error:
XMLHttpRequest cannot load http://localhost:8080/app-web/user/create. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
Here is the Cors Filter : in package com.day.jobly.web.filters;
#Component
public class SimpleCORSFilter implements Filter {
#Override
public void destroy() {
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST,PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
System.out.println("DO FILTER
chain.doFilter(req, res);
}
#Override
public void init(FilterConfig config) throws ServletException {
}
}
Here is my Spring Config :
app-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- activates various annotations to be detected in bean classes -->
<context:annotation-config />
<!-- Scans the classpath of this application for #Bean to deploy as beans -->
<context:component-scan
base-package="com.day.jobly.web.controllers,com.day.jobly.web.security,com.day.jobly.web.filters,com.day.jobly.services" />
<!-- Configures Handler Interceptors -->
<mvc:interceptors>
<!-- Changes the locale when a 'locale' request parameter is sent; e.g.
/?locale=de -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptors>
<!-- Saves a locale change using a cookie -->
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver" />
<!-- Application Message Bundle -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>../resources/properties/clientMessages</value>
</list>
</property>
<property name="cacheSeconds" value="0" />
</bean>
<!-- all resources inside folder src/main/webapp/resources are mapped so
they can be refered to inside JSP files (see header.jsp for more details) -->
<mvc:resources mapping="/**" location="/" />
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
</beans>
app-daos.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Repository and Service layers -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<jpa:repositories base-package="com.day.jobly.dao" entity-manager-factory-ref="myEmf"/>
<alias alias="entityManagerFactory" name="myEmf"/>
<bean id="myEmf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" />
<property name="generateDdl" value="true" />
</bean>
</property>
<property name="packagesToScan" value="com.day.jobly.entities" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:file:db/jobly" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEmf"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean class="com.day.jobly.web.debug.HsqlManager" init-method="init"
depends-on="myEmf" />
</beans>
Here is the web.xml
<web-app id="WebApp_ID" 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>Archetype Created Web Application</display-name>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/app-servlet.xml,classpath:spring/app-daos.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring/app-servlet.xml, classpath:spring/app-daos.xml
</param-value>
</context-param>
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Why this configuration <context:annotation-config /> does not work ?
You need to register the filter in web.xml, not as component in spring context.
To register in web.xml, add an xml fragment similar to characterEncodingFilter:
<filter>
<filter-name>corsFilter</filter-name>
<filter-class>com.day.jobly.web.filters.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>corsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
If you need to add a "spring-bean" as a web-filter:
You could use a delegating filter proxy , like spring-security does
You can also use WebAppInitializer, but this is more complicated.

Spring #Autowired Field - NoSuchBeanDefinitionException

I realize this question has been asked many times, but those answers don't seem to get me working.
The class which has the #Autowired field:
#Component
public class SpecialClaimsCaseManager {
#Autowired
private SpecialClaimsCaseRepositoryService<SpecialClaimsCaseDto> service;
public SpecialClaimsCaseManager() {
}
public Collection<SpecialClaimsCase> findAll() {
return convertToSpecialClaimsCase(service.findAll());
}
The interface SpecialClaimsCaseRepositoryService
public interface SpecialClaimsCaseRepositoryService<C extends SpecialClaimsCaseDto> {
//Some method signatures, not relevant
The implementation class (what should be injected)
#Service("specialClaimsCaseRepositoryService")
public class SpecialClaimsCaseRepositoryServiceImpl implements SpecialClaimsCaseRepositoryService<SpecialClaimsCaseDto> {
//Some method implementations, not relevant
mvcDispatcher.xml
<?xml version="1.0" encoding="UTF-8"?>
<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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.redacted.sch"/>
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:annotation-driven />
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>SpecialClaimsHandling</display-name>
<!-- Spring Configuration Files -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/application-security.xml
classpath*:sch_model_spring.xml
</param-value>
</context-param>
<!-- Spring Security Filters -->
<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>
<!-- Spring Listeners -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- MVC Filter -->
<servlet>
<servlet-name>mvcDispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvcDispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Session Configuration -->
<session-config>
<session-timeout>5</session-timeout>
</session-config>
</web-app>
sch_model_spring.xml (in another project)
<?xml version="1.0" encoding="UTF-8"?>
<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"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.redacted.sch.model"/>
<tx:annotation-driven />
<tx:jta-transaction-manager />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver" />
<property name="url" value="redacted" />
<property name="username" value="redacted" />
<property name="password" value="redacted" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="schManager" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
Full stack trace (fpasted because it's pretty long) http://fpaste.org/116696/14049194/
So, as we can see, mvc:annotation-driven is enabled, and autowiring is enabled. If I understand this correctly (I might not, pretty new to Spring), this should be all I need. SpecialClaimsCaseRepositoryService is an interface, if that matters, though I don't think it should as this same #Autowiring worked fine in another class annotated with #Controller.
Thanks for any help!
You'll notice from your stack trace that the exception occurs in the process of initializing the root application context loaded by the ContextLoaderListener. That's taken from
<!-- Spring Configuration Files -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/application-security.xml
classpath*:sch_model_spring.xml
</param-value>
</context-param>
In those two, you are scanning
<context:component-scan base-package="com.redacted.sch.model"/>
but not the com.redacted.sch.service... package that is required by one of the beans.
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.redacted.sch.service.SpecialClaimsCaseRepositoryService com.redacted.sch.model.SpecialClaimsCaseManager.specialClaimsCaseRepositoryService;
In this case, xyz.model.SpecialClaimsCaseManager has an #Autowired field of type xyz.service.SpecialClaimsCaseRepositoryService, but no such bean exists.
Don't mix component-scanned folders between application contexts, those loaded by ContextLoaderListener vs DispatcherServlet. Refactor so that application beans are loaded by the ContextLoaderListener and controller-related beans are loaded by the DispatcherServlet.
Reading:
Difference between applicationContext.xml and spring-servlet.xml in Spring Framework
What is the difference between ApplicationContext and WebApplicationContext in Spring MVC?

OpenSessionInViewFilter doesnt work in a JSF+Spring+Hibernate application

I want to use OpenSessionInViewFilter in my JSF 2.1+Spring 3.1+Hibernate 3.6.6 project
in order to get rid of the .LazyInitializationException.
Although i declare the filter in web.xml i keep getting ;
org.hibernate.LazyInitializationException: failed to lazily initialize
a collection of role: pts.entity.Invention.inventors, no
session or session was closed
My web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<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>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.tt</url-pattern>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>excite-bike</param-value>
</context-param>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<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>
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
My applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<import resource="classpath:applicationContext-security.xml" />
<context:annotation-config />
<context:component-scan base-package="pts.component" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>pts.entity</value>
</list>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/PTS" />
<property name="username" value="root" /> <property name="password"
value="" />
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"
name="template">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="txManager" />
</bean>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="view">
<bean class="pts.scope.ViewScope" />
</entry>
</map>
</property>
</bean>
</beans>
I use spring managed(HibernateTemplate) hibernate daos for db operations.Thanks for the help.
You just have to be sure that you are not redirecting between JSF view for example:
In this view your Open Session in vew Filter will work:
<navigation-rule>
<from-view-id>start.xhtml</from-view-id>
<navigation-case>
<from-outcome>page1</from-outcome>
<to-view-id>page1.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
and if you modify this example this way:
<navigation-rule>
<from-view-id>start.xhtml</from-view-id>
<navigation-case>
<from-outcome>page1</from-outcome>
<to-view-id>page1.xhtml</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
Your Filter will bnot help you because you are redirecting and this is completely new request and your original Hibernate session is already closed.
Inspired by this post:
OpenSessionInViewFilter +Redirect in JSF
When does it fail? I can see that you use Spring Security and have springSecurityFilterChain defined in you web.xml. And would assume that filter loads user from database and user has lazy collection that is accessed later, when Hibernate session created during authentication is propably closed, before OpenSessionInView filter starts executing.
Remember that filter-mapping order makes sense, filter executed in the order of their filter mappings are declared. I would try reorder them first.

Categories

Resources