Pregunta

¿Es posible conectar un interceptor Spring MVC usando anotaciones y si es así es posible que alguien me proporcione un ejemplo de cómo hacerlo?

Por el alambre a través de la anotación me refiero a hacer lo menos en la configuración XML como sea posible. Por ejemplo, en este archivo de configuración que encontré en http://www.vaannila.com/spring/ primavera-interceptors.html ;

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

¿Cómo poca configuración podría salirse con la que hay? Imagino un @Autowired eliminaría la necesidad de declarar explícitamente el frijol en la línea 2, pero ¿sería posible deshacerse de la línea 1, con una anotación así?

¿Fue útil?

Solución

Por lo que yo sé, no hay maneras de configurar los interceptores Spring MVC sin XML en absoluto.

Sin embargo, hay algunas simplificaciones con espacio de nombres mvc en las últimas versiones de primavera 3.0.x (no 3.0.0 Primavera!):

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

Ver también:

Otros consejos

Tropezamos con esta pregunta durante la búsqueda exactamente esto. Finalmente descubrí que funciona en la primavera de 3,1 usando @EnableWebMVC conjuntamente con WebMvcConfigurerAdapter.

simple ejemplo:

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

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

}

Me implementó una solución de trabajo utilizando una anotación @Interceptor personalizado en el espíritu de anotación @Controller de primavera:

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

Esta anotación se debe aplicar a los tipos HandlerInterceptor este modo:

@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;
  }
}

Finalmente, la clase de procesador, InterceptorProcessor, es un bean resorte que se extiende WebMvcConfigurerAdapter e implementos BeanPostProcessor con el fin de explorar en busca de las anotaciones @Interceptor personalizados y registrar los granos que tienen que anntation como HandlerInterceptors dentro del método addInterceptors reemplazado:

@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;
  }
}

Sólo recuerde que su aplicación de escaneo de primavera de este grano de procesador con el fin de tener en realidad confirmar su @Interceptors. Algo así como:

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

No sé sobre la primavera-AOP, pero si usted está utilizando AspectJ a través de primavera se puede utilizar @Aspect, @Pointcut, @Advise y más ...

también hay un buen artículo sobre howto utilizar estas anotaciones con Spring AOP aquí: http://java-x.blogspot.com /2009/07/spring-aop-with-aspecj-annotations.html

como Markus Kreusch'answers, también podría funcionar como esto

@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;
    }

}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top