我一直在研究Spring MVC + Spring Security + hibernate的一个例子来创建一个登录页面,但现在我遇到了一个燃料@Autowire
的问题,它一直给我空值。服务器不会报告任何错误,只是它没有完成操作。
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;
}
}
此处字段userDao
保持beign null,因此当我尝试使用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 :(得分:3)
您如何访问CustomUSerDetailsService类?我希望你没有在安全配置文件或任何其他弹簧配置中将此类添加为bean?
<强> Editted:强> 你的服务bean用@service注释,你也用xml声明它,spring创建了两个服务bean,一个基于@service注释(完全填充为autowried),第二个使用xml配置(我假设你没有') t明确地注入dao依赖),所以第二个没有dao对象集。当您使用安全配置中声明的服务bean的bean名称时,您将在调试时将userDao设置为null。
要么在安全xml中注释显式bean定义,请直接使用ref =“customUSerDetailsService”,因为@service注释已经在spring上下文中添加了一个带有此名称的bean。
即。在安全配置中注释/删除此行,并且每件事都应该有效。
<beans:bean class="com.carloscortina.paidosSimple.service.CustomUserDetailsService" id="customUserDetailsService"></beans:bean>
当您使用@ component / @ service注释bean时,spring会添加一个名称等于short classname的bean(首字母小写),因此名称为“customUserDetailsService”的bean已经存在,在xml中显式定义它是覆盖它。
或者明确声明所有bean定义(包括那些依赖项)xml config
答案 1 :(得分:1)
将dao包添加到组件扫描
<context:component-scan base-package="com.carloscortina.paidosSimple, com.carloscortina.paidosSimple.dao" />