2010-09-05 11 views
13

Nella mia classe bean di filtro, ho aggiunto alcune dipendenze con i bean (con annotazione @Autowired). Ma nel metodo doFilter(), tutti i miei fagioli di dipendenza hanno nulla ...Utilizzo di alcuni bean nella classe Filter bean?

public class FacebookOAuth implements Filter 
{ 
@Autowired 
private BusinessLogger logger; 

@Autowired 
private IUserSessionInfo userSessionInfo; 

@Autowired 
private FacebookOAuthHelper oAuthHelper; 

public void init(FilterConfig fc) throws ServletException 
{ 
    // Nothing to do 
} 

public void doFilter(ServletRequest sr, ServletResponse sr1, FilterChain fc) throws IOException, ServletException 
{ 
    // HttpServletRequest req = (HttpServletRequest)sr; 
    HttpServletResponse res = (HttpServletResponse) sr1; 

    String code = sr.getParameter("code"); 

    if (StringUtil.isNotBlankStr(code)) 
    { 
     String authURL = this.oAuthHelper.getAuthURL(code); 

this.oAuthHelper è uguale a zero (e altri fagioli dipendenza a) ...

Potrebbe aiutarmi?


Infatti non utilizzo nozione MVC sul lato server (Spring). Per il mio cliente lato utilizzo la tecnologia Flex e il servlet BlazeDS comunica con il mio server.

Quindi, questo è il motivo, io uso il concetto di bean filtro.

Quindi, come posso gestire il mio concetto di bean di sessione nel mio bean Filtro?


Skaffman,

ho implementato la tua idea, quindi aggiorno il mio application.xml con:

<bean id="FacebookOAuthHandler" class="com.xx.FacebookOAuthHandler" /> 
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
    <property name="mappings"> 
    <props> 
     <prop key="/fbauth">FacebookOAuthHandler</prop>   
    </props> 
    </property> 
</bean> 

e la mia FacebookOAuthHandler classe:

public class FacebookOAuthHandler extends AbstractController 
{ 
@Autowired 
private BusinessLogger logger; 

@Autowired 
private IUserSessionInfo userSessionInfo; 

@Autowired 
private FacebookOAuthHelper oAuthHelper; 

@Override 
protected ModelAndView handleRequestInternal(HttpServletRequest request, 
     HttpServletResponse response) throws Exception { 

    // TODO 

    return null; 
} 

Ma, questo metodo handleRequestInt ernal non viene mai chiamato quando il mio URL è: http://xx.xx.xx.xx/MyApp/fbauth

+0

Come si presenta la configurazione della molla? – GaryF

risposta

12

Supponendo che questo Filter è cablato nel vostro web.xml, allora questo non è andare a lavorare, dal momento che non è riuscito entro la primavera, è gestito dal servlet container. Quindi cose come l'autowiring non funzioneranno.

Se si vuole definire un filtro servlet come Primavera di fagioli, allora avete bisogno di definirlo nel contesto di applicazione principale del webapp (utilizzando un ContextLoaderListener in web.xml), e poi defining a DelegatingFilterProxy che delega al bean gestito Primavera-a Fai il lavoro.

Tuttavia, è davvero necessario un filtro servlet per questo? Quello che so delle cose dell'autore di Facebook, potrebbe essere done just as easily with a Spring HandlerInterceptor. Questo sarebbe molto meno lavoro di configurazione di un filtro delegante.

+0

Ciao Skaffman! Grazie mille per la tua risposta. Sì, tutti i miei file di configurazione (web.xml e my application.xml) sono ok (con ContextLoaderListenner, con delegatingFilterProxy, ecc.). Ma, anche con questa configurazione, non posso usare bean nel mio filtro, giusto? – Anthony

+0

Potete per favore fornire alcuni esempi di codice su come definire un filtro servlet come bean spring? – Dejell

+0

In realtà ho visto http://pro-programmers.blogspot.co.il/2011/08/spring-bean-as-servlet-filter.html articolo, ma non sto usando SpringMCV. aiuterà? – Dejell

7

Guardate questa risposta sul sito della primavera: http://forum.springsource.org/showthread.php?60983-Autowiring-the-servlet-filter

In breve - è possibile forzare manualmente la primavera di applicare @Autowire annotazioni al filtro:

public void init(FilterConfig filterConfig) throws ServletException { 

    ServletContext servletContext = filterConfig.getServletContext(); 
    WebApplicationContext webApplicationContext = 
      WebApplicationContextUtils.getWebApplicationContext(servletContext); 

    AutowireCapableBeanFactory autowireCapableBeanFactory = 
      webApplicationContext.getAutowireCapableBeanFactory(); 

    autowireCapableBeanFactory.configureBean(this, BEAN_NAME); 
} 
5

so che una domanda ormai vecchio, ma non vi è alcun esempio di utilizzo di DelegatingFilterProxy nelle risposte correnti e una domanda recente che richiede un tale esempio è stata contrassegnata come duplicata per questo.

Quindi un DelegatingFilterProxy è un filtro speciale che conosce la radice ApplicationContext e delega il suo doFilter a un bean.

Esempio: MyFilter è una classe che implementa Filter, e myFilter è un fagiolo molla

<bean id=myFilter class="org.example.MyFilter ...>...</bean> 

o in una classe di configurazione

@Bean 
public MyFilter myFilter() { 
    MyFilter myFilter = new MyFilter(); 
    //initialization ... 
    return myFilter; 
} 

In web.xml, basta dichiarare un DelegatingFilterProxy con la stessa nome come bean:

<filter> 
    <filter-name>myFilter</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>myFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

Che w come, myBean è un vero bean, può essere iniettato normalmente con altri bean con annotazioni @Autowired e il suo metodo doFilter verrà chiamato dallo DelegatingFilterProxy. Poiché è possibile utilizzare i metodi spring init e destroy, per impostazione predefinita i metodi init e destroy non verranno chiamati, a meno che non si specifica il filtro "targetFilterLifecycle" come "true".

+0

Sto provando a farlo nel mio progetto, ma all'avvio del server, viene generato un errore: Severe: filtro iniziale di eccezione myFilter org.springframework.beans.factory.NoSuchBeanDefinitionException: Nessun bean denominato 'myFilter' è definito. Ho provato a configurare tramite XML e annotazione. Sembra che web.xml sia letto prima che il bean sia configurato. – Alex

+0

L'ho usato in molti progetti e non ho mai avuto problemi.Ma il bean deve essere dichiarato nel contesto root, non in dispatcher-servlet one. Dovresti mostrare come dichiari il tuo fagiolo. –

+0

Mi dispiace per la mia disponibilità, ma come posso dichiarare un bean nel contesto root o dispatcher-servlet? Ho appena creato una classe di configurazione in cui ho inserito un'annotazione "@Configuration", quindi ho creato un "@Bean" (riferendosi alla classe myFilter). – Alex

27

stavo affrontando lo stesso problema e la mia prima idea era quella di forzare manualmente primavera per applicare l'annotazione @Autowired al filtro come qui proposto

http://forum.springsource.org/showthread.php?60983-Autowiring-the-servlet-filter

ma non mi piace l'idea di hardcoding del nome del bean nella mia classe Java.

ho trovato un modo più pulito che funziona così:

public void init(FilterConfig filterConfig) throws ServletException { 
    SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, 
      filterConfig.getServletContext()); 
} 
+1

Grazie mille. Questo funziona davvero per me. :) – Akash5288

1

mi è stato sempre puntatore nullo durante l'accesso a un servizio classe bean in classe filtro con autowiring. Ho cercato più di 100 collegamenti ma non sono riuscito a trovare una soluzione. Sto usando Spring Boot Application e configurazione richiesta per ottenere bean nella classe filtro:

FilterConfig.java che fornisce l'oggetto contesto dell'applicazione.

@Component 
public class FilterConfig implements ApplicationContextAware{ 

private static ApplicationContext context; 


public static ApplicationContext getApplicationContext() { 
     return context; 
    } 
public static <T> T getBean(String name,Class<T> aClass){ 
    return context.getBean(name,aClass); 
} 

@Override 
public void setApplicationContext(ApplicationContext ctx) throws BeansException { 
    context = ctx; 
} 

} 

in classe filtro, ho usato questo come:

UserService userService =FilterConfig.getBean("UserService", UserService.class); 

UserService questo è il nome di fagiolo che è menzionato nel

@Service("UserService") 
    public class UserServiceImpl implements UserService { ...} 

No Configurazione nella classe principale del Boot primavera: SpringBootServletInitializer

Problemi correlati