2013-10-09 11 views
7

Ich kenne die Standardmethode für das Schreiben eines AOP-Hinweises um eine Controller-Methode und den Zugriff auf das Argument HttpServletRequest, wenn dies in der Controller-Methode deklariert ist.Wie injiziere ich HttpServletRequest in eine Spring-AOP-Anfrage (benutzerdefiniertes Szenario)?

Aber mein Szenario ist, dass ich einen Übersetzungsdienst habe, der derzeit session-scoped ist, der das Gebietsschema des Benutzers für die Übersetzung beibehält. Ich denke, das macht den Service Stateful und ich will auch nicht, dass es Session-Bereich ist, wie ich denke, es ist wirklich Singleton. Es gibt jedoch mehrere Stellen, an denen die Übersetzungsdienstmethoden aufgerufen werden. Daher möchte ich die Signatur nicht ändern, um eine Anforderung/Gebietsschema in diesen Methoden hinzuzufügen. Das Problem ist, dass alle Aufrufer der Methoden des Übersetzungsdienstes keinen Zugriff auf HttpServletRequest (nicht Controller-Methoden) haben? Kann ich einen Aspekt um die Methoden des Übersetzungsdienstes schreiben und bekomme irgendwie Zugang zu HttpServletRequest, unabhängig davon, ob er im Kontext des Aufrufers verfügbar ist oder nicht?

@Service 
public class TranslationService { 
    public void translate(String key) { 
     ... 
    } 
} 

@Aspect 
@Component 
public class LocaleFinder { 
    @PointCut("execution(* TranslationService.translate(..))") 
    private void fetchLocale() {} 

    @Around("fetchLocale()") // in parameter list 
    public void advice(JoinPoint joinpoint, HttpServletRequest request) { .... } 
} 

Wenn nun der Anrufer von übersetzt sich HttpServletRequest nicht haben, kann ich nicht Anfrage bekommen im Rat? Gibt es eine Problemumgehung?

Antwort

28

Kann ich schreibe einen Aspekt rund um die Übersetzungsservice Methoden und irgendwie magisch Zugang bekommen zu HttpServletRequest unabhängig von , ob es in dem Anrufer Kontext verfügbar ist oder nicht?

Nicht leicht. Eigentlich würde es viel Aufwand erfordern.

Der einfache Weg ist, sich auf RequestContextHolder zu verlassen. Bei jeder Anforderung bindet die DispatcherServlet den aktuellen HttpServletRequest an ein static ThreadLocal Objekt in der RequestContextHolder. Sie können es abrufen, wenn innerhalb der gleichen Thread mit

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

Ausführung du in der advice() Methode tun können und müssen daher nicht um einen Parameter deklarieren.