2013-08-05 122 views
0

我一直在爲Spring MVC + Spring Security + hibernate做一個登錄頁面的例子,但現在我遇到了一個問題,燃料@Autowire一直給我空值。服務器不報告任何錯誤,只是它沒有完成操作。Autowired Field is Null

CustomUSerDetailsS​​ervice.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; 

    } 

} 

這裏領域userDao保持beign空,因此當我嘗試使用userDao.getUsuario(username)操作只是不繼續,它不報告錯誤或類似它只是給了我一個404-錯誤

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> 

我不知道什麼是缺失,所以任何想法的歡迎,在此先感謝。

編輯: 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; 
     } 
    } 

} 

試圖與UsuarioDaoImp添加一個bean我得到這個錯誤後:

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); 
    } 

} 

我想我在短關於這個問題的知識,那爲什麼我要跟着一個例子,但我結束了因此,如果我沒有正確地給出信息或者我誤解了概念,我很抱歉。

彈簧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> 
+0

你在哪裏創建UsuarioDaoImp豆? –

+0

好吧,它是由彈簧使用註釋@@ UsuarioDaoImp – Ccortina

回答

3

您是如何訪問CustomUSerDetailsS​​ervice類?我希望你沒有在安全配置文件或其他任何spring配置文件中添加這個類作爲bean?

Editted: 您的服務bean被註解爲@服務,你也宣佈它在XML中,春天已經創建了兩個服務組件一個基於@Service註釋(完全組裝爲autowried)和第二使用XML配置(我假設你沒有注入dao依賴關係),所以第二個沒有設置dao對象。由於您正在使用安全配置中聲明的服務bean的bean名稱,因此在調試時將userDao設置爲null。

要麼在安全xml中註釋顯式bean定義,直接使用ref =「customUSerDetailsS​​ervice」作爲@service註釋已在spring上下文中添加具有此名稱的bean。

即註釋/刪除這條線在你的安全配置和每件事情應該工作。

<beans:bean class="com.carloscortina.paidosSimple.service.CustomUserDetailsService" id="customUserDetailsService"></beans:bean> 

當你註解爲@組件/ @服務春豆增添與名稱的豆等於短類名(首字母小寫),所以豆名稱爲「customUserDetailsS​​ervice」已經存在,在明確界定它xml重寫它。

或宣佈所有的bean定義(包括有依賴性)明確它的XML配置

+0

wel ..是的,我在安全xml中添加了一個bean。 – Ccortina

+0

所以現在有兩個服務bean,一個自動裝配正確,但沒有被使用,另一個在xml中沒有被userDao填充。嘗試在ref中使用服務bean名稱而不聲明xml中的服務bean – coder

+0

im很抱歉,但我該怎麼做?我仍然習慣春天的術語和概念。 – Ccortina

1

的DAO組件添加到組件掃描

<context:component-scan base-package="com.carloscortina.paidosSimple, com.carloscortina.paidosSimple.dao" /> 
+0

上的@@ Repository的線,謝謝,但它沒有工作.. userDao的價值保持良好的空 – Ccortina

+0

它是否拋出任何異常..你能顯示錯誤嗎? –

+0

那也是我的問題,它顯示沒有錯誤或例外。我只知道它的null,因爲我使用了Spring Tool Suite的調試並添加了一個breakline,並且它表示該值爲null。 – Ccortina