All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.boot.autoconfigure.web.WebMvcAutoConfigurationAfter Maven / Gradle / Ivy

package org.springframework.boot.autoconfigure.web;

import java.util.List;
import java.util.Map.Entry;

import javax.servlet.Servlet;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.ControllerProperties.RedirectViewProperties;
import org.springframework.boot.autoconfigure.web.ControllerProperties.ViewProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.filter.OrderedForwardedHeaderFilter;
import org.springframework.boot.web.filter.OrderedInspectionFilter;
import org.springframework.boot.web.filter.OrderedMultipartFilter;
import org.springframework.boot.web.filter.OrderedTimeZoneAwareLocaleChangeFilter;
import org.springframework.boot.web.filter.OrderedTraceFilter;
import org.springframework.context.ApplicationContext;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.support.StringToEnumConverter;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.HttpStatus;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.method.annotation.DimensionArgumentResolver;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.RedirectViewControllerRegistration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.JsonpResponseBodyAdvice;
import org.springframework.web.servlet.mvc.method.annotation.MediaTypeResponseBodyAdvice;
import org.springframework.web.servlet.mvc.method.annotation.PageResponseBodyAdvice;

@Configuration
// @ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 5)
// @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 20)
@AutoConfigureAfter({ WebMvcAutoConfiguration.class })
public class WebMvcAutoConfigurationAfter {
  @Bean
  @ConfigurationProperties("spring.mvc.filter.trace-filter")
  @ConditionalOnProperty(prefix = "spring.mvc.filter.trace-filter", name = "enabled", matchIfMissing = true)
  public OrderedTraceFilter traceFilter() {
    OrderedTraceFilter orderedTraceFilter = new OrderedTraceFilter();
    return orderedTraceFilter;
  }

  @Bean
  @ConfigurationProperties("spring.mvc.filter.inspection")
  public OrderedInspectionFilter inspectionFilter() {
    OrderedInspectionFilter orderedInspectionFilter = new OrderedInspectionFilter();
    return orderedInspectionFilter;
  }

  @Bean
  @ConditionalOnBean({ MultipartResolver.class })
  @ConfigurationProperties("spring.mvc.filter.multipart-filter")
  @ConditionalOnProperty(prefix = "spring.mvc.filter.multipart-filter", name = "enabled", matchIfMissing = true)
  public OrderedMultipartFilter multipartFilter(ApplicationContext applicationContext) {
    String[] beanNames = applicationContext.getBeanNamesForType(MultipartResolver.class);
    Assert.notEmpty(beanNames, "No MultipartResolver found: not in a DispatcherServlet request?");
    Assert.isTrue(beanNames.length < 2, "Multiple MultipartResolver found: in a DispatcherServlet request? " + StringUtils.arrayToCommaDelimitedString(beanNames));

    OrderedMultipartFilter multipartFilter = new OrderedMultipartFilter(null);
    multipartFilter.setMultipartResolverBeanName(beanNames[0]);
    return multipartFilter;
  }

  @Bean
  @ConditionalOnBean(LocaleResolver.class)
  @ConfigurationProperties("spring.mvc.filter.time-zone-aware-locale-change-filter")
  @ConditionalOnProperty(prefix = "spring.mvc.filter.time-zone-aware-locale-change-filter", name = "enabled", matchIfMissing = true)
  public OrderedTimeZoneAwareLocaleChangeFilter timeZoneAwareLocaleChangeFilter(ApplicationContext applicationContext) {
    String[] beanNames = applicationContext.getBeanNamesForType(LocaleResolver.class);
    Assert.notEmpty(beanNames, "No LocaleResolver found: not in a DispatcherServlet request?");
    Assert.isTrue(beanNames.length < 2, "Multiple LocaleResolver found: in a ApplicationContext " + StringUtils.arrayToCommaDelimitedString(beanNames));

    OrderedTimeZoneAwareLocaleChangeFilter filter = new OrderedTimeZoneAwareLocaleChangeFilter();
    filter.setLocaleResolverBeanName(beanNames[0]);
    return filter;
  }

  @Bean
  @ConfigurationProperties("spring.mvc.filter.forwarded-header-filter")
  @ConditionalOnProperty(prefix = "spring.mvc.filter.forwarded-header-filter", name = "enabled", matchIfMissing = true)
  public OrderedForwardedHeaderFilter forwardedHeaderFilter() {
    OrderedForwardedHeaderFilter forwardedHeaderFilter = new OrderedForwardedHeaderFilter();
    return forwardedHeaderFilter;
  }

  @Bean
  @ConfigurationProperties("spring.mvc.advice.media-type-response-body")
  @ConditionalOnProperty(prefix = "spring.mvc.advice.media-type-response-body", name = "enabled", matchIfMissing = true)
  public MediaTypeResponseBodyAdvice mediaTypeResponseBodyAdvice() {
    return new MediaTypeResponseBodyAdvice();
  }

  @Bean
  @ConditionalOnClass(name = "org.springframework.data.domain.Page")
  @ConfigurationProperties("spring.mvc.advice.page-response-body")
  @ConditionalOnProperty(prefix = "spring.mvc.advice.page-response-body", name = "enabled", matchIfMissing = true)
  public PageResponseBodyAdvice pageResponseBodyAdvice() {
    return new PageResponseBodyAdvice();
  }

  @Bean
  @ConfigurationProperties("spring.mvc.advice.jsonp-response-body")
  @ConditionalOnProperty(prefix = "spring.mvc.advice.jsonp-response-body", name = "enabled", matchIfMissing = true)
  public JsonpResponseBodyAdvice jsonpResponseBodyAdvice() {
    return new JsonpResponseBodyAdvice();
  }

  @Configuration
  @EnableConfigurationProperties({ CorsProperties.class, ControllerProperties.class })
  public static class WebMvcAutoConfigurationAdapterCustom extends WebMvcConfigurerAdapter {
    private final CorsProperties corsProperties;
    private final ControllerProperties controllerProperties;
    private final MessageSource messageSource;
    private final AsyncTaskExecutor asyncTaskExecutor;
    private final List handlerMethodArgumentResolvers;

    public WebMvcAutoConfigurationAdapterCustom(MessageSource messageSource, ObjectProvider asyncTaskExecutor,
        ObjectProvider> handlerMethodArgumentResolvers, CorsProperties corsProperties, ControllerProperties controllerProperties) {
      super();
      this.corsProperties = corsProperties;
      this.controllerProperties = controllerProperties;
      this.asyncTaskExecutor = asyncTaskExecutor.getIfAvailable();
      this.messageSource = messageSource;
      this.handlerMethodArgumentResolvers = handlerMethodArgumentResolvers.getIfAvailable();
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
      if (controllerProperties.isEnabled()) {
        for (Entry entry : controllerProperties.getRedirectView().entrySet()) {
          RedirectViewProperties redirectViewProperties = entry.getValue();
          RedirectViewControllerRegistration redirectView = registry.addRedirectViewController(entry.getKey(), redirectViewProperties.getRedirectUrl());
          if (redirectViewProperties.getContextRelative() != null) {
            redirectView.setContextRelative(redirectViewProperties.getContextRelative());
          }
          if (redirectViewProperties.getKeepQueryParams() != null) {
            redirectView.setKeepQueryParams(redirectViewProperties.getKeepQueryParams());
          }
          if (redirectViewProperties.getHttpStatus() != null) {
            redirectView.setStatusCode(redirectViewProperties.getHttpStatus());
          }
        }
        // controllerProperties.getView().keySet().size()
        // controllerProperties.getView().keySet()values()
        for (Entry entry : controllerProperties.getView().entrySet()) {
          ViewProperties viewProperties = entry.getValue();
          ViewControllerRegistration view = registry.addViewController(entry.getKey());
          if (viewProperties.getHttpStatus() != null) {
            view.setStatusCode(viewProperties.getHttpStatus());
          }
          view.setViewName(viewProperties.getViewName());
        }
        for (Entry entry : controllerProperties.getStatus().entrySet()) {
          registry.addStatusController(entry.getKey(), entry.getValue());
        }
        if (controllerProperties.getOrder() != null) {
          registry.setOrder(controllerProperties.getOrder());
        }
      }
    }

    /**
     * @see org.springframework.web.context.request.async.TimeoutCallableProcessingInterceptor
     * @see org.springframework.web.context.request.async.TimeoutDeferredResultProcessingInterceptor
     */
    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
      if (asyncTaskExecutor != null) {
        configurer.setTaskExecutor(asyncTaskExecutor);
      }
    }

    @Bean
    @ConfigurationProperties("spring.mvc.resolver.dimension-argument")
    public DimensionArgumentResolver dimensionArgumentResolver() {
      DimensionArgumentResolver dimensionArgumentResolver = new DimensionArgumentResolver();
      return dimensionArgumentResolver;
    }

    // @Override
    // // @Bean("mvcValidator")
    // public Validator getValidator() {
    // StaticMessageSource staticMessageSource = new StaticMessageSource();
    // staticMessageSource.setParentMessageSource(messageSource);
    //
    // LocalValidatorFactoryBean localValidatorFactoryBean = new
    // LocalValidatorFactoryBean();
    // localValidatorFactoryBean.setValidationMessageSource(staticMessageSource);
    // return localValidatorFactoryBean;
    // }

    // @Override
    // public void addInterceptors(InterceptorRegistry registry) {
    // for (HandlerInterceptor handlerInterceptor : this.handlerInterceptors) {
    // registry.addInterceptor(handlerInterceptor);
    // }
    // for (WebRequestInterceptor webRequestInterceptor : this.webRequestInterceptors) {
    // registry.addWebRequestInterceptor(webRequestInterceptor);
    // }
    // }

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
      AntPathMatcher antPathMatcher = new AntPathMatcher();
      antPathMatcher.setCaseSensitive(false);

      configurer.setPathMatcher(antPathMatcher);
      configurer.setUseSuffixPatternMatch(false);
      configurer.setUseTrailingSlashMatch(false);
    }

    @Override
    public void addArgumentResolvers(List argumentResolvers) {
      argumentResolvers.add(dimensionArgumentResolver());
      if (this.handlerMethodArgumentResolvers != null) {
        for (HandlerMethodArgumentResolver resolver : this.handlerMethodArgumentResolvers) {
          if (!argumentResolvers.contains(resolver)) {
            argumentResolvers.add(resolver);
          }
        }
      }
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
      registry.addConverterFactory(new ConverterFactory>() {
        @SuppressWarnings({ "rawtypes", "unchecked" })
        @Override
        public > Converter getConverter(Class targetType) {
          Class enumType = targetType;
          while (enumType != null && !enumType.isEnum()) {
            enumType = enumType.getSuperclass();
          }
          Assert.notNull(enumType, "The target type " + targetType.getName() + " does not refer to an enum");
          return new StringToEnumConverter(enumType);
        }
      });
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
      if (!StringUtils.hasText(corsProperties.getPathPattern()) && CollectionUtils.isEmpty(corsProperties.getAllowedOrigins())) {
        return;
      }
      CorsRegistration corsRegistration = registry.addMapping(corsProperties.getPathPattern());
      corsRegistration.allowedOrigins(corsProperties.getAllowedOrigins().toArray(new String[corsProperties.getAllowedOrigins().size()]));

      if (!CollectionUtils.isEmpty(corsProperties.getAllowedHeaders())) {
        corsRegistration.allowedHeaders(corsProperties.getAllowedHeaders().toArray(new String[corsProperties.getAllowedHeaders().size()]));
      }
      if (!CollectionUtils.isEmpty(corsProperties.getAllowedMethods())) {
        corsRegistration.allowedMethods(corsProperties.getAllowedMethods().toArray(new String[corsProperties.getAllowedMethods().size()]));
      }
      if (!CollectionUtils.isEmpty(corsProperties.getExposedHeaders())) {
        corsRegistration.exposedHeaders(corsProperties.getExposedHeaders().toArray(new String[corsProperties.getExposedHeaders().size()]));
      }
      if (corsProperties.getMaxAge() != null) {
        corsRegistration.maxAge(corsProperties.getMaxAge());
      }
      if (corsProperties.getAllowCredentials() != null) {
        corsRegistration.allowCredentials(corsProperties.getAllowCredentials());
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy