我尝试使用Spring-MVC和Spring-Security在Java上构建Web应用程序。 在我需要从数据库获取信息的一个模块中,我无法获得SessionFactory。 形成更多信息,这里是我的java配置和其他文件源代码: 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;
}
}
UserDAOImpl.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中,我检索一个Exception。 SessionFactory为null。 我在想我的WebAppConfig类中存在什么问题,因为在DatabaseMessageSource.java中我检索了相同的异常,我在config中添加了这个类,并在构造函数中添加了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
DatabaseMessageSource.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();
}
}
答案 0 :(得分:3)
你的问题在这里:
new DatabaseMessageSource(sessionFactory().getObject());
Spring只能自动装配它管理的bean;如果您自己调用new
来创建bean,则@Autowired
字段不会被填充(并且不会调用@PostConstruct
之类的方法)。该字段应在@Bean
方法返回后填写,但如果您需要在bean的构造函数中访问它,则必须将其作为参数传递。首选解决方案是将依赖于@Autowired
设置的代码移动到使用@PostConstruct
注释的方法中。
答案 1 :(得分:-1)
尝试使用AnnotationSessionFactoryBean
代替LocalSessionFactoryBean
LocalSessionFactoryBean sessionFactoryBean = new AnnotationSessionFactoryBean();