Spring: comment injecter une HttpServletRequest dans un bean à portée de requête?

95

J'essaie de mettre en place un bean à portée de demande au printemps.

Je l'ai configuré avec succès pour que le bean soit créé une fois par demande. Maintenant, il doit accéder à l'objet HttpServletRequest.

Puisque le bean est créé une fois par requête, je suppose que le conteneur peut facilement injecter l'objet de requête dans mon bean. Comment puis je faire ça ?

Léonel
la source

Réponses:

114

Les beans à portée de requête peuvent être câblés automatiquement avec l'objet de requête.

private @Autowired HttpServletRequest request;
skaffman
la source
2
Existe-t-il une méthode XML à l'ancienne pour cela?
cherouvim
2
Cela ne fonctionne pas pour moi (spring mvc 3.1) - il y a peut-être quelque chose de plus à faire? Aller avec la solution de Samit.
kldavis4
2
Le problème est que lorsque vous testez des validateurs en utilisant MockMvc et ce type d'injection, vous aurez des problèmes. Peut-être que l'autre solution sera préférée dans ce cas
Neyko
21
Il est possible d'autowire HttpServletRequest également dans des beans non étendus à la demande, car pour HttpServletRequest, Spring générera un proxy HttpServletRequest qui sait comment obtenir l'instance réelle de la demande. Il est donc prudent de faire passer automatiquement la demande même si votre contrôleur a une portée singleton.
vtor le
3
Attention pour les utilisateurs de Spring <= 3.1, le câblage automatique ne fonctionnera pas lors des tests.
Rubens Mariuzzo
138

Spring expose l' HttpServletRequestobjet actuel (ainsi que l' HttpSessionobjet actuel ) via un objet wrapper de type ServletRequestAttributes. Cet objet wrapper est lié à ThreadLocal et est obtenu en appelant la staticméthode RequestContextHolder.currentRequestAttributes().

ServletRequestAttributesfournit la méthode getRequest()pour obtenir la requête actuelle, getSession()pour obtenir la session actuelle et d'autres méthodes pour obtenir les attributs stockés dans les deux étendues. Le code suivant, bien qu'un peu laid, devrait vous obtenir l'objet de requête actuel n'importe où dans l'application:

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

Notez que la RequestContextHolder.currentRequestAttributes()méthode renvoie une interface et doit être typée pour ServletRequestAttributesimplémenter l'interface.


Javadoc de printemps: RequestContextHolder | ServletRequestAttributes

samitgaur
la source
8
L'injection est une bonne résolution, mais j'ai trouvé des problèmes avec MockMvc testant les validateurs Spring qui injectent HttpServletRequest. Donc, si vous voulez que les tests fictifs et le code de production fonctionnent correctement, cela devrait être le choix.
Neyko
@Neyko Pourquoi est-ce? pour un test simulé (test unitaire?), vous pouvez injecter une simulation HttpServletRequest ou ce que vous voulez .. n'est-ce pas? Ou vous pouvez utiliser MockHttpServletRequest je suppose?
wonhee
Est-il sûr d'être utilisé dans une instance de service à portée singleton?
Jin Kwon
2

Comme suggéré ici, vous pouvez également injecter le paramètre en HttpServletRequesttant que méthode, par exemple:

public MyResponseObject myApiMethod(HttpServletRequest request, ...) {
    ...
}
Will Cain
la source