I am trying to build a REST API with Spring and Hibernate.
When I run the server it returns no errors, but I can't access my links.
Here is my config file:
spring.xml
<mvc:annotation-driven />
<context:component-scan base-package="org.bloggy.spring" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hbm2ddl.auto">create-drop</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="show_sql">true</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/my_bloggy?createDatabaseIfNotExist=true" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="txManager"
class="org.springframework.transaction.jta.JtaTransactionManager" />
And that is my web.xml:
<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/resources/spring.xml</param-value>
<param-value>WEB-INF/resources/dao.xml</param-value>
<param-value>WEB-INF/resources/service.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
Controller:
#Controller
#RequestMapping(value = "users")
public class UserController {
#Autowired
private UserService userService;
#RequestMapping(value = "/", method = RequestMethod.GET)
public List<User> getUsers() {
return userService.listUsers();
}
}
As visible in logs the application MyBloggy doesn't actually initialize any spring beans. There is a problem with cache or the war file deployed on the tomcat. Ideally, At the time of deploying a war all the beans initialized can be seen in the logs unless disabled. Make sure that you are deploying a correct war on the server.
As #Ken mentioned In order to expose your API as a REST AP you need to use #RestController or if you want to use #Controller then use #ResponseBody annotation.
With regards to your issue I think you need to define your RequestMapping as
#Controller
#RequestMapping(value = "api")
public class UserController {
#Autowired
private UserService userService;
#RequestMapping(value = "/users", method = RequestMethod.GET)
public List<User> getUsers() {
return userService.listUsers();
}
}
Or
#Controller
#RequestMapping(value = "api/users")
public class UserController {
#Autowired
private UserService userService;
#RequestMapping(method = RequestMethod.GET)
public List<User> getUsers() {
return userService.listUsers();
}
}
Please see if it works.
You are using #Controller annotation, but if you want expose REST webservice, you need use #RestController or #ResponseBody
#RestController
#RequestMapping(value = "users")
public class UserController
Related
I was reading this https://spring.io/guides/gs/rest-service/ and I see that in Spring 4 , the #RestController is a combination of #ResponseBody and #Controller and hence its not necessary to mention the #ResponseBody at every method as it was previously. But, in one of the application am working on, we are using Spring 3.x and we have developed spring webservices and annotated the Controller class as #Controller. The sample controller looks like this:
#Controller
public class SomeController {
#RequestMapping(value = "uri/{values}", method = RequestMethod.GET)
public List<SampleClassPOJO> giveSomething(#PathVariable("values") String some){
//logic
return listOfSampleClassPOJO;
}
//Other services
}
and have the following config in the dispatcher servlet xml :
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="prettyPrint" value="false"/>
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper"/>
</property>
</bean>
</list>
</property>
</bean>
The dispatcher servlet is referred in the web.xml
<servlet>
<servlet-name>dispatch</servlet-name>
<servlet-class>someCustom.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatch</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
And we haven't annotated with #ResponseBody for any of the web services method nor at the class level, but still the response is a json. So, when is the #ResponseBody annotation required?
Now, this has gotten me into a confused state, I tried to search for any example with just the above entry in the dispatcher-servlet.xml and without using the #ResponseBody in the methods of the services, but there are no example as such. Only thing I found was, the above entry along with #RestController annotation in Spring 4.
Can anyone please tell me what is the piece of information that am missing here?
Thanks
I have developed a JAX-WS based web-service. I have Web service layer, service layer and a Dao layer. When i call a service method from web service class it gives null pointer exception. The reason is the service class bean is not getting injected.
web-service class:
package com.test.webservice.controller;
import javax.jws.WebMethod;
import javax.jws.WebService;
import com.test.salary.service.SalaryService;
#WebService
public class EmployeeSalaryWebService {
private SalaryService salaryService;
/**
* #param salaryService the salaryService to set
*/
#WebMethod(exclude = true)
public void setSalaryService(SalaryService salaryService) {
this.salaryService = salaryService;
}
#WebMethod
public double getEmployeeSalary(String name){
System.out.println("==== Inside getEmployee Salary === "+salaryService );
return salaryService.calculateSalary(name);
}
}
Application-context
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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-3.0.xsd">
<bean name="salaryWebService"
class="com.test.webservice.controller.EmployeeSalaryWebService">
<property name="salaryService" ref="salaryService" />
</bean>
<bean name="salaryService" class="com.test.salary.service.SalaryServiceImpl">
<property name="salaryDAO" ref="salaryDAO" />
</bean>
<bean name="salaryDAO" class="com.test.salary.dao.SalaryDaoImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe" />
<property name="username" value="LOCAL" />
<property name="password" value="abcdef" />
</bean>
</beans>
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_2_5.xsd"
version="2.5">
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/salaryConfiguration.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
Please let me know why the SalaryService salaryService not getting injected.
Your service class and bean in context is two separate things. I believe that you don't get bean from context and just use class, aren't you?
I advice you marking your service class with
#Component
That will make your class to become spring bean.
Then you can use inside following annotation.
#Autowired
This will try to find appropriate bean with annotated element type in spring context.
And don't forget to put into your context.
<context:component-scan base-package="..." />
This will search all classes marked as #Component and add it to spring context as beans.
For more detailed instruction you can check this article
https://www.javacodegeeks.com/2010/11/jaxws-with-spring-and-maven-tutorial.html
Make your SalaryService auto wired as follows:
public class EmployeeSalaryWebService {
#Autowired
private SalaryService salaryService;
....
I am trying to use Hibernate version 4.3.11.Final and spring version 4.2.2.RELEASE.
When i get the session in my UserDAO i have a hibernate exception : No Session found for current thread. I don't understand why could you help me please?
Below My files and sources :
Thank you
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml,
/WEB-INF/spring-security.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>
<!-- Spring Security -->
<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>
root-context.xml
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:8889/flosite" />
<property name="username" value="test" />
<property name="password" value="" />
</bean>
<!-- Hibernate Session Factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan">
<array>
<value>com.rg.flosite.model</value>
<value>com.rg.flosite.dao</value>
<value>com.rg.flosite.service</value>
</array>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
</value>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="dataSource" ref="myDataSource"/>
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
servlet-context.xml
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<resources mapping="/resources/**" location="/resources/" />
<resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources
in the /WEB-INF/views directory -->
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<beans:bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<beans:property name="definitions">
<beans:list>
<beans:value>/WEB-INF/tiles.xml</beans:value>
</beans:list>
</beans:property>
<beans:property name="preparerFactoryClass"
value="org.springframework.web.servlet.view.tiles2.SpringBeanPreparerFactory" />
</beans:bean>
<beans:bean id="userService" class="com.rg.flosite.service.UserServiceImpl"></beans:bean>
<beans:bean id="userDao" class="com.rg.flosite.dao.UserDAOImpl"></beans:bean>
<context:component-scan base-package="com.rg.flosite.controller" />
userDao.java
package com.rg.flosite.dao;
import com.rg.flosite.model.User;
public interface UserDAO {
public void updateUser(User user);
public User getUser();
}
UserDAOImpl.java
package com.rg.flosite.dao;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.rg.flosite.model.User;
#Repository
public class UserDAOImpl implements UserDAO {
#Autowired
private SessionFactory sessionFactory;
private Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
#Override
public void updateUser(User user) {
User userToUpdate = getUser();
if (userToUpdate == null) {
user.setId((long) 1);
getCurrentSession().save(user);
}
else {
user.setId(userToUpdate.getId());
getCurrentSession().update(user);
}
}
#Override
public User getUser() {
User user = (User) getCurrentSession().get(User.class,1);
return user;
}
}
UserService.java
package com.rg.flosite.service;
import com.rg.flosite.model.User;
public interface UserService {
public User getUser();
public void updateUser(User user);
}
UserServiceImpl.java
package com.rg.flosite.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.rg.flosite.dao.UserDAO;
import com.rg.flosite.model.User;
#Service
#Transactional
public class UserServiceImpl implements UserService {
#Autowired
private UserDAO userDao;
#Override
public User getUser() {
return userDao.getUser();
}
#Override
public void updateUser(User user) {
userDao.updateUser(user);
}
}
AdminMeControler.java
package com.rg.flosite.controller;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.rg.flosite.model.User;
import com.rg.flosite.service.UserService;
#Controller
public class AdminMeController {
#Autowired
private UserService userService;
#RequestMapping(value="/admin/moi", method = RequestMethod.GET)
public String home(Locale locale,Model model) {
User user = userService.getUser();
return "adminme";
}
}
Ok i have found the solution on an other forum.
My packages DAO, model, service have to be scanned by the application context (root-context.xml) and not by the servlet context (servlet-context.xml).
So i have changed the code below from servlet-context to root-context.
<bean id="userService" class="com.rg.flosite.service.UserServiceImpl"></bean>
<bean id="userDao" class="com.rg.flosite.dao.UserDAOImpl"></bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:component-scan base-package="com.rg.flosite.dao" />
<context:component-scan base-package="com.rg.flosite.model" />
<context:component-scan base-package="com.rg.flosite.service" />
I'm kinda new to Spring MVC, so I'm creating a small web application just to try it.
I am using Spring 4.2 and Hibernate 5.
The web app has a Spring servlet-context.xml and a Spring application-context.xml.
I have a #Controller with a method that make use of a #Service. This Service has a findAll() method marked as #Transactional.
The web.xml looks like this:
...
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:*-context.xml
</param-value>
</context-param>
<servlet>
<servlet-name>myDispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>myDispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
...
Here the Controller:
#Controller
public class TestOneController
{
#Autowired
private UserManager userManager;
#RequestMapping("views/test")
public ModelAndView defaultResolution()
{
List<User> users = userManager.findAll();
// here I build my String msg object
return new ModelAndView("views/resolution", "msg", msg);
}
}
Here the Service:
#Service("userManager")
public class UserManagerImpl implements UserManager
{
#Autowired
private UserDao userDao;
#Override
#Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public List<User> findAll()
{
return userDao.findAll();
}
}
And finally the Dao used by the Service:
#Repository("userDao")
public class UserDaoImpl implements UserDao
{
#Autowired
private SessionFactory sessionFactory;
#Override
#SuppressWarnings("unchecked")
#Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public List<User> findAll()
{
Query query = sessionFactory.getCurrentSession().createQuery("from User ");
return query.list();
}
}
My question:
I have tried several configurations, that I believed to be equivalent, but with one of them I am getting an org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread when I hit the mapped Controller method from a link in a page. Could someone explain me why this exception is raised when I use configuration 2, but not on configuration 1 and 3?
Configuration 1 (working)
application-context.xml
...
<tx:annotation-driven />
<context:component-scan base-package="my.package">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="packagesToScan">
<list>
<value>my.package.entities</value>
</list>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/myDb" />
</bean>
...
servlet-context.xml
...
<context:component-scan base-package="my.package.inner.package">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
...
Configuration 2 (raises the exception)
Same configuration as 1, with the difference of the <context:component-scan> tag of the servlet-context.xml, that has a base-package closer to the root:
<context:component-scan base-package="my.package">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
Note that this is the same base-package for the component-scan in the application-context.xml.
Configuration 3 (working)
Same as 2 (thus with base-package="my.package" in the servlet-context.xml), with the difference that instead of annotating my Service with #Service, I declare it explicitly as a bean in the application-context.xml:
...
<bean id="userManager" class="my.package.services.impl.UserManagerImpl">
</bean>
...
TL;DR
Could someone explain me why I am getting an org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread when I hit the Controller mapped method with configuration 2 and not with configuration 1 and 3?
I was believing that all those 3 configuration were equivalent.
Thank you.
After some hours of trial-and-error process, I found out the issue.
In all the 3 configurations, the component-scan tag of servlet-context.xml needs another attribute: use-default-filters must be set to "false".
<context:component-scan base-package="my.package" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
If it's set to "true" (as per default), it's essentially like having a default include filter like this one:
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Component"/>
This means that during the package scan, it loaded also the defined #Service (and the #Repository, etc.).
Since the Service was loaded by the Servlet Context, that has no <tx:annotation-driven /> tag, no Transactional context was enabled for the Service, and the Exception was raised.
In configuration 1, since the base package for scanning was restricted (including only the Controller package), the issue was bypassed (the Servlet Context only loaded the Controller, so the Service used was the one loaded by the Application Context, that has Transactional context enabled).
In configuration 3, since I used a "manual definition" of the Service bean in the right "transactional" context (application-context.xml), the problem was bypassed too.
I found many solutions to lots of my queries already from stackoverflow and this is first time I am asking a question here and I don't really know what's wrong with that. Actually I am trying to Autowire one of my classes by type but unable to do that. Following is the source code in sequence.
Spring Context
<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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/mysqlConfig.properties" />
<bean id="sessionManager" class="com.bakaenterprise.dal.SessionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<context:annotation-config />
<context:component-scan base-package="com.bakaenterprise" />
<bean id="searchManager" class="com.bakaenterprise.bl.SearchManager" />
<bean id="fileDao" class="com.bakaenterprise.dal.impl.FileUploadDao" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="10" />
<property name="maxActive" value="5" />
<property name="maxWait" value="5000" />
</bean>
<!-- Hibernate Configuration -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
p:dataSource-ref="dataSource" p:packagesToScan="com.bakaenterprise.beans">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">
true
</prop>
<prop key="hibernate.generate_statistics">
true
</prop>
</props>
</property>
</bean>
</beans>
interface
package com.bakaenterprise.dal;
import com.bakaenterprise.beans.FileUploadBean;
import com.bakaenterprise.core.base.GenericDao;
public interface IFileUploadDao extends GenericDao<FileUploadBean> {
}
implementation
package com.bakaenterprise.dal.impl;
import com.bakaenterprise.beans.FileUploadBean;
import com.bakaenterprise.core.base.HibernateDaoSupport;
import com.bakaenterprise.dal.IFileUploadDao;
import java.io.Serializable;
import java.util.List;
import org.springframework.stereotype.Component;
/**
* #author ali
*/
#Component
public class FileUploadDao extends HibernateDaoSupport<FileUploadBean> implements IFileUploadDao {
#Override
public boolean save(FileUploadBean obj) {
super.save(obj);
return true;
}
#Override
public FileUploadBean getRecordById(Serializable id) {
return super.getRecordById(id);
}
public boolean deleteRecordById(int id){
return super.deleteById(id);
}
#Override
public List<FileUploadBean> listAll() {
return super.listAll();
}
}
Manager class
package com.bakaenterprise.bl;
package com.bakaenterprise.bl;
import com.bakaenterprise.dal.IFileUploadDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* #author ali
*/
#Component
public class TestManagerImpl implements ITestManager {
#Autowired
private IFileUploadDao fileDao;
#Override
public void test() {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public IFileUploadDao getFileDao() {
return fileDao;
}
#Override
public void setFileDao(IFileUploadDao fileDao) {
this.fileDao = fileDao;
}
}
Code where I am using Search Manager and testing FileUploadDao object is null or not
#Autowired
private ITestManager testManager;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
IFileUploadDao fileUploadDao = testManager.getFileDao();
// now testManager is null
}
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>SearchServlet</servlet-name>
<servlet-class>com.bakaenterprise.server.SearchServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SearchServlet</servlet-name>
<url-pattern>/servlets/SearchServlet</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<jsp-config>
<taglib>
<taglib-uri>/jstl/core_rt</taglib-uri>
<taglib-location>/WEB-INF/tld/c.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/jstl/xml_rt</taglib-uri>
<taglib-location>/WEB-INF/tld/x_rt.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/jstl/fn_rt</taglib-uri>
<taglib-location>/WEB-INF/tld/fn.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/jstl/fmt_rt</taglib-uri>
<taglib-location>/WEB-INF/tld/fmt.tld</taglib-location>
</taglib>
</jsp-config>
<filter>
<filter-name>performance</filter-name>
<filter-class>com.bakaenterprise.util.PerformanceLog</filter-class>
</filter>
<filter-mapping>
<filter-name>performance</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
Now File Dao is always null, I think its not scanning the components though base package is correct. Any help or suggestion would be highly regarded and appreciated. And I know this type of question is being asked many times so apologizes for asking it again, those answer didn't work for me.
I believe you have to declare this explicitly in applicationContext for the bean you want to autowire.
<bean id="searchManager" class="com.bakaenterprise.bl.SearchManager" autowire="byType"/>
An alternative is to autowire byName, which should work in your case too (since member variablefileDao has the same name as the bean ID fileDao).
SearchManager should be annotated also for the IFileUploadDao implementation bean to be injected during the component scan
#Component
public class SearchManager {
Also you're initializing SearchManager manually which will result in its dependencies not being injected - The bean needs to be managed by Spring. As there is no direct way to inject Spring Beans into a Java Servlet, you can use a Spring framework HttpRequestHandler.
public class AnnotatedHttpServletRequestHandler implements HttpRequestHandler {
#Autowired
private SearchManager searchManager;
...
}
Specific details are described in Injecting Spring Beans into Java Servlets
Try to add depends-on attribute in your spring context configuration:
<bean id="searchManager" class="com.bakaenterprise.bl.SearchManager"
depends-on="fileDao" />
EDIT:
You FileUploadDao defined twice, one bean with #Component annotation and second with XML:
<bean id="fileDao" class="com.bakaenterprise.dal.impl.FileUploadDao" />
So, you just create two copies of one bean! And it's a problem I think.
EDIT-2
Try to remove this XML definitions:
<bean id="searchManager" class="com.bakaenterprise.bl.SearchManager" />
<bean id="fileDao" class="com.bakaenterprise.dal.impl.FileUploadDao" />
and add #Component annotation to SearchManager
EDIT-3
You need to autowire SearchManager:
public SearchServlet extends HttpServlet {
#Autowired
private SearchManager searchManager;
public void init(ServletConfig config) {
super.init(config);
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,
config.getServletContext());
}
}
You have some options here, you can annotate your class SearchManager with:
#Component
#Configurable - The #Configurable is used to mark a class eligible for Spring dependency injection. It's should be used when you can't or have no intention to use your class as a Spring Bean (Available since Spring 2.0)
There are other ways to wire your classes, but you may lose some benefits.
You also should remove the xml declaration:
<bean id="searchManager" class="com.bakaenterprise.bl.SearchManager" />