Autowiring Beans defined in XML into Spring's Java Config - spring

I have an xml configuration of spring as below:
<bean id="processor"
class="org.springframework.security.saml.processor.SAMLProcessorImpl">
<constructor-arg>
<list>
<ref bean="redirectBinding" />
<ref bean="postBinding" />
<ref bean="artifactBinding" />
<ref bean="soapBinding" />
<ref bean="paosBinding" />
</list>
</constructor-arg>
</bean>
I also have another Java Configuration of Spring as below:
#ImportResource({ "classpath:security/samlMetadata.xml" })
#Configuration
public class SecConfig{
#Autowired
private SAMLProcessorImpl processor;
#Bean(name ="webSSOProfileConsumer")
public WebSSOProfileConsumer webSSOProfileConsumer(){
WebSSOProfileConsumerImpl webSSOProfileConsumerImpl = new WebSSOProfileConsumerImpl();
try {
webSSOProfileConsumerImpl.setProcessor(processor);
webSSOProfileConsumerImpl.afterPropertiesSet();
}
catch (Exception e) {
e.printStackTrace();
}
return webSSOProfileConsumerImpl;
}
}
I get the processor bean as null, please help me if I am missing some basic thing while autowiring.
EDIT
Here is the relevant part of web.xml The only thing I am skipping is welcome-file-list
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.config.WebConfig
</param-value>
</context-param>
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>production</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>security</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>security</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>filterChainProxy</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>filterChainProxy</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
EDIT2
#Configuration
#ImportResource({ "classpath:security/samlMetadata.xml" })
#Import({SecureConfig.class})
#Profile("production")
#ComponentScan(basePackages = "com.config")
public class WebConfig extends WebMvcConfigurationSupport {
#Bean(name = "viewResolver")
public InternalResourceViewResolver viewResolver() throws Exception {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
I am sorry I didn't add this class earlier.

Related

Autowiring bean in Session Listener

I need to Autowire a service class annotated with #Service annotation in my session listener class as I need to perform some DB operation on session destroyed method. I am not able to autowire the service class as I have added the listener in my web.xml and it is no longer spring managed. I have tried several options(workarounds) like getting a bean from application context via servlet context but I am not getting any beans in that way.
Following are my classes:-
MyService:
#Service
#Transactional
public class FxTransactionService{
//some autowirings
public void performDBoperation(Long id)
{
//business logic
}
}
Session Listener:
public class SessionHandler implements HttpSessionListener {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
#Autowired
private MyService myService;
#Override
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("Session created");
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(arg0.getSession()
.getServletContext());
System.out.println(Arrays.toString(context.getBeanDefinitionNames()));
//This gives me empty list
}
#Override
public void sessionDestroyed(HttpSessionEvent arg0) {
Long id = (Long) arg0.getSession().getAttribute("Id");
myService.performDBoperation(id);
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.abc.controller.SessionHandler</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>
<filter>
<filter-name>preAuthHeaderAdditionFilter</filter-name>
<filter-class>com.abc.filter.PreAuthHeaderAdditionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>preAuthHeaderAdditionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- <filter> <filter-name>openEntityManagerInViewFilter</filter-name> <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter> <filter-mapping> <filter-name>openEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern> </filter-mapping> -->
</web-app>
First install the Spring listener ContextLoaderListener.
In your own listener you can access the context using WebApplicationContextUtils.
It is not autowiring though, you have to fetch the required bean/service yourself.

How to load the data in index page using spring mvc?

I tried couple of Tutorial in Spring-MVC to load the data in index page without using ajax call means before loading the index page I want to get the data from server and load the data into the index page.but did not get proper answer.
Finally after couple of try i got the answer.here is my code.
web.xml
<display-name>SpringTest</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<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>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
My Controller
#Controller
public class WebController {
#Autowired
private EmployeeService empService;
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView index() {
List<Employee> empList = empService.getAllEmployee();
Collections.sort(empList, new EmployeeSortById());
ModelAndView modelMap = new ModelAndView("index","employeeList", empList);
System.out.println("Calling controller");
return modelMap;
}
}
spring-context.xml
<context:component-scan base-package="com.app.controller,com.app.dao.impl,com.app.service.impl" />
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>

Spring JavaConfig JPA issue - " No bean named 'entityManagerFactory' is defined"

I'm in the process of converting XML based configuration for a Spring Java Web project to JavaConfig.
I'm using JPA. So I created an additional JavaConfig class with the necessary configuration. But the JPA configuration fails for some reason.
Here is my [web.xml][1]
<?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">
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<!-- Configuration locations must consist of one or more comma- or space-delimited
fully-qualified #Configuration classes. Fully-qualified packages may also be
specified for component-scanning -->
<!-- <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.my.contoso.spring.contosoJPA</param-value>
</context-param>-->
<!-- Bootstrap the root application context as usual using ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Declare a Spring MVC DispatcherServlet as usual -->
<servlet>
<servlet-name>restservices</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<!-- Again, config locations must consist of one or more comma- or space-delimited
and fully-qualified #Configuration classes -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.my.contoso.spring.contosoConfig</param-value>
</init-param>
</servlet>
<!--
This Servlet mapping means that this Servlet will handle all incoming requests
-->
<servlet-mapping>
<servlet-name>restservices</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- for CORS -->
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, HEAD, POST, PUT, DELETE, OPTIONS</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>Content-Type, X-Requested-With, Origin, Accept</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- End for CORS -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<filter>
<filter-name>OpenEntityManagerFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
<init-param>
<param-name>entityManagerFactoryBeanName</param-name>
<param-value>entityManagerFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>OpenEntityManagerFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- <resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/contosoDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>-->
</web-app>
Here is my primary [JavaConfig class][2]
#Configuration
#EnableWebMvc
//#ImportResource("contoso-jpa.xml") //Import any existing xml context files
#Import(contosoJPA.class)
//#EnableTransactionManagement //substitute for <tx:annotation-driven/>
#ComponentScan({"com.my.contoso.webservices.rest", "com.my.contoso.services,com.my.contoso.dao"})
public class contosoConfig {
}
And Here's the JavaConfig class with [JPA config][3]
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories //(basePackages = { "com.my.contoso.domain" })
public class contosoJPA {
#Bean
public DataSource dataSource() {
// return new EmbeddedDatabaseBuilder().setType(H2).build();
DriverManagerDataSource ds = new DriverManagerDataSource();
try {
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUsername("root");
ds.setPassword("");
ds.setUrl("jdbc:mysql://localhost:3306/contosodb");
} catch (Exception e) {
// logger.error(e.getMessage());
System.out.println(e);
}
return ds;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
lef.setDataSource(dataSource);
lef.setJpaVendorAdapter(jpaVendorAdapter);
lef.setPackagesToScan("com.my.contoso.domain");
lef.setPersistenceUnitName("contosoPU");
return lef;
}
#Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setShowSql(false);
hibernateJpaVendorAdapter.setGenerateDdl(true);
hibernateJpaVendorAdapter.setDatabase(Database.MYSQL);
// hibernateJpaVendorAdapter.setDatabase(Database.H2);
return hibernateJpaVendorAdapter;
}
#Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}
}
Full Stack Trace:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:570)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1108)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:278)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1121)
at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.lookupEntityManagerFactory(OpenEntityManagerInViewFilter.java:222)
at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.lookupEntityManagerFactory(OpenEntityManagerInViewFilter.java:205)
at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:152)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:179)
at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:241)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2430)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2419)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:570)
'entityManagerFactory' is declared in the [web.xml][1]. The error says that a bean with such name doesn't exist. But I did include it in the [JPA config][3] file. So I'm guessing that the beans in the JPA javaConfig file are not getting picked up. Wondering where the configuration is failing.
Why did you comment out
<!-- Configuration locations must consist of one or more comma- or space-delimited
fully-qualified #Configuration classes. Fully-qualified packages may also be
specified for component-scanning -->
<!-- <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.uhsarp.billrive.spring.BillriveJPA</param-value>
</context-param>-->
?
It seems to me like that root context should be loaded and made available to the whole application through the ContextLoaderListener. That context-param needs to be available so that the root context has a source from which to load bean definitions.
i would try to remove parameters and call bean methods manually:
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
lef.setDataSource(dataSource());
lef.setJpaVendorAdapter(jpaVendorAdapter());
lef.setPackagesToScan("com.my.contoso.domain");
lef.setPersistenceUnitName("contosoPU");
return lef;
}
then
try to debug/sout if spring get to any method from this configuration class.
Maybe mixing web.xml configuration with java config is not the best idea? Did you consider to migrate it? :)

Restful web service based on CXF

everyone!
Something has confused me a lot. I make a Restful Web service based on CXF,but it does not work.
My web.xml is as follows:
<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>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
and then is my applicationContext.xml:
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="handleRequest" class="test.cjm.HandleReuqst"/> <jaxrs:server id="customerService" address="/">
<jaxrs:serviceBeans>
<ref bean="handleRequest"/>
</jaxrs:serviceBeans>
and my HandleRequest.java file presents below:
#Produces("application/json")
#Path("/test")
public class HandleRequest {
#GET
#Path("/Spring")
public TestVO testSpring(){
System.out.println("get users:");
TestVO tv = TestDAO.getPerson();
return tv;
}
}
The TestDAO.java file
private static Map<String,TestVO> testVOs;
static{
testVOs = new HashMap<String,TestVO>();
TestVO t1 = new TestVO();
t1.setId(1);
t1.setName("cjm");
testVOs.put("1", t1);
}
public static TestVO getPerson(){
return testVOs.get("1");
}
I deploy the program in tomcat named CXFSpring. I don't know where is wrong, Everytime I make a request to localhost:8080/CXFSpring/test/Spring, It just return a 404 status.
Could you tell me Where is wrong?
you CXF serving servlet is mapped to /service/*
try the following URL: localhost:8080/CXFSpring/service/test/Spring

InternalResourceViewResolver doesn't load page from subfolder

under the webapp folder of my application i have a folder called meetingroom
and in that folder i have a jsp page called viewrooms.jsp
- DispatcherServlet configuration is as follows:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring/config/applicationContext.xml
</param-value>
</context-param>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/config/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/meetingroom/*</url-pattern>
</servlet-mapping>
- InternalResourceViewResolver bean:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
- Controller:
#Controller
#RequestMapping("/viewrooms.jsp")
public class ViewRooms {
#RequestMapping(method = RequestMethod.GET)
public String get() {
log.debug("######## GET METHOD FOR VIEW ROOMS ########");
return "meetingroom/viewrooms";
}
}
How i am accessing the page: http://localhost:8081/MyAPP/meetingroom/viewrooms.jsp
ISSUE: the controller get method is getting called in infinite loop and the page is not rendered.
please advise why it's not working, thanks.
IMHO #RequestMapping("/viewrooms.jsp") points to /MyAPP/viewrooms.jsp
changing #RequestMapping to "/meetingroom/viewrooms.jsp" would be my next guess for the fix of your problem
problem fixed after changing the pages folder name, maybe it was conflicting with the servlet url mapping.

Resources