Spring: come si inserisce un HttpServletRequest in un bean con ambito di richiesta?


95

Sto cercando di impostare un bean con ambito di richiesta in primavera.

L'ho impostato con successo in modo che il bean venga creato una volta per richiesta. Ora, deve accedere all'oggetto HttpServletRequest.

Poiché il bean viene creato una volta per richiesta, immagino che il contenitore possa facilmente iniettare l'oggetto richiesta nel mio bean. Come lo posso fare ?

Risposte:


114

I bean con ambito di richiesta possono essere collegati automaticamente con l'oggetto richiesta.

private @Autowired HttpServletRequest request;

2
Esiste un vecchio metodo XML per questo?
cherouvim

2
Non funziona per me (spring mvc 3.1) - forse c'è qualcos'altro che deve essere fatto? Seguendo la soluzione di Samit.
kldavis4

2
Il problema è che quando provi i validatori usando MockMvc e questo tipo di iniezione avrai problemi.
Forse

21
È possibile autowire HttpServletRequest anche in bean senza ambito di richiesta, perché per HttpServletRequest Spring genererà un proxy HttpServletRequest che è a conoscenza di come ottenere l'istanza effettiva della richiesta. Quindi è sicuro eseguire la richiesta di autowire anche se il controller è con ambito singleton.
vtor

3
Avviso per gli utenti Spring <= 3.1 l'autowiring non funzionerà eseguendo i test.
Rubens Mariuzzo

138

Spring espone l' HttpServletRequestoggetto corrente (così come l' HttpSessionoggetto corrente ) tramite un oggetto wrapper di tipo ServletRequestAttributes. Questo oggetto wrapper è associato a ThreadLocal e viene ottenuto chiamando il staticmetodo RequestContextHolder.currentRequestAttributes().

ServletRequestAttributesfornisce il metodo getRequest()per ottenere la richiesta corrente, getSession()per ottenere la sessione corrente e altri metodi per ottenere gli attributi memorizzati in entrambi gli ambiti. Il codice seguente, sebbene un po 'brutto, dovrebbe portarti l'oggetto richiesta corrente ovunque nell'applicazione:

HttpServletRequest curRequest = 
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();

Si noti che il RequestContextHolder.currentRequestAttributes()metodo restituisce un'interfaccia e deve essere convertito in typecast per ServletRequestAttributesimplementare l'interfaccia.


Javadoc di primavera: RequestContextHolder | ServletRequestAttributes


8
L'iniezione è una buona risoluzione, ma ho riscontrato problemi con MockMvc testando i validatori di primavera che iniettano HttpServletRequest. Quindi, se vuoi che sia i test fittizi che il codice di produzione funzionino correttamente, questa dovrebbe essere la scelta.
Neyko

@Neyko Perché è? per il test di simulazione (test unitario?), puoi iniettare HttpServletRequest o quello che vuoi .. non è vero? Oppure puoi usare MockHttpServletRequest immagino?
wonhee

È sicuro da utilizzare in un'istanza di servizio con ambito singleton?
Jin Kwon

2

Come suggerito qui puoi anche iniettare il HttpServletRequestparametro come metodo, ad esempio:

public MyResponseObject myApiMethod(HttpServletRequest request, ...) {
    ...
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.