我正在使用Java EE,Spring,EclipseLink和Glassfish服务器开发Web应用程序。
我的应用程序工作正常之后,我尝试更改我的bean配置,以便向Spring注入实体管理器并实现更好的事务管理......我没有让它工作......(之前我有它完全相同,除了我必须在每个数据库请求之前调用emf.createEntityManager()。)
以下是我的配置文件:
的web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<!-- jsp config => automatic inclusions in all jsp files -->
<jsp-config>
<jsp-property-group>
<url-pattern>/WEB-INF/views/*</url-pattern>
<include-prelude>taglibs.jsp</include-prelude>
<include-prelude>setLanguage.jsp</include-prelude>
</jsp-property-group>
</jsp-config>
<display-name>MEANS</display-name>
<!-- Beans in these files will makeup the configuration of the root web
application context -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/applicationContext.xml</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Deploys the 'dispatcher' dispatcher servlet whose configuration resides
in /WEB-INF/spring/mvc-config.xml -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/mvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern><!-- detect all urls ending with ".do" -->
</servlet-mapping>
<!-- Security Spring filter -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>30</session-timeout><!-- the session is automatically
disconnected after 30 min of inactivity -->
</session-config>
<listener id="myLogger">
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.do</welcome-file>
</welcome-file-list>
</web-app>
安全-config.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:util="http://www.springframework.org/schema/util"
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/util
http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:authentication-manager><!-- custom authentication manager-->
<security:authentication-provider
user-service-ref="userService">
<security:password-encoder ref="passwordEncoder">
<security:salt-source user-property="username" />
</security:password-encoder>
</security:authentication-provider>
</security:authentication-manager>
<bean id="passwordEncoder"
class="org.springframework.security.authentication.encoding.MessageDigestPasswordEncoder">
<constructor-arg value="MD5" />
</bean>
<bean id="userService" class="fr.services.security.MyUserDetailsService"><!-- custom userDetailService -->
<constructor-arg ref="myDAOFactory"/>
</bean>
<!-- disable authentication for those free access components-->
<security:http pattern="/login.jsp*" security="none" />
<security:http pattern="/disconnected.jsp*" security="none" />
<security:http pattern="/css/**" security="none" />
<security:http pattern="/javascript/**" security="none" />
<security:http pattern="/jquery/**" security="none" />
<security:http access-denied-page="/denied.jsp" use-expressions="true">
<security:form-login login-page="/login.jsp"
authentication-failure-url="/login.jsp?errorMessage=invalidConnection"
default-target-url='/index.do' always-use-default-target='false' />
<security:intercept-url pattern="/admin*.do"
access="hasRole('ROLE_ADMINISTRATEUR')" />
<security:intercept-url pattern="/access*.do"
access="isAnonymous() or isAuthenticated()" />
<security:intercept-url pattern="/**"
access="isAuthenticated()" />
<security:logout logout-success-url="/disconnected.jsp" />
</security:http>
</beans>
持久-config.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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="org.postgresql.Driver"
p:url="jdbc:postgresql://localhost:5432/databaseName"
p:username="postgres"
p:password="pwd" />
<tx:annotation-driven/>
<tx:jta-transaction-manager>
<property name="entityManagerFactory" ref="entityManagerFactory" />
</tx:jta-transaction-manager>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="databaseName" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>
应用context.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: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.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<import resource="persistence-config.xml"/>
<import resource="security-config.xml"/>
<context:component-scan base-package="fr" />
<context:annotation-config/>
<!-- Define the location of the property file to change properties dependent on the application environment -->
<context:property-placeholder location="/WEB-INF/configuration.properties" />
</beans>
MVC-config.xml中:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="persistence-config.xml"/>
<import resource="security-config.xml"/>
<!-- Spring MVC Support for annotations (JSR-303) -->
<mvc:annotation-driven>
</mvc:annotation-driven>
<context:component-scan base-package="fr.controller, fr.dao, fr.services" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/views/" p:suffix=".jsp" />
<bean id="urlMap" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map>
<entry key="accessPasswordLost.do" value-ref="urlFilenameViewController"/>
<entry key="documentation.do" value-ref="urlFilenameViewController"/>
<entry key="hierarchyDialog.do" value-ref="urlFilenameViewController"/>
<entry key="nameDialog.do" value-ref="urlFilenameViewController"/>
<entry key="openCopyDialog.do" value-ref="urlFilenameViewController"/>
<entry key="tableErosionParameterLS.do" value-ref="urlFilenameViewController"/>
<entry key="training.do" value-ref="urlFilenameViewController"/>
<entry key="userSettings.do" value-ref="urlFilenameViewController"/>
</map>
</property>
</bean>
<!-- For direct mapping between URL (i.e. index.htm index) and the JSP to render -->
<bean id="urlFilenameViewController"
class="org.springframework.web.servlet.mvc.UrlFilenameViewController">
</bean>
<import resource="aspects-config.xml"/>
</beans>
我不确定persistence-config和security-config的导入......
为了确保,您拥有所有信息,这里是MyDAOFactory类,它可以注入实体管理器:
/**
* A factory for creating DAO objects.
*/
@Component
public class MyDAOFactory implements IMyDAOFactory{
/** The map dao. */
private Map<Class<?>, IDao<?>> mapDAO;
/** The entity manager. */
@PersistenceContext(unitName="databaseName")
public EntityManager em;
/**
* Instantiates a new my dao factory.
*/
public MyDAOFactory() {
mapDAO = new HashMap<Class<?>, IDao<?>>();
}
/**
* Gets the em.
*
* @return the em
*/
public EntityManager getEm() {
return em;
}
/**
* Sets the em.
*
* @param emf the new em
*/
public void setEm(EntityManager em) {
this.em = em;
}
@Override
public <T extends Serializable> IDao<T> getBasicDAO(Class<T> entity) {
if(mapDAO.containsKey(entity)){
return (IDao<T>) mapDAO.get(entity);
}else{
BasicDAO<T> dao = new BasicDAO<T>(entity);
dao.setEm(em);
mapDAO.put(entity, dao);
return dao;
}
}
}
自定义UserDetailsService:
@Transactional
public class MyUserDetailsService implements UserDetailsService {
/** The my dao factory. */
IMyDAOFactory myDAOFactory;
/**
* Instantiates a new means user details service.
*
*/
public MyUserDetailsService(IMyDAOFactory myDAOFactory) {
this.myDAOFactory = myDAOFactory;
}
/* (non-Javadoc)
* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException{
IDao<Utilisateur> userDAO = this.myDAOFactory.getBasicDAO(Utilisateur.class);
Map<String, String> map = new HashMap<String, String>();
map.put("loginLdap", username);
Utilisateur user = userDAO.findByAttributes(map).get(0);
IMyUserDetails userDetails = new MyUserDetails(user.getLoginLdap(), user.getPwdLocal(), user.getActif(), user.getDateValidite().getTime()>System.currentTimeMillis(), true, true, AuthorityUtils.createAuthorityList("ROLE_"+user.getProfil().getNomProfil().toUpperCase()));
userDetails.setUser(user);
return userDetails;
}
}
当我在调试模式下启动服务器时,似乎在MyUserDetailsService中注入了myDAOFactory时设置了entitymanager,但是当我尝试登录到我的应用程序时,不知何时调用loadUserByName不再发生.. (虽然我没有改变配置的这一部分......)。
非常感谢任何帮助!
答案 0 :(得分:1)
一些指示:
不要在MVC配置中导入安全性和持久性配置,它们已在根应用程序上下文中定义(通过导入),其bean对MVC上下文可见
DriverManagerDataSource仅在测试中可用,最迟用生产池DataSource(例如通过JNDI查找的容器管理的DataSource)替换它
查看您的DataSource配置,您可能没有使用JTA。如果是,请删除<tx:jta-transaction-manager />
bean定义
调试以尝试查明问题。如果它是与持久性相关的,那么从最小的根应用上下文开始,只使用持久性(JPA)的东西和一个简单的bean来测试它:
<bean class="pkg.Test" init-method="persistence" />
如果您无法使其发挥作用,请在此处发布更多信息
答案 1 :(得分:0)
在尝试了几天所有可能的配置之后,我终于使用spring,eclipseLink和Glassfish为我的事务管理找到了正确的解决方案:
以下是我的更正,如果它有一天可以帮助某人:
的applicationContext.xml
<beans ...>
<import resource="persistence-config.xml"/>
<import resource="security-config.xml"/>
<context:component-scan base-package="fr.dao, fr.services" /><!-- do not scan the controllers here -->
<context:annotation-config/>
<!-- Define the location of the property file to change properties dependent on the application environment -->
<context:property-placeholder location="/WEB-INF/configuration.properties" />
</beans>
MVC-config.xml中
<beans >
<!-- Spring MVC Support for annotations (JSR-303) -->
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="fr.utils.CurrentUserWebArgumentResolver"></bean>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<context:component-scan base-package="fr.controller" /><!-- only scan controllers here -->
...
<import resource="aspects-config.xml"/>
</beans>
和persistence-config.xml:
<beans ...>
<tx:annotation-driven/>
<!-- We want to locate the container transaction manager -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="showSql" value="true" />
</bean>
</property>
<property name="jpaDialect">
<bean
class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
</property>
<property name="persistenceUnitName" value="databaseName"/>
<property name="persistenceUnitManager">
<bean
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager"/>
</property>
</bean>
<tx:jta-transaction-manager/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
</beans>