2016-08-13 3 views
1

web.xml verwenden:, wie ich @Transactional und session Bohne in Servlet-Filter mit Feder

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> 
    <context-param> 
    <param-name>contextClass</param-name> 
    <param-value> 
      org.springframework.web.context.support.AnnotationConfigWebApplicationContext 
     </param-value> 
    </context-param> 

    <context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>com.phoenix.config.ApplicationConfig</param-value> 
    </context-param> 

    <listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 

    <servlet> 
    <servlet-name>dispatcher</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextClass</param-name> 
     <param-value> 
     org.springframework.web.context.support.AnnotationConfigWebApplicationContext 
     </param-value> 
    </init-param> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>com.phoenix.config.MvcConfig</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
    <servlet-name>dispatcher</servlet-name> 
    <url-pattern>/</url-pattern> 
    </servlet-mapping> 
    <filter> 
    <filter-name>authenticationFilter</filter-name> 
    <filter-class> 
    com.phoenix.authentication.AuthenticationFilter 
    </filter-class> 
    </filter> 
    <filter> 
    <filter-name>authorizationFilter</filter-name> 
    <filter-class> 
    com.phoenix.authentication.AuthorizationFilter 
    </filter-class> 
    </filter> 
    <filter-mapping> 
    <filter-name>authenticationFilter</filter-name> 
    <url-pattern>/login/*</url-pattern> 
    </filter-mapping> 
    <filter-mapping> 
    <filter-name>authorizationFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
    </filter-mapping> 
    <error-page> 
    <exception-type>java.lang.Exception</exception-type> 
    <location>/ErrorHandler</location> 
    </error-page> 

    <servlet> 
    <servlet-name>PhoenixExceptionHandler</servlet-name> 
    <servlet-class>com.phoenix.authentication.PhoenixExceptionHandler</servlet-class> 
    </servlet> 
    <servlet-mapping> 
    <servlet-name>PhoenixExceptionHandler</servlet-name> 
    <url-pattern>/ErrorHandler</url-pattern> 
    </servlet-mapping> 
</web-app> 

Kontextkonfigurationsklasse:

package com.phoenix.config; 

import java.util.Properties; 

import javax.sql.DataSource; 

import org.hibernate.SessionFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.PropertySource; 
import org.springframework.core.env.Environment; 
import org.springframework.http.HttpHeaders; 
import org.springframework.jdbc.datasource.DriverManagerDataSource; 
import org.springframework.orm.hibernate5.HibernateTransactionManager; 
import org.springframework.orm.hibernate5.LocalSessionFactoryBean; 
import org.springframework.transaction.annotation.EnableTransactionManagement; 

@Configuration 
@EnableTransactionManagement 
@ComponentScan({ "com.phoenix" }) 
@PropertySource(value = { "classpath:hibernate.properties" }) 
public class ApplicationConfig { 

    @Autowired 
    private Environment environment; 

    @Bean 
    public LocalSessionFactoryBean sessionFactory() { 
     LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); 
     sessionFactory.setDataSource(dataSource()); 
     sessionFactory.setPackagesToScan("com.phoenix.data.entity"); 
     sessionFactory.setHibernateProperties(hibernateProperties()); 
     return sessionFactory; 
    } 

    @Bean 
    public DataSource dataSource() { 
     DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
     dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName")); 
     dataSource.setUrl(environment.getRequiredProperty("jdbc.url")); 
     dataSource.setUsername(environment.getRequiredProperty("jdbc.username")); 
     dataSource.setPassword(environment.getRequiredProperty("jdbc.password")); 
     return dataSource; 
    } 

    private Properties hibernateProperties() { 
     Properties properties = new Properties(); 
     properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect")); 
     properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql")); 
     return properties; 
    } 

    @Bean 
    @Autowired 
    public HibernateTransactionManager transactionManager(SessionFactory s) { 
     HibernateTransactionManager txManager = new HibernateTransactionManager(); 
     txManager.setSessionFactory(s); 
     return txManager; 
    } 
    @Bean 
    public HttpHeaders responseHeader(){ 
    HttpHeaders responseTypeHeader = new HttpHeaders(); 
    responseTypeHeader.add("Content-Type", "application/json; charset=utf-8"); 
    return responseTypeHeader; 
    } 
} 

Dispatcher-Konfigurationsklasse:

package com.phoenix.config; 

import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.web.servlet.config.annotation.EnableWebMvc; 
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry; 
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 
import org.springframework.web.servlet.view.InternalResourceViewResolver; 

@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages = "com.phoenix") 
public class MvcConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void addResourceHandlers(ResourceHandlerRegistry registry) { 
     registry.addResourceHandler("/resources/**") 
     .addResourceLocations("/WEB-INF/resources/"); 
    } 

    @Override 
    public void configureViewResolvers(ViewResolverRegistry registry) { 
     InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); 
     viewResolver.setPrefix("/WEB-INF/views/"); 
     viewResolver.setSuffix(".jsp"); 
     registry.viewResolver(viewResolver); 
    } 


} 

Filterklasse:

package com.phoenix.authentication; 

import java.io.IOException; 
import java.util.List; 

import javax.persistence.Query; 
import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.FilterConfig; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.http.HttpServletRequest; 

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

import com.phoenix.data.entity.UserInfo; 


public class AuthenticationFilter implements Filter { 

    @Autowired 
    SessionFactory sessionFactory; 



    @Override 
    public void destroy() { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException { 
    HttpServletRequest httpRequest = (HttpServletRequest) request; 
    if(httpRequest.getParameter("username") != null 
      && httpRequest.getParameter("password") != null) 
    { 
     String username = httpRequest.getParameter("username"); 
     String password = httpRequest.getParameter("password"); 
     boolean rememberMe = false; 
     if(httpRequest.getParameter("rememberMe")!= null) 
      rememberMe = httpRequest.getParameter("rememberMe").equals("on"); 

     UserInfo user = getUserInfo(username, password); 
     System.out.print(user+"\n"+rememberMe); 

    } 
    chain.doFilter(request, response); 
    } 

    @Override 
    public void init(FilterConfig arg0) throws ServletException { 

    } 

    public UserInfo getUserInfo(String username, String password) 
    { 
     UserInfo user=null; 
     Session session=sessionFactory.getCurrentSession(); 
     Query query = session.createQuery("FROM UserInfo WHERE" 
       + " UserInfo.username = :xusername AND UserInfo.password = :xpassword"); 
     query.setParameter("xusername",username); 
     query.setParameter("xpassword",password); 
     List list=query.getResultList(); 
     if (list.size()>0) 
      user=(UserInfo)list.get(0); 
     return user; 
    } 

} 

Ausnahme:

Aug 13, 2016 5:02:39 PM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/phoenix] threw exception 
java.lang.NullPointerException 
    at com.phoenix.authentication.AuthenticationFilter.getUserInfo(AuthenticationFilter.java:65) 
    at com.phoenix.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:50) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Unknown Source) 

Ich habe ein wenig Suche und die Lösung org.springframework.web.filter.DelegatingFilterProxy kam. Aber diese Lösung ist für mich etwas vage. Ich bin dankbar, wenn ich das erkläre.

Antwort

0

Sie können @Autowired nicht in Ihrem AuthenticationFilter verwenden, da es nicht in Spring Container instanziiert wird. Es wird in dem Webanwendungscontainer instanziiert, so dass sessionFactory immer null sein wird, also NullPointerException.

Sie können den WebApplicationContext jedoch innerhalb eines Filters abrufen, indem Sie WebApplicationContextUtils.getRequiredWebApplicationContext verwenden, das von Spring bereitgestellt wird.

Also mit der modifizierten AuthenticationFilter.init Methode wie unten, sollte Ihr Filter funktionieren.

public class AuthenticationFilter implements Filter { 

    SessionFactory sessionFactory; 

    @Override 
    public void destroy() { 
     this.sessionFactory.close(); 
     this.sessionFactory = null;  
    } 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException { 
    HttpServletRequest httpRequest = (HttpServletRequest) request; 
    if(httpRequest.getParameter("username") != null 
      && httpRequest.getParameter("password") != null) 
    { 
     String username = httpRequest.getParameter("username"); 
     String password = httpRequest.getParameter("password"); 
     boolean rememberMe = false; 
     if(httpRequest.getParameter("rememberMe")!= null) 
      rememberMe = httpRequest.getParameter("rememberMe").equals("on"); 

     UserInfo user = getUserInfo(username, password); 
     System.out.print(user+"\n"+rememberMe); 

    } 
    chain.doFilter(request, response); 
    } 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
     WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext()); 
     this.sessionFactory = ctx.getBean(SessionFactory.class); 
    } 

    public UserInfo getUserInfo(String username, String password) 
    { 
     UserInfo user=null; 
     Session session=sessionFactory.getCurrentSession(); 
     Query query = session.createQuery("FROM UserInfo WHERE" 
       + " UserInfo.username = :xusername AND UserInfo.password = :xpassword"); 
     query.setParameter("xusername",username); 
     query.setParameter("xpassword",password); 
     List list=query.getResultList(); 
     if (list.size()>0) 
      user=(UserInfo)list.get(0); 
     return user; 
    } 

} 
+0

danke für Ihre Antwort @shazin. aber ohne Transaktion arbeitet diese Lösung. Ich habe Transactional Annotation für getUserInfo() -Methode verwendet, funktioniert aber immer noch nicht ... Ich habe die Transaktion tx = session.beginTransaction() und tx.commit() verwendet. Aber es hat nicht funktioniert. In beiden Fällen tritt diese Ausnahme auf: HibernateException: Transaktionssynchronisierte Sitzung konnte nicht für den aktuellen Thread – yousef

+0

@yousef abgerufen werden. Warum denken Sie, dass Sie eine Transaktion für eine Abfrage benötigen, die keinen Inhalt ändert? – shazin

+0

Funktioniert nicht ohne Transaktion und diese Ausnahme tritt auf: HibernateException: Transaktionssynchronisierte Sitzung für aktuellen Thread konnte nicht abgerufen werden. Deshalb denke ich, dass Transaktion für getCurrentSession ... essentiell ist. – yousef

Verwandte Themen