Im have been working on a example for spring MVC + Spring Security + hibernate to make a login page, but now i have come to a problem with a fuel #Autowire that keeps giving me null values. the server doesnt report any errors its just that it doesnt complete the operation.
CustomUSerDetailsService.java
package com.carloscortina.paidosSimple.service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import com.carloscortina.paidosSimple.dao.UsuarioDao;
import com.carloscortina.paidosSimple.model.Usuario;
#Service
#Transactional(readOnly=true)
public class CustomUserDetailsService implements UserDetailsService {
private static final Logger logger = LoggerFactory.getLogger(CustomUserDetailsService.class);
#Autowired UsuarioDao userDao;
#Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
logger.info(username);
Usuario domainUser = userDao.getUsuario(username);
logger.info(domainUser.getUsername());
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
return new User(
domainUser.getUsername(),
domainUser.getPassword(),
enabled,
accountNonExpired,
credentialsNonExpired,
accountNonLocked,
getAuthorities(domainUser.getRol().getId()));
}
public Collection<? extends GrantedAuthority> getAuthorities(Integer rol){
List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(rol));
return authList;
}
public List<String> getRoles(Integer rol){
List<String> roles = new ArrayList<String>();
if(rol.intValue() == 1){
roles.add("ROLE_DOCTOR");
roles.add("ROLE_ASISTENTE");
}else if (rol.intValue() == 2){
roles.add("ROLE_ASISTENTE");
}
return roles;
}
public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles){
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
return authorities;
}
}
Here the field userDao keeps beign null so when i try to use userDao.getUsuario(username) the operation just doesnt continue, it doesn't report an error or similar its just gives me a 404- error
UsuarioDao.xml
package com.carloscortina.paidosSimple.dao;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.carloscortina.paidosSimple.model.Usuario;
#Repository
public class UsuarioDaoImp implements UsuarioDao {
private static final Logger logger = LoggerFactory.getLogger(UsuarioDaoImp.class);
#Autowired
private SessionFactory sessionFactory;
private Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
#Override
public Usuario getUsuario(String username) {
logger.debug("probando");
List<Usuario> userList = new ArrayList<Usuario>();
Query query = getCurrentSession().createQuery("from Usuario u where u.Username = :username");
query.setParameter("username", username);
userList = query.list();
if (userList.size() > 0){
return (Usuario) userList.get(0);
}else{
return null;
}
}
}
servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
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
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
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Enable transaction Manager -->
<tx:annotation-driven/>
<!-- DataSource JNDI -->
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/paidos" resource-ref="true" />
<!-- Session factory -->
<beans:bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
p:dataSource-ref="dataSource"
p:hibernateProperties-ref="hibernateProperties"
p:packagesToScan="com.carloscortina.paidosSimple.model" />
<!-- Hibernate Properties -->
<util:properties id="hibernateProperties">
<beans:prop key="hibernate.dialect">
org.hibernate.dialect.MySQL5InnoDBDialect
</beans:prop>
<beans:prop key="hibernate.show_sql">false</beans:prop>
</util:properties>
<beans:bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- 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>
<context:component-scan base-package="com.carloscortina.paidosSimple" />
</beans:beans>
I dont know whats missing , so any idea its welcome, thanks in advance.
Edit:
UsuarioDaoImp
package com.carloscortina.paidosSimple.dao;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.carloscortina.paidosSimple.model.Usuario;
#Repository
public class UsuarioDaoImp implements UsuarioDao {
private static final Logger logger = LoggerFactory.getLogger(UsuarioDaoImp.class);
#Autowired
private SessionFactory sessionFactory;
private Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
#Override
public Usuario getUsuario(String username) {
logger.debug("probando");
List<Usuario> userList = new ArrayList<Usuario>();
Query query = getCurrentSession().createQuery("from Usuario u where u.Username = :username");
query.setParameter("username", username);
userList = query.list();
if (userList.size() > 0){
return (Usuario) userList.get(0);
}else{
return null;
}
}
}
After trying to add a bean with UsuarioDaoImp i got this error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'usuarioServicioImp': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.carloscortina.paidosSimple.dao.UsuarioDao com.carloscortina.paidosSimple.service.UsuarioServicioImp.usuarioDao; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.carloscortina.paidosSimple.dao.UsuarioDao] is defined: expected single matching bean but found 2: usuarioDaoImp,userDao
UsuarioServiceImp
package com.carloscortina.paidosSimple.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.carloscortina.paidosSimple.dao.UsuarioDao;
import com.carloscortina.paidosSimple.model.Usuario;
#Service
#Transactional
public class UsuarioServicioImp implements UsuarioService{
#Autowired
private UsuarioDao usuarioDao;
#Override
public Usuario getUsuario(String username) {
return usuarioDao.getUsuario(username);
}
}
i think I'm short in knowledge about the subject, that why i was following an example but i ended with this, so my apologise if I'm not giving the information correctly or if im misunderstanding concepts.
spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<beans:bean class="com.carloscortina.paidosSimple.service.CustomUserDetailsService" id="customUserDetailsService"></beans:bean>
<security:http auto-config="true">
<security:intercept-url pattern="/sec/moderation.html" access="ROLE_ASISTENTE" />
<security:intercept-url pattern="/admin/*" access="ROLE_DOCTOR" />
<security:form-login login-page="/user-login.html"
default-target-url="/success-login.html"
authentication-failure-url="/error-login.html" />
<security:logout logout-success-url="/index.html" />
</security:http>
<security:authentication-manager>
<security:authentication-provider user-service-ref="customUserDetailsService">
<security:password-encoder hash="plaintext" />
</security:authentication-provider>
</security:authentication-manager>
</beans:beans>
How are you accessing CustomUSerDetailsService class ? I hope you haven't added this class as bean in security config file or any other spring config?
Editted:
Your service bean is annotated with #service and you have also declared it in xml, spring has created two service beans one based on #service annotation (fully populated as its autowried) and second using the xml config (in which I assume you haven't injected dao dependency explicitly), so the second one doesnt have dao object set. As you are using the bean name of the service bean declared in your security config, you are getting userDao as null on debug.
Either comment the explicit bean definition in security xml, use ref="customUSerDetailsService" directly as #service annotation already added a bean with this name in spring context.
i.e. comment/remove this line in your security config and every thing should work.
<beans:bean class="com.carloscortina.paidosSimple.service.CustomUserDetailsService" id="customUserDetailsService"></beans:bean>
When you annotate a bean with #component/#service spring adds a bean with name equals to short classname(first letter lower case), so bean with name "customUserDetailsService" already exists, defining it explicitly in xml is overriding it.
Or declare all the bean definitions (including there dependencies) explicitly it xml config
Add the dao package to the component scan
<context:component-scan base-package="com.carloscortina.paidosSimple, com.carloscortina.paidosSimple.dao" />
Related
I've created a simple page project, which checks a single inputdata field "name" and if it's empty or size is less than 5, it has to show a error-message.
At the moment BindingResult thinks there is no error all the time.
Spring.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:mvc="http://www.springframework.org/schema/mvc"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- Step 3: Add support for component scanning -->
<context:component-scan base-package="com.mvc" />
<!-- Step 4: Add support for conversion, formatting and validation support -->
<mvc:annotation-driven/>
<!-- Step 5: Define Spring MVC view resolver -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
Student class:
package com.mvc;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class Student {
#NotNull(message = "IsRequired!")
#Size(min = 5, message = "must be greater than 5!")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Controller:
package com.mvc;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.validation.Valid;
#Controller
public class StudentController {
#RequestMapping("/")
public String showPage(Model model){
model.addAttribute("student", new Student());
return "index";
}
#RequestMapping("/processForm")
public String processForm(
#Valid #ModelAttribute("student") Student student,
BindingResult theBindingResult) {
if (theBindingResult.hasErrors()) {
return "index";
} else {
return "student-confirm";
}
}
}
If required, i can post web.xml, and jsp pages.
Removed previous version of Tomcat(7.0) and installed latest version.
AdminService.java
package service;
import java.awt.Window.Type;
import java.util.HashMap;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import dao.IMemberDAO;
import model.Member;
#Service
public class MemberService
{
#Autowired
private IMemberDAO memberDao;
// 로그인
public HashMap<String, Object> login(String id,String pw)
{
HashMap<String, Object> result = memberDao.selectOne(id);
if(result != null) // 존재하는 값이 있으면
{
String opwd = (String) result.get("pw"); // opwd = 존재하는값의 pw값을 가져온 값
if(opwd.equals(pw))
{
return result; // true면 존재하는값을 반환
}
else
{
return null;
//return null; // 아니면 값을 반환하지 않음.
}
}
else // 존재하는 값이 없다면
{
return null;
}
}
// 아이디 체크
public boolean idCheck(String loginPerson)
{
HashMap<String, Object> user = memberDao.selectOne(loginPerson);
if(user != null)
{
return false;
}
else
{
return true;
}
}
// 멤버 추가
public boolean insertMember(Member member)
{
if(idCheck(member.getId()))
{
memberDao.insertMember(member);
return true;
}
else
{
return false;
}
}
public HashMap<String, Object> getMemberInfo(String id)
{
return memberDao.selectOne(id);
}
// 회원 수정
public void memberUpdate(HashMap<String, Object> params)
{
System.out.println("params is : " + params);
memberDao.updateMember(params);
}
// 회원삭제
public boolean memberDelete(String id,String pw)
{
HashMap<String, Object> user = memberDao.selectOne(id);
String pw2 = (String) user.get("pw");
System.out.println("id and pw is : " + id + "/" + pw);
System.out.println("pw2 is : " + pw2);
if(pw2.equals(pw))
{
memberDao.deleteMember(id);
System.out.println("return true");
return true;
}
else
{
System.out.println("return false");
return false;
}
}
}
AdminController.java
package controller;
import java.io.IOException;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import service.AdminService;
import service.MemberService;
#Controller
public class AdminController
{
#Autowired
public AdminService aService;
// 관리자 로그인 폼 페이지
#RequestMapping("admin.do")
public String adminLoginPage()
{
return "adminLoginPage";
}
// 관리자 로그인했을 시 요청
#RequestMapping("adminLoginOK.do")
#ResponseBody
public String adminMainPage(#RequestParam(required=false) String id, #RequestParam(required=false)String pw,HttpSession session,HttpServletRequest req,HttpServletResponse resp)
{
HashMap<String, Object> adminLoginIdentify = aService.adminLogin(id, pw);
//if(session.getAttribute("id") == null){System.out.println("zzz kkk");}
//String admin_id = (String) session.getAttribute("id");
if(adminLoginIdentify != null)
{
return "1";
}
else
{
return "0";
}
}
#RequestMapping("adminPage.do")
public String adminPage(
#RequestParam(required = false) String keyword,
#RequestParam(defaultValue="0") int type,
HttpSession session,HttpServletRequest resquest,HttpServletResponse response) throws IOException
{
ModelAndView mav = new ModelAndView();
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("type", type);
params.put("keyword", keyword);
System.out.println(params);
return "adminMainPage";
}
}
adminDaoMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.IAdminDAO">
<select id="selectOne" parameterType="Strig" resultType="java.util.HashMap">
select * from member where id = #{id}
</select>
<select id="selectMemberAll" resultType="java.util.HashMap">
select * from member
</select>
</mapper>
AdminDao.java
package dao;
import java.util.HashMap;
public interface IAdminDAO
{
public HashMap<String, Object> selectOne(String id);
}
The code before modifying the applicationContext file is shown below.
<?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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
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-4.1.xsd">
<context:component-scan base-package="service" />
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property value="com.mysql.jdbc.Driver" name="driverClassName"></property>
<property value="jdbc:mysql://localhost/rachelvf" name="url"></property>
<property value="root" name="username"/>
<property value="mysql" name="password"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath*:dao/mapper/*.xml"></property>
</bean>
<bean id="memberDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
<property name="mapperInterface" value="dao.IMemberDAO"></property>
</bean>
</beans>
This is the appliCation code after the modification.
<?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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
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-4.1.xsd">
<context:component-scan base-package="service" />
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property value="com.mysql.jdbc.Driver" name="driverClassName"></property>
<property value="jdbc:mysql://localhost/rachelvf" name="url"></property>
<property value="root" name="username"/>
<property value="mysql" name="password"/>
</bean>
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="mapperLocations" value="classpath:dao/mapper/*.xml"></property>
<property name="typeAliasesPackage" value="model"></property>
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
The project worked well before the applicationContext file was modified,
but after the code has been modified, an error occurs.
error code is that.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adminService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private dao.IAdminDAO service.AdminService.adminDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [dao.IAdminDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
I thought about the cause of the error,
but I think it is because I did not insert the service annotation.
However, there is no typos in any way, and everything is written correctly and errors occur. Is there something I don't know?
Can you tell me what caused this error?
And what about the solution?
Please help me..
Try to change this code of yours:
#Autowired
public AdminService aService;
to this:
#Autowired
public AdminService adminService;
because when you Autowire, he can't see aService on your context that's why he can't create instance of adminService as a default name of your Service bean.
EDIT:
Another thing is you have to implement your interfaces to a concrete class in order to instantiate beans, you can't instantiate interfaces remember, so you need concrete beans to implement what is on your interfaces. Like this:
#Repository
public class IAdminDAOImpl implements IAdminDAO {
//Implementation here
}
#Service
public class AdminServiceImpl implements AdminService {
//Implementation here
}
Im having a problem with a spring-mvc project. The #autowiring is not creating the beans required. Ive worked on this for over 4 days and followed all the search results. But nothing has worked. Can someone please take a look. Thank You
The error stack is this:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productsController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.davis.ty.service.ProductsService com.davis.ty.controller.ProductsController.productsService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.davis.ty.service.ProductsService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
My servlet.xml is:
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
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
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">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<context:annotation-config />
<context:component-scan base-package="com.davis.ty" />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
My controller is:
package com.davis.ty.controller;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.davis.ty.domain.Products;
import com.davis.ty.service.ProductsService;
#Controller
public class ProductsController {
#Autowired
private ProductsService productsService;
#RequestMapping(value = "/index", method = RequestMethod.GET)
public String listProducts (Map<String, Object> map) {
System.out.println("index");
map.put("products", new Products());
map.put("productsList", productsService.listProducts());
return "index";
}
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addProducts(#ModelAttribute("products")
Products products, BindingResult result) {
productsService.addProducts(products);
return "redirect:/index";
}
#RequestMapping("/delete/{Id}")
public String deleteProducts(#PathVariable("Id")
Integer Id) {
productsService.removeProducts(Id);
return "redirect:/index";
}
}
My service program is:
package com.davis.ty.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.davis.ty.dao.ProductsDAO;
import com.davis.ty.domain.Products;
#Service
public class ProductsServiceImpl {
#Autowired
private ProductsDAO productsDAO;
#Transactional
public void addProducts(Products products){
productsDAO.addProduct(products);
}
#Transactional
public List<Products> listProducts() {
return productsDAO.listProducts();
}
#Transactional
public void removeProducts(Integer id) {
productsDAO.removeProducts(id);
}
}
Well, your ProductsServiceImpl class doesn't implement ProductsService... so there's no way that bean is injected in a field of type ProductsService.
From my experience, I just add #Repository at my DAO, maybe you can try to use it too
#Repository
public class ProductsDAO
{
}
How Spring autowire works is, Spring application context scans for all the classes inside the package and sub packages, specified by the component scan and internally creates a map by Type and Name. Incase of Type, value can be List of implementing classes, and by name its one.
Then whenever a #Autowire if encounter,
first it check by Type, so if you autowire using interface, it checks for all the implementation of that interface, and if only 1 if found then inject the same. (In case more then 1 is found, then you need to qaulify using the Qualifier and give proper name.
If above fails, if check by name, and injects.
If both fails, if gives NoSuchBeanDefinitionException,
So in your case, you have set the component scan, which is correct. Then while autowiring, you are giving Interface class name and the implementation class does not implements interface. So type check is failing, and also the by name is also failing, and hence you are getting NoSuchBeanDefinitionException.
To fix this, you will need to do what #JB Nizet is suggesting, so that #1 works and bean gets injected properly.
Add implements ProductService after public class ProductsServiceImpl
create a service interface and implement the interface method in service Impl class with #Overrride annotation.
public interface ProductService{
List<Product> getProducts();
}
And then
#Service
public class ProductsServiceImpl implements ProductService{
#Override
public List<Product> getProducts() {
return productRepository.findAll();
}
I want to use data caching with ehcache in my portlet. I use Spring MVC and liferay portal. If I want to use Cacheable annotation, empty data file is generated.
SocialGraphUI-portlet.xml
<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:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<context:component-scan base-package="socialgraphui" />
<cache:annotation-driven />
<cache:annotation-driven cache-manager="cacheManager" mode="proxy" proxy-target-class="true" />
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="/WEB-INF/ehcache.xml" p:shared="true" />
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehcache" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
</bean>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.GsonHttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
<bean class="org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<bean class="org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<!-- Spring MVC Message Source -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="useCodeAsDefaultMessage" value="true"/>
<property name="basenames">
<list>
<value>content.socialGraph</value>
</list>
</property>
</bean>
</beans>
ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="user.dir"/>
<defaultCache eternal="true" overflowToDisk="true" diskPersistent="true" />
<cache name="socialGraphCache" eternal="true" overflowToDisk="true" diskPersistent="true" />
</ehcache>
SocialGraphViewController.java
package socialgraphui.controller;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.liferay.portal.kernel.util.ParamUtil;
import socialgraphui.model.Edge;
import socialgraphui.model.Message;
import socialgraphui.model.Node;
import socialgraphui.model.SocialGraph;
import socialgraphui.service.SocialGraphService;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import org.apache.log4j.Logger;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.portlet.bind.annotation.ActionMapping;
import org.springframework.web.portlet.bind.annotation.RenderMapping;
import org.springframework.web.portlet.bind.annotation.ResourceMapping;
/**
*
* Controller for VIEW mode of portlet
*/
#Controller("socialGraphViewController")
#RequestMapping(value = "VIEW")
public class SocialGraphViewController{
Gson gson = new GsonBuilder().setPrettyPrinting().create();
private static final Logger logger = Logger.getLogger(SocialGraphViewController.class);
// -- auto-wiring of service dependency
#Autowired
#Qualifier("SGService")
private SocialGraphService socialGraphService;
public void setSocialGraphService(SocialGraphService service){
this.socialGraphService = service;
}
#ModelAttribute(value="socialgraph")
public SocialGraph getSocialGraph(){
return socialGraphService.getSocialGraph();
}
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(PersonDefinitionTypeList.class, new PersonDefinitionTypeListEditor());
}
#ActionMapping(SocialGraphPortletConstants.SUBMIT_FILTER)
public void handleActionRequest(ActionRequest request, ActionResponse response, PortletSession session)throws Exception {
logger.info("handleActionRequest in was executed");
...
}
#RenderMapping
public String handleRenderRequest(RenderRequest request, RenderResponse response, ModelMap model, Locale locale, PortletSession session) {
logger.info("handleRenderRequest was executed");
...
return SocialGraphPortletConstants.VIEW;
}
}
I want to cache result of service constructor, but not sure if I do it in proper way.
SocialGraphServiceImpl.java
import com.google.common.base.Function;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import socialgraphui.controller.SocialGraphViewController;
import socialgraphui.model.Discussion;
import socialgraphui.model.Edge;
import socialgraphui.model.Email;
import socialgraphui.model.Message;
import socialgraphui.model.Node;
import socialgraphui.model.PhoneCall;
import socialgraphui.model.SocialGraph;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
/**
*
*/
#Service(value="SGService")
public class SocialGraphServiceImpl implements SocialGraphService{
private SocialGraph socialgraph = new SocialGraph();
private CreateObjects crObjects = new CreateObjects();
public SocialGraphServiceImpl(){
this.fillGraph();
}
#Override
#Cacheable(value = "socialGraphCache")
public SocialGraph fillGraph(){
this.socialgraph = crObjects.createObjects();
return this.socialgraph;
}
}
And here is what I want to cache.
SocialGraph.java
package socialgraphui.model;
import java.io.Serializable;
import java.util.List;
public class SocialGraph implements Serializable{
private static final long serialVersionUID = -6977846672304367384L;
private List<Node> nodes;
private List<Edge> edges;
public List<Node> getNodes() {
return nodes;
}
public void setNodes(List<Node> nodes) {
this.nodes = nodes;
}
public List<Edge> getEdges() {
return edges;
}
public void setEdges(List<Edge> edges) {
this.edges = edges;
}
}
When I deploy the portlet, I don't get any errors, but generated cache file is empty.
I have same problem and it cause due to i didn't implement all object(class) that used in main object that i want to save in disk.
for more detail see this example.
public class User implements Serializable{
private Address address; // this object(class) not implements Serializable
}
so after implements for all class it works correctly.
I m building an app using Spring mvc and I am trying to access an http request from a bean outside the scope of the DispatcherServlet. I read similar posts and figured out that I need to add the RequestContextListener. However I keep getting the same error .Below you can see the controller and the bean I m injecting to the controller:
#Controller
public class ChargeController {
// Injected bean
#Autowired
public StripeCharger stripeCharger;
#RequestMapping(value = "/stripecharge", method = RequestMethod.POST)
public String chargeStripe(ModelMap model) {
// user`s custom code
String response = stripeCharger.charge();
}
}
part of the web.xml
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
The injected bean
package com.controller;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.stripe.Stripe;
import com.stripe.exception.StripeException;
import com.stripe.model.Charge;
public class StripeCharger {
public String token;
public StripeCharger()
{
HttpServletRequest curRequest = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
this.token = curRequest.getParameter("stripeToken");
}
}
-servlet.xml
<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:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<mvc:default-servlet-handler />
<mvc:annotation-driven />
<context:component-scan base-package="com.controller" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- This bean is auto-generated -->
<!-- define the bean to inject the Stripe charger -->
<bean id="StripeCharger" class="com.controller.StripeCharger" scope="request">
<aop:scoped-proxy/>
</bean>
</beans>
Anybody could help me with this issue? Thank you