我尝试使用 Spring-MVC 和 Spring-Security 在 Java 上构建 Web 应用程序。在我需要从数据库中获取信息的一个模块中,我无法获取 SessionFactory。表单更多信息,这里是我的 java config 和其他文件源代码:WebAppConfig.java:
package com.sprsec.init;
import org.hibernate.SessionFactory;
import org.springframework.context.annotation.*;
import org.springframework.context.support.AbstractMessageSource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan("com.sprsec")
@PropertySource("classpath:application.properties")
@ImportResource("classpath:spring-security.xml")
public class WebAppConfig extends WebMvcConfigurerAdapter {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
private static final String PROPERTY_NAME_POOL_SIZE = "hibernate.pool_size";
@Resource
private Environment env;
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
sessionFactoryBean.setHibernateProperties(hibProperties());
return sessionFactoryBean;
}
@Bean
public SessionFactory getSessioFactory(){
return sessionFactory().getObject();
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put(PROPERTY_NAME_POOL_SIZE, env.getRequiredProperty(PROPERTY_NAME_POOL_SIZE));
return properties;
}
@Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
@Bean(name = "messageSource")
public AbstractMessageSource getMesageSource(){
return new DatabaseMessageSource(sessionFactory().getObject());
}
@Bean
public HandlerInterceptor localeChangeInterceptor(){
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
return localeChangeInterceptor;
}
@Bean
public UrlBasedViewResolver setupViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/pages/");
//resolver.setSuffix(".xhtml");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
registry.addInterceptor(localeChangeInterceptor);
}
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setDefaultLocale(StringUtils.parseLocaleString("en"));
return cookieLocaleResolver;
}
}
用户DAOImpl.java:
package com.sprsec.dao;
import com.sprsec.model.User;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
@Repository
public class UserDAOImpl implements UserDAO {
@Autowired
private SessionFactory sessionFactory;
private Session getSession(){
return sessionFactory.getCurrentSession();
}
public User getUser(String login) {
List<User> userList = new ArrayList<User>();
Query query = getSession().createQuery("from User u where u.login = :login");
query.setParameter("login", login);
System.out.println(query.getQueryString());
userList = query.list();
if (userList.size() > 0)
return userList.get(0);
else
return null;
}
public User getUserByLoginAndPassword(String login, String password){
Query query = getSession().createQuery("from User u where u.login = :login and u.password = :password");
query.setParameter("login", login);
query.setParameter("password", password);
User user = (User) query.uniqueResult();
return user;
}
}
在这里,在 UserDAOImpl.java 中,我检索了一个异常。会话工厂为空。我介意我的 WebAppConfig 类中存在什么问题,因为在 DatabaseMessageSource.java 中我检索到相同的异常,我将在配置中添加这个类,并在构造函数中放置 SessionFactory。我不想在那里添加每个需要这种依赖关系的类。
错误信息:
Caused by: java.lang.NullPointerException
at com.sprsec.init.DatabaseMessageSource.openSession(DatabaseMessageSource.java:95)
at com.sprsec.init.DatabaseMessageSource.getSQLDictionary(DatabaseMessageSource.java:104)
at com.sprsec.init.DatabaseMessageSource.loadTexts(DatabaseMessageSource.java:114)
at com.sprsec.init.DatabaseMessageSource.refreshProperties(DatabaseMessageSource.java:90)
at com.sprsec.init.DatabaseMessageSource.reload(DatabaseMessageSource.java:132)
at com.sprsec.init.DatabaseMessageSource.<init>(DatabaseMessageSource.java:35)
at com.sprsec.init.WebAppConfig.getMesageSource(WebAppConfig.java:90)
at com.sprsec.init.WebAppConfig$$EnhancerByCGLIB$$f4b941bb.CGLIB$getMesageSource$3(<generated>)
at com.sprsec.init.WebAppConfig$$EnhancerByCGLIB$$f4b941bb$$FastClassByCGLIB$$c1655200.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:286)
at com.sprsec.init.WebAppConfig$$EnhancerByCGLIB$$f4b941bb.getMesageSource(<generated>)
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.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:160)
... 57 more
数据库消息源.java:
public class DatabaseMessageSource extends AbstractMessageSource implements MessageSource {
private final Map<String, Map<String, String>> properties = new HashMap<String, Map<String, String>>();
@Autowired
private SessionFactory sessionFactory;
public DatabaseMessageSource() {
super();
//this.sessionFactory = sessionFactory;
this.setUseCodeAsDefaultMessage(true);
reload();
setParentMessageSource(this);
}
/**
* {@inheritDoc}
*/
@Override
protected String resolveCodeWithoutArguments(String code, Locale locale) {
return getText(code, locale);
}
/**
* {@inheritDoc}
*/
@Override
protected MessageFormat resolveCode(String code, Locale locale) {
String msg = getText(code, locale);
MessageFormat result = createMessageFormat(msg, locale);
return result;
}
/**
* @param code
* @param locale
* @return
*/
private String getText(String code, Locale locale) {
Map<String, String> localizedText = properties.get(locale.getLanguage());
System.out.println("===================================================");
System.out.println("requested code: "+code+" Result: "+localizedText.get(code));
System.out.println("===================================================");
String textForCurrentLanguage = null;
if (localizedText != null) {
textForCurrentLanguage = localizedText.get(code);
if (textForCurrentLanguage == null) {
saveKeyword(code);
reload();
return "__"+code;
}else if (textForCurrentLanguage.equals("")){
return "__"+code;
} else {
return textForCurrentLanguage;
}
} else {
return "__"+code;
}
}
/**
* @return properties which keeps localized text
*/
private Map<String, Map<String, String>> refreshProperties() {
properties.clear();
properties.putAll(loadTexts());
return properties;
}
public Session openSession(){
return sessionFactory.openSession();
}
private void saveKeyword(final String key){
Query query = openSession().createSQLQuery("insert into b_dictionary (keyword,lang_ru,lang_lv,lang_en) values ('"+key+"','','','')");
query.executeUpdate();
}
private Iterator getSQLDictionary(){
Query query = openSession().createSQLQuery("select m.keyword, m.lang_ru, m.lang_lv, m.lang_en from b_dictionary as m");
return query.list().iterator();
}
protected Map<String, Map<String, String>> loadTexts() {
Map<String, Map<String, String>> myProp = new HashMap<String, Map<String, String>>();
Map<String, String> dataRU = new HashMap<String, String>();
Map<String, String> dataLV = new HashMap<String, String>();
Map<String, String> dataEN = new HashMap<String, String>();
Iterator result = getSQLDictionary();
while( result.hasNext() ){
Object[] row = (Object[]) result.next();
String code = row[0].toString();
dataRU.put(code,row[1].toString());
dataLV.put(code,row[2].toString());
dataEN.put(code,row[3].toString());
}
myProp.put("ru", dataRU);
myProp.put("lv", dataLV);
myProp.put("en", dataEN);
return myProp;
}
/**
* Reload all codes.
*/
public void reload() {
refreshProperties();
}
}