【问题标题】:Getter returning null SessionFactoryGetter 返回 null SessionFactory
【发布时间】:2014-05-08 21:18:19
【问题描述】:

我正在尝试开发具有 springs 安全性的 Springs-Hibernate 登录应用程序。当我尝试使用 Hibernate 从数据库中检索用户时。我有正常工作的 Springs-Hibernate 配置。每次 getter 返回 sessionFactory null (我在 getSessionFactory 方法中打印地址)。我有一种方法 getLoginDetails() 如果我没有在登录时调用方法(仅使用简单的锚标记检查),它可以正常工作,但是当我登录时它不起作用。这是我的代码:

Springs-security.xml

<?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:security="http://www.springframework.org/schema/security"
   xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
  http://www.springframework.org/schema/security 
  http://www.springframework.org/schema/security/spring-security-3.1.xsd">

<!-- This is where we configure Spring-Security  -->
<security:http auto-config="true" use-expressions="true" access-denied-page="/auth/denied" >
    <security:intercept-url pattern="/auth/login" access="permitAll"/>
    <security:intercept-url pattern="/main/admin" access="hasRole('ROLE_ADMIN')"/>
    <security:intercept-url pattern="/main/common" access="hasRole('ROLE_USER')"/>
    <security:form-login
        login-page="/auth/login"
        authentication-failure-url="/auth/hi"
        authentication-success-handler-ref="myAuthenticationSuccessHandler"/>
    <security:logout
        invalidate-session="true"
        logout-success-url="/loggedout" />
</security:http>


<!-- A custom service where Spring will retrieve users and their corresponding access levels  -->
<bean id="customUserDetailsService" class="com.springs.service.CustomUserDetailsService"/>

<!--A service where spring will redirect to proper view after successfull login-->
<bean id="myAuthenticationSuccessHandler" class="com.springs.controller.MySimpleUrlAuthenticationSuccessHandler" />

<!-- Declare an authentication-manager to use a custom userDetailsService -->
<security:authentication-manager>
    <security:authentication-provider user-service-ref="customUserDetailsService">
    </security:authentication-provider>
</security:authentication-manager>
</beans>

ApplicationContext.xml:

<?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:p="http://www.springframework.org/schema/p"
   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-3.1.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
        <value>classpath:jdbc.properties</value>
    </property>
</bean>

<bean id="DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${jdbc.driverClassName}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="acquireIncrement" value="${c3p0.acquireIncrement}" />
    <property name="minPoolSize" value="${c3p0.minPoolSize}" />
    <property name="maxPoolSize" value="${c3p0.maxPoolSize}" />
    <property name="maxIdleTime" value="${c3p0.maxIdleTime}" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="DataSource"/>
    <property name="packagesToScan" value="com.hibernate.model" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
        </props>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/> 
</bean>
</beans>

调度程序-servlet.xml

<?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:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:task="http://www.springframework.org/schema/task"
       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-3.1.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
   http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
   http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- Scan only for @Controllers -->
<context:component-scan base-package="com.springs">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<mvc:annotation-driven />
<tx:annotation-driven/>
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="index">indexController</prop>
        </props>
    </property>
</bean>

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

<!--
The index controller.
-->
<bean name="indexController"
      class="org.springframework.web.servlet.mvc.ParameterizableViewController"
      p:viewName="index" />

</beans>

CustomerUserDetailsS​​ervice.java

package com.springs.service;
import com.hibernate.model.DbUser;
import com.springs.dao.UserDAO;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
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;

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

@Autowired
private UserDAO userDAO ;

@Override
public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException, DataAccessException {

    UserDetails user = null;

    try {
        DbUser dbUser;
        userDAO=new UserDAO();
        dbUser = userDAO.getLoginDetails(username);

        user = new User(
                dbUser.getUsername(),
                dbUser.getPassword().toLowerCase(),
                true,
                true,
                true,
                true,
                getAuthorities(dbUser.getAccess()));

    } catch (Exception e) {
        System.out.println("\n\n\n\n\n");
        e.printStackTrace();
        throw new UsernameNotFoundException("Error in retrieving user");
    }
    return user;
}


public Collection<SimpleGrantedAuthority> getAuthorities(Integer access) {
    List<SimpleGrantedAuthority> authList = new ArrayList<SimpleGrantedAuthority>(2);
    if (access.compareTo(1) == 0) {
        authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
    } else {
        authList.add(new SimpleGrantedAuthority("ROLE_USER"));
    }
    return authList;
}
}

UserDAO.java

@Repository
public class UserDAO {

@Autowired
private SessionFactory sessionFactory;

public SessionFactory getSessionFactory() {
    System.out.println("session factory: "+sessionFactory);
    return sessionFactory;
}

public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
}

public int getdata(String username) {
    String hql = "select count(*) from Userdetails";
    Userdetails u = (Userdetails) getSessionFactory().openSession().get(Userdetails.class, username);
    System.out.println(u.getName());
    Long l = (Long) getSessionFactory().openSession().createQuery(hql).uniqueResult();
    return l.intValue();

}

public DbUser getLoginDetails(String username) {
    DbUser user = new DbUser();
    Userdetails u = (Userdetails) getSessionFactory().openSession().get(Userdetails.class, username);
    user.setUsername(u.getName());
    user.setPassword(u.getPassword());
    user.getAccess();
    Set userroles = u.getUserroles();
    Iterator it = userroles.iterator();
    while (it.hasNext()) {
        Userrole ux=(Userrole) it.next();
        user.setAccess(ux.getRollid());
    }
    System.out.println("accss is: "+user.getAccess());
    System.out.println("username is: "+user.getUsername());
    System.out.println("pw is "+user.getPassword());

    return user;
}
}

服务器日志中的消息:

SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/SpringSecurity] threw exception [Request processing failed; nested exception is        java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at com.springs.dao.UserDAO.getdata(UserDAO.java:42)
at com.springs.controller.testController.getUser(testController.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)

如果我在登录活动中使用 sessionFactory,我无法确定它是否为空,否则它不为空。首先,我在 xml 中缺少 tx 注释,后来我为 @Transactional 注释添加了该注释。我该如何解决这个问题?

【问题讨论】:

    标签: java spring hibernate spring-security


    【解决方案1】:

    对不起,我没有看到问题。但我想附上 myy 示例项目中关于安全性的类似文件。希望对你有帮助:

    applicationContext-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" 
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/security 
            http://www.springframework.org/schema/security/spring-security-3.1.xsd
            ">
        <!-- HTTP security configurations -->
        <http auto-config="true" use-expressions="true">
            <form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t" />
            <logout logout-url="/resources/j_spring_security_logout" />
            <!-- Configure these elements to secure URIs in your application -->
            <intercept-url pattern="/login-user/**" access="hasRole('ROLE_ADMIN')" />
            <intercept-url pattern="/choices/**" access="hasRole('ROLE_ADMIN')" />
            <intercept-url pattern="/member/**" access="isAuthenticated()" />
            <intercept-url pattern="/resources/**" access="permitAll" />
            <intercept-url pattern="/login/**" access="permitAll" />
            <intercept-url pattern="/**" access="isAuthenticated()" />
        </http>
        <!-- Configure Authentication mechanism -->
        <authentication-manager alias="authenticationManager">
            <!-- SHA-256 values can be produced using 'echo -n your_desired_password | sha256sum' (using normal *nix environments) -->
            <authentication-provider>
                <password-encoder hash="sha-256" />
                <user-service>
                    <user name="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" authorities="ROLE_ADMIN" />
                    <user name="user" password="04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb" authorities="ROLE_USER" />
                </user-service>
            </authentication-provider>
        </authentication-manager>
    </beans:beans>
    

    applicationContext.xml:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <beans 
        xmlns="http://www.springframework.org/schema/beans" 
        xmlns:aop="http://www.springframework.org/schema/aop" 
        xmlns:context="http://www.springframework.org/schema/context" 
        xmlns:jee="http://www.springframework.org/schema/jee" 
        xmlns:tx="http://www.springframework.org/schema/tx" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context-3.2.xsd
            http://www.springframework.org/schema/jee 
            http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
            ">
    
        <context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>
        <context:spring-configured/>
        <context:component-scan base-package="org.sample.login">
            <context:exclude-filter expression=".*_Roo_.*" type="regex"/>
            <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
        </context:component-scan>
        <bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
            <property name="driverClassName" value="${database.driverClassName}"/>
            <property name="url" value="${database.url}"/>
            <property name="username" value="${database.username}"/>
            <property name="password" value="${database.password}"/>
            <property name="testOnBorrow" value="true"/>
            <property name="testOnReturn" value="true"/>
            <property name="testWhileIdle" value="true"/>
            <property name="timeBetweenEvictionRunsMillis" value="1800000"/>
            <property name="numTestsPerEvictionRun" value="3"/>
            <property name="minEvictableIdleTimeMillis" value="1800000"/>
            <property name="validationQuery" value="SELECT version();"/>
        </bean>
        <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory"/>
        </bean>
        <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
        <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
            <property name="persistenceUnitName" value="persistenceUnit"/>
            <property name="dataSource" ref="dataSource"/>
        </bean>
    </beans>
    

    MyUser.java:

    package org.sample.login.domain;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Table;
    import javax.persistence.Version;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Size;
    
    @Table(name = "my_user")
    @Entity
    public class MyUser {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "id")
        private Long id;
    
        @Version
        @Column(name = "version")
        private Integer version;
    
        /**
         */
        @NotNull
        @Size(min = 6)
        private String name;
    
        /**
         */
        @NotNull
        @Size(min = 6)
        private String password;
    
        @Override
        public String toString() {
            return "MyUser [name=" + name + ", password=" + password + "]";
        }
    
    
    
        public String getName() {
            return this.name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPassword() {
            return this.password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public Long getId() {
            return this.id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public Integer getVersion() {
            return this.version;
        }
    
        public void setVersion(Integer version) {
            this.version = version;
        }
    }
    

    【讨论】:

    • 我调试了我的项目,发现 userDAO(在 customerUserDetailsS​​ervice 中自动装配)为空。你能建议我解决这个问题吗?
    猜你喜欢
    • 2021-05-04
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 2020-01-26
    • 1970-01-01
    • 2016-07-01
    • 1970-01-01
    • 2018-06-02
    相关资源
    最近更新 更多