2010-12-08 6 views
24

Ist es möglich, einen Spring MVC Interceptor mit Anmerkungen zu verbinden, und wenn ja, könnte mir jemand ein Beispiel dafür geben?Kann ein Spring MVC Interceptor mit Anmerkungen verbunden werden?

Per Draht via Annotation ich meine, so wenig wie möglich in der XML-Konfiguration zu tun. Zum Beispiel in dieser Konfigurationsdatei fand ich bei http://www.vaannila.com/spring/spring-interceptors.html;

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:interceptors-ref="loggerInterceptor" /> 
<bean id="loggerInterceptor" class="com.vaannila.interceptor.LoggerInterceptor" /> 

Wie wenig Konfiguration konnten Sie damit durchkommen? Ich stelle mir vor, ein @Autowired würde die Notwendigkeit beseitigen, die Bean explizit in Zeile 2 zu deklarieren, aber wäre es auch möglich, Zeile 1 mit einer Anmerkung loszuwerden?

+0

Können Sie klären? Meinst du Spring MVC Abfangjäger oder AOP Abfangjäger? Was meinst du mit "Verkabelung"? – axtavt

+1

Vielleicht möchten Sie dies sehen http://karthikg.wordpress.com/2009/10/12/athandlerinterceptor-for-spring-mvc/ – ashishjmeshram

+1

Ich weiß, es ist ein paar Jahren, dass Sie diese Frage gestellt haben, aber @Markus Kreusch hat die richtige Antwort für die neue Version von Spring MVC –

Antwort

17

Soweit ich weiß, gibt es keine Möglichkeiten, Spring MVC Interzeptoren ohne XML überhaupt zu konfigurieren.

Es gibt jedoch einige Vereinfachungen mit mvc Namespace in den neuesten Versionen von Spring 3.0.x (nicht 3.0.0 Frühling!):

<mvc:interceptors> 
    <bean class="com.vaannila.interceptor.LoggerInterceptor" /> 
</mvc:interceptors> 

Siehe auch:

+0

Gute Antwort. Ist es möglich, Interceptor zu erstellen, der Ausnahmen behandelt? – fastcodejava

+0

@fastcodejava: Nein. Für die Behandlung von Ausnahmen können Sie ['HandlerExceptionResolver's] (http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc -exceptionhandlers). – axtavt

+0

Möge all die Güte auf der Welt zu dir kommen, feinster Herr! – Art

0

Ich weiß nicht, über den Frühling-AOP, aber wenn Sie AspectJ über Frühling verwenden können Sie verwenden @Aspect, @Pointcut, @Advise und mehr ...

gibt es auch einen schönen Artikel über Howto diese Anmerkung verwenden mit Spring AOP hier: http://java-x.blogspot.com/2009/07/spring-aop-with-aspecj-annotations.html

+0

geschrieben. Vielen Dank, aber wir verwenden AspectJ derzeit nicht, soweit ich weiß. Ich möchte auch Aspekte vermeiden, wenn ich kann. –

72

Stolperte über diese Frage bei der Suche genau dies. Schließlich habe ich herausgefunden, dass es in Spring 3.1 mit @EnableWebMVC in Verbindung mit WebMvcConfiguratorAdapter funktioniert.

Einfaches Beispiel:

@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages="webapp.base.package") 
public class WebApplicationConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void addInterceptors(InterceptorRegistry registry) { 
     registry.addInterceptor(new LoggerInterceptor()); 
    } 

} 
+11

Ich denke, das sollte eine akzeptierte Antwort sein. Ein Vorbehalt, wenn Sie Ihren benutzerdefinierten Interceptor automatisch ansteuern möchten, deklarieren Sie ihn als '@ Bean' in einer der' @Configuration'-Klassen und fügen Sie ihn über seine Bean-Methode hinzu. –

+0

@AlexanderPogrebnyak, Dies könnte die richtige Antwort für neuere Versionen von Spring sein, aber ich bin nicht mehr in der Lage, Spring Annotationen zu testen, und ich wäre nachlässig, es korrekt zu markieren, ohne es persönlich getestet zu haben. –

+1

beziehen Sie sich auch darauf: http://stackoverflow.com/questions/21228447/spring-interceptors-excludepathpatterns-function-is-not-working-properly – Nikhil

-2

wie Markus Kreusch'answers, Es könnte auch wie arbeiten diese

@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages="webapp.base.package") 
public class WebApplicationConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public RequestMappingHandlerMapping requestMappingHandlerMapping() { 
     RequestMappingHandlerMapping RequestMappingHandlerMapping= super.requestMappingHandlerMapping(); 
     Object[] interceptors = new Object[1]; 
     interceptors[0] = new RoleInterceptor(); 
     RequestMappingHandlerMapping.setInterceptors(interceptors); 
     return RequestMappingHandlerMapping; 
    } 

} 
+1

Dies hat Markus Antwort in keiner Weise verbessert. Ihre Antwort ist tatsächlich mehr verwirrt, als sie das Problem beleuchtet. – javaauthority

1

ich eine funktionierende Lösung implementiert eine benutzerdefinierte @Interceptor Annotation im Geiste der Spring @Controller Anmerkung mit :

@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.TYPE}) 
@Documented 
@Component 
public @interface Interceptor { 
    String[] pathPatterns() default {}; 
    String[] excludePathPatterns() default {}; 
} 

Diese Anmerkung s hould zu HandlerInterceptor Typen wie so angewendet werden:

@Interceptor 
public class BuildTimestampInterceptor extends HandlerInterceptorAdapter { 
    private final String buildTimestamp; 

    public BuildTimestampInterceptor(@Value("${build.timestamp}") String buildTimestamp) { 
    this.buildTimestamp = buildTimestamp; 
    } 

    @Override 
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception { 
    req.setAttribute("buildTimestamp", buildTimestamp); 
    return true; 
    } 
} 

Schließlich ist die Prozessorklasse, InterceptorProcessor ist eine Feder Bean, die WebMvcConfigurerAdapter und implementiert BeanPostProcessor, um für die benutzerdefinierte @Interceptor Annotationen zu scannen erstreckt und registrieren Bohnen aufweist, die anntation als HandlerInterceptor s innerhalb der überschrieben addInterceptors Methode:

@Component 
public class InterceptorProcessor extends WebMvcConfigurerAdapter implements BeanPostProcessor { 
    private final Map<HandlerInterceptor,Interceptor> interceptors = new HashMap<>(); 

    @Override 
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 
    scanForInterceptorAnnotation(bean, beanName); 
    return bean; 
    } 

    @Override 
    public Object postProcessAfterInitialization(Object bean, String string) throws BeansException { 
    return bean; 
    } 

    protected void scanForInterceptorAnnotation(Object bean, String beanName) { 
    Optional<Interceptor> optionalInterceptor = getInterceptorAnnotation(bean.getClass()); 
    if (optionalInterceptor.isPresent() && bean instanceof HandlerInterceptor) { 
     interceptors.put((HandlerInterceptor) bean, optionalInterceptor.get()); 
    } 
    } 

    private Optional<Interceptor> getInterceptorAnnotation(Class cls) { 
    Annotation[] annotations = cls.getAnnotationsByType(Interceptor.class); 
    if (hasValue(annotations)) { 
     return Optional.of((Interceptor) annotations[0]); 
    } 
    return Optional.empty(); 
    } 

    @Override 
    public void addInterceptors(InterceptorRegistry registry) { 
    interceptors.forEach((HandlerInterceptor key, Interceptor val) -> { 
     InterceptorRegistration registration = registry.addInterceptor(key); 
     if (hasValue(val.pathPatterns())) { 
     registration.addPathPatterns(val.pathPatterns()); 
     } 

     if (hasValue(val.excludePathPatterns())) { 
     registration.excludePathPatterns(val.excludePathPatterns()); 
     } 
    }); 
    } 

    private static <T> boolean hasValue(T[] array) { 
    return array != null && array.length > 0; 
    } 
} 

Denken sie daran, Ihre Feder Anwendung Scan für diesen Prozessor Bohne haben, um es tatsächlich registrieren Ihre @Interceptor s.Etwas wie:

@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages = {"org.my.controller", "org.my.utils.processor"}) 
public class WebConfig extends WebMvcConfigurerAdapter {... 
Verwandte Themen