为什么我从spring security获得“Null指针异常”?

时间:2016-03-30 22:02:08

标签: hibernate spring-mvc spring-security

我是Spring Security的新手并且无法理解为什么我继续使用“Null Pointer Exception”消息,我阅读其他帖子并做了一些更改但仍然遇到此错误。它似乎不与我的数据库通信。请帮我。感谢

这是我的代码: 调度员servlet.xml中

><?xml version="1.0" encoding="UTF-8"?>
<beans 
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd

">

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp"/>

<bean id="filterMultipartResolver" 
      class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 
    <property name="maxUploadSize" value="-1" />
</bean> 

<!-- a chaque espace de nom correspond un schema, les 2 points sont suivis d'un prefixe -->
<!-- Dans schema location: A chaque schema est associe un fichier xsd  -->
<context:component-scan base-package="demos.controller"/>

<mvc:annotation-driven/>
<tx:annotation-driven/>
<context:annotation-config/>

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

<!-- Spring s'adresse au conteneur JPA de Glassfish. Le fichier persistence.xml situé dans META-INF du classpath est utilisé -->
<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/springsecuritybasicJNDI" />

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>

<!--  Dao -->
<bean id="roleDAO" class="demos.dao.RoleDAOImpl"/>
<bean id="userDAO" class="demos.dao.UserDAOImpl"/>


<bean id="domainUser" class="demos.model.User" scope="session">
    <aop:scoped-proxy />
</bean>


</beans>

Spring Security.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">


    <http auto-config="true" use-expressions="true">
        <access-denied-handler error-page="/403Page.html"/>
        <intercept-url pattern="/sec/*" access="hasAnyRole('ROLE_MODERATOR','ROLE_ADMIN')" />
        <intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')" />

        <form-login login-page="/user-login.html"
            default-target-url="/success-login.html"
             authentication-failure-url="/error-login.html"
             login-processing-url="/j_spring_security_check"/>

        <logout logout-success-url="/success-logout.html"
         logout-url="/j_spring_security_logout"
          invalidate-session="true" />

    </http>

    <authentication-manager>
        <authentication-provider user-service-ref="MyUserDetail">
            <password-encoder hash="plaintext" />
        </authentication-provider>
    </authentication-manager>

    <beans:bean id="MyUserDetail" class="demos.service.CustomUserDetailsService" autowire="byType" />

</beans:beans>

我的customerDetailsS​​ervice:

package demos.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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 demos.dao.UserDAO;


@Service
@Transactional(readOnly=true)
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserDAO userDAO;    

    public UserDetails loadUserByUsername(String login)
            throws UsernameNotFoundException {

        // Declare a null Spring User
        UserDetails user = null;

        System.out.println("serviceLogin: "+login);
        demos.model.User domainUser = userDAO.getUser(login);

        if(domainUser == null){
            throw new UsernameNotFoundException("UserName "+login+" not found");
        }

        boolean enabled = true;
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;
System.out.println("loginuser: " + domainUser.getLogin() );

        user = new User(
                domainUser.getLogin(), 
                domainUser.getPassword(), 
                enabled, 
                accountNonExpired, 
                credentialsNonExpired, 
                accountNonLocked,
                getAuthorities(domainUser.getRole().getId()) );

        return user;

    }


    public Collection<? extends GrantedAuthority> getAuthorities(Integer role) {
        List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role));
        return authList;
    }

    public List<String> getRoles(Integer role) {

        List<String> roles = new ArrayList<String>();

        if (role.intValue() == 1) {
            roles.add("ROLE_MODERATOR");
            roles.add("ROLE_ADMIN");
        } else if (role.intValue() == 2) {
            roles.add("ROLE_MODERATOR");
        }
        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:

package demos.dao;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import org.springframework.stereotype.Repository;

import demos.model.User;


@Repository
public class UserDAOImpl implements UserDAO {

    @PersistenceContext
    private EntityManager em;


    @Override
    public User getUser(String login) {

        System.out.println("daoLogin1: "+ login);

        List<User> userList = new ArrayList<User>();

        System.out.println("daoLogin2: "+login);

        String query = "select u from User u where u.login like ?1 ";
        TypedQuery<User> q = em.createQuery(query,User.class); 
        q.setParameter(1, login);
//      q.setParameter(1, '%'+login+'%');
        userList = q.getResultList();
        if (userList.size() > 0)
            return userList.get(0);
        else
            return null;    
    }

}

以下是UserService层:

package demos.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import demos.dao.UserDAO;
import demos.model.User;

    @Service
    @Transactional
    public class UserServiceImpl implements UserService {

        @Autowired
        private UserDAO userDAO;

        public User getUser(String login) {
            return userDAO.getUser(login);
        }


}

用户类:

package demos.model;

import java.io.Serializable;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="users")
public class User implements Serializable{

    @Id
    @GeneratedValue
    private Integer id;

    private String login;

    private String password;

    @OneToOne(cascade=CascadeType.ALL)
    @JoinTable(name="user_roles",
        joinColumns = {@JoinColumn(name="user_id", referencedColumnName="id")},
        inverseJoinColumns = {@JoinColumn(name="role_id", referencedColumnName="id")}
    )
    private Role role;


    //getter et setter

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", login=" + login + ", password=" + password
                + ", role=" + role + "]";
    }


}

使用角色类:

package demos.model;

import java.io.Serializable;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="roles")
public class Role implements Serializable{

    @Id
    @GeneratedValue
    private Integer id;

    private String role;

    @OneToMany(cascade=CascadeType.ALL)
    @JoinTable(name="user_roles", 
        joinColumns = {@JoinColumn(name="role_id", referencedColumnName="id")},
        inverseJoinColumns = {@JoinColumn(name="user_id", referencedColumnName="id")}
    )
    private Set<User> userRoles;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public Set<User> getUserRoles() {
        return userRoles;
    }

    public void setUserRoles(Set<User> userRoles) {
        this.userRoles = userRoles;
    }

    @Override
    public String toString() {
        return "Role [id=" + id + ", role=" + role + ", userRoles=" + userRoles
                + "]";
    }


}

以下是我收到的消息:

Caused by: java.lang.NullPointerException
    at demos.service.CustomUserDetailsService.loadUserByUsername(CustomUserDetailsService.java:34)
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:114)
    ... 56 more

|Infos: serviceLogin: adm

如果您需要更多详细信息,请告诉我,但我看不出有什么问题。

1 个答案:

答案 0 :(得分:0)

UserDao未注入CustomUserDetailsService,因为它们是在不同的Spring上下文中定义的(在本例中为xml文件)。

如果必须将这些定义保存在不同的上下文中,请考虑将其中一个导入另一个。