2016-11-07 4 views
2

Ich möchte einen Filter erstellen, der die für bestimmte Webanforderungen aufgewendete Zeit zusammen mit dem Vorgangsnamen protokolliert. Einige URLs haben jedoch Pfadparameter und ich suche nach etwas, das es mir ermöglichen würde, ein URL-Muster zu erhalten, das der bestimmten Methode statt der URL selbst entspricht.Zugriff auf das URL-Handlermuster über den HTTP-Filter

Zum Beispiel für Verfahren, die wie /users/{id}/accounts/{type} Anforderungen für URLs verarbeitet GET Ich mag Operationsnamen wie GET /users/{}/accounts/{} statt, um zu sehen, sagen: GET /users/1/accounts/facebook oder GET /users/2/accounts/twitter?someParam=3.

Im Moment löse ich dies, indem ich die URL mit vordefinierten Mustern in dem Tool, das Protokolldatensätze analysiert, abgleicht, aber für mich sieht es wie ein Hack aus.

Ich habe keinen einfachen Weg gefunden, auf URL-Muster zuzugreifen, die mit einer Methode zur Verarbeitung eingehender Anfragen verknüpft sind. Eine mögliche Lösung, die ich jetzt in Erwägung ziehe, ist das Festlegen einer lokalen Variablen in der Controller-Methode selbst und Zugriff darauf in meinem HTTP-Filter, aber das scheint auch nicht eine saubere Möglichkeit, dies zu lösen.

Gibt es eine bessere Lösung für dieses Problem?

Um etwas Kontext ein: Ich bin mit Spring MVC 4.

+1

Wenn Sie Ihren Filter erweitern GenericFilterBean kann es Spring sein. Sie können dann eine Instanz des konfigurierten RequestMappingHandlerMapping einfügen, das für die Suche nach dem Mapping für eine bestimmte Anforderung benötigt wird. Ich war nicht in der Lage, herauszufinden, wie von hier aus vorzugehen, aber siehe http://stackoverflow.com/questions/14025872/reflectively-getting-list-of-spring-mvc-controllers-matching-specific-url, die Sie geben können einige Ideen, wie Sie das passende URL-Muster erhalten würden. –

+1

OK, sieht aus wie ich sehe, wie es funktioniert. Ich werde meine Frage aktualisieren, wenn ich mich dazu entscheide, diesen Ansatz mit dem Arbeitscode beizubehalten - es sei denn, ich entscheide mich für etwas anderes. – Alex

+0

@AlanHay Ich habe eine Antwort geschrieben, es stellte sich heraus, dass es viel einfacher war, als ich es mir erhofft hatte. – Alex

Antwort

1

OK, stellte sich heraus, super-einfach zu sein. Mit Feder, können Sie es wie folgt:

public class HttpOperationLoggerFilter extends OncePerRequestFilter { 
    private final Logger log = LoggerFactory.getLogger(getClass()); 

    @Override 
    protected void doFilterInternal(HttpServletRequest request, 
            HttpServletResponse response, 
            FilterChain filterChain) throws ServletException, IOException { 
     // do filter first 
     filterChain.doFilter(request, response); 

     // ... then you'll be able to access spring MVC's bestMatchingPattern! 
     final Object urlPattern = request 
     .getAttribute("org.springframework.web.servlet.HandlerMapping.bestMatchingPattern"); 
     log.info("urlPattern={}", urlPattern); 
    } 
} 

Also, wenn Sie MVC-Controller-Methode haben, die Griffe URL-Muster wie ‚/ do/{etwas}/wie/{dass}‘ Sie genau das sehen werden Muster!

Gut, dass diese Variable ein zusammengesetztes Muster enthält. Wenn Ihr Controller also mit RequestMapping annotiert ist, wird sein Wert dem Muster vorangestellt.

Verwandte Themen