2017-03-29 7 views
0

Stellen abfangen haben wir einen Controller wie dieseSpring MVC @Controller eigene Anfragen

@RestController 
@RequestMapping("/{parameter}") 
pubic class MyController { 

    @ExceptionHandler(SomeException.class) 
    public Object handleSomeException() { /* handle */ } 

    @RequestMapping("/something") 
    public Object handleSomething(@PathVariable("parameter") String parameter) { 
     /* handle */ 
    } 

    @RequestMapping("/somethingElse") 
    public Object handleSomethingElse(@PathVariable("parameter") String parameter) { 
     /* handle */ 
    } 
} 

Und die Frage, wie eine gemeinsame Vor- \ post-Handling für diese spezielle Steuerung in ähnlicher Weise wie @ExceptionHandler implementieren arbeitet . Z.B. Ich möchte eine Methode im Controller haben, die eine Anfrage vor den Handler-Methoden empfängt, aber nur Anfragen für diesen speziellen Controller.

Ich bin bewusst, RequestBodyAdvice und ResponseBodyAdvice Schnittstellen, aber wollen etwas lokalen Controller.

Als ein Anwendungsbeispiel - Ich möchte einige Validierung für gemeinsame parameter Variable vor jedem Handler.

+1

Werfen Sie einen Blick auf Frühling AOP: https://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html – user1675642

+0

Sie können auch gehe mit HandlerInterceptor wie hier erwähnt http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/HandlerInterceptor.html – Zeus

Antwort

0

Verwenden HandlerInterceptorAdapter

Intercept die vor und nach dem Controller Ausführung, meldet den Beginn und das Ende der Ausführungszeit, speichern Sie sich in die bestehenden abgefangen Controllers Modeland für eine spätere Anzeige.

public class ExecuteTimeInterceptor extends HandlerInterceptorAdapter{ 

private static final Logger logger = Logger.getLogger(ExecuteTimeInterceptor.class); 

//before the actual handler will be executed 
public boolean preHandle(HttpServletRequest request, 
    HttpServletResponse response, Object handler) 
    throws Exception { 

    long startTime = System.currentTimeMillis(); 
    request.setAttribute("startTime", startTime); 

    return true; 
} 

//after the handler is executed 
public void postHandle(
    HttpServletRequest request, HttpServletResponse response, 
    Object handler, ModelAndView modelAndView) 
    throws Exception { 

    long startTime = (Long)request.getAttribute("startTime"); 

    long endTime = System.currentTimeMillis(); 

    long executeTime = endTime - startTime; 

    //modified the exisitng modelAndView 
    modelAndView.addObject("executeTime",executeTime); 

    //log it 
    if(logger.isDebugEnabled()){ 
     logger.debug("[" + handler + "] executeTime : " + executeTime + "ms"); 
    } 
} 

Einige weitere Beispiele - http://www.mkyong.com/spring-mvc/spring-mvc-handler-interceptors-example/

0

Sie werden Sie HandlerInterceptor besitzen schreiben müssen. Sie können es leicht tun, indem Sie HandlerInterceptorAdapter erweitern. Und dann können Sie preHandle() und/oder postHandle() überschreiben.

preHandle() wird aufgerufen, nachdem ein geeignetes HandlerMapping handler Objekt bestimmt, aber bevor HandlerAdapter ruft die Behandlungsroutine.

postHandle() wird aufgerufen, nachdem HandlerAdapter tatsächlich die Handler aufgerufen, aber vor dem DispatcherServlet macht die Ansicht.

Sie können die getRequestURI() Methode von HttpServletRequest Logiken in preHandle() für verschiedene Handler hinzuzufügen.

Beispiel:

public class ValidationInterceptor extends HandlerInterceptorAdapter { 

    public static final String FOO_URL = "foo"; 
    public static final String BAR_URL = "bar"; 

    @Override 
    public boolean preHandle(HttpServletRequest request, 
          HttpServletResponse response, 
          Object handler) throws Exception { 

     String uri = request.getRequestURI(); 

     if (FOO_URL.equals(uri)) {   
      // for example - validation failed 
      response.sendRedirect("/to/some/url"); 
      return false; 
     } else if (BAR_URL.equals(uri)) { 
      // for example - validation successful 
     } 
     return true; 
    } 
} 

Dann ist dieses HandlerInterceptor in Ihrem dispatcher-servlet.xml registrieren.

<mvc:interceptors> 
    <bean class="your.package.ValidationInterceptor"/> 
</mvc:interceptors> 

Sie können dies konfigurieren, um mehr URL-spezifisch zu sein. Siehe Abschnitt 22.16.5 Interceptors der Spring Reference.

0

Während HandlerInterceptorAdapter scheint die "richtige" Lösung, scheint es nicht die Lösung, die Sie wollen.

Der folgende Code könnte die Lösung sein, die Sie wollen (oder zumindest die, die Sie in Ihrer Frage gefragt).

Zusammenfassung, schreiben Sie Ihre eigenen PreBlam und PostBlam Methoden.

Einige codeish:

@RestController 
@RequestMapping("/{parameter}") 
pubic class MyController 
{ 

    @ExceptionHandler(SomeException.class) 
    public Object handleSomeException() 
    { 
    /* handle */ 
    } 

    @RequestMapping("/something") 
    public Object handleSomething(@PathVariable("parameter") String parameter) 
    { 
     preBlam(desired params here); 

     /* handle */ 

     postBlam(desired params here); 
    } 

    @RequestMapping("/somethingElse") 
    public Object handleSomethingElse(@PathVariable("parameter") String parameter) 
    { 
     preBlam(desired params here); 

     /* handle */ 

     postBlam(desired params here); 
    } 

    private blam preBlam(parameters) 
    { 
    // do initial blamish work 
    } 

    private blam postBlam(parameters) 
    { 
    // do post blamish work here 
    } 
} 

Eine weitere Option: Verwenden AOP Pre-und Post-Handler für die betroffenen Verfahren einzustellen. Ich bin kein großer AOP Benutzer, also kann ich nicht einfach ein Beispiel rasseln.

0

Da Sie die Pfadvariable auf eine allgemeine Weise behandeln möchten, sollten Sie ein Modellobjekt vorstellen. Mit diesem können Sie das Attribut (Java Bean Validierung) validieren und auch Pfadvariablen und Abfrageparameter mischen (ein sehr einfaches Beispiel hier können Sie sogar benutzerdefinierte Validierungen erstellen):

@Data 
class SomeModel { 
    @NotEmpty 
    private String parameter; 
} 

In der Steuerung müssen Sie einfach hinzufügen das Modell als Parameter:

@RequestMapping("/something") 
public Object handleSomething(@Valid SomeModel model) { 
    /* handle using model.getParameter() */ 
} 
Verwandte Themen