zoukankan      html  css  js  c++  java
  • 初入spring boot(四 )web项目

    1. 模板引擎

      spring boot提供了大量的模板引擎,包括FreeMark、Groovy、Thymeleaf、Velocity等,但spring boot中推荐用Thymeleaf,因为Thymeleaf提供了完美的spring mvc的支持。

    2. 与spring boot集成

      在spring mvc中,若要集成一个模板引擎的话,需要定义ViewResolver,而ViewResolver需要定义一个View。Thymeleaf已经定义好了ViewResolver和View,分别是org.thymeleaf.spring4.view.ThymeleafViewResolver(默认使用ThymeleafView作为View)和org.thymeleaf.spring4.view.ThymeleafView。Thymeleaf提供了SpringTemplateEngine类,用来驱动在spring mvc下使用Thymeleaf模板引擎,另外还提供了一个TemplateResolver用来设置通用的模板引擎(包含前缀、后缀等),这使我们在spring mvc中集成Thymeleaf引擎变得十分简单。

      上面说的是与spring mvc集成,但是ThymeleafView与Spring boot集成很方便,spring boot通过org.springframework.boot.autoconfigure.thymeleaf包对Thymeleaf进行了自动配置。

                  

      通过ThymeleafAutoConfiguration类对集成所需要的bean进行自动配置,包括templateResolver、templateEngine和thymeleafViewResolver的配置。

      通过ThymeleafProperties来配置Thymeleaf,在application.properties中,以spring.thymeleaf开头来配置,通过查看ThymeleafProperties的主要源码,可以看出如何设置属性以及默认的配置:

      1 @ConfigurationProperties(prefix = "spring.thymeleaf")
      2 public class ThymeleafProperties {
      3 
      4     private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8");
      5 
      6     private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");
      7 
      8     public static final String DEFAULT_PREFIX = "classpath:/templates/";
      9 
     10     public static final String DEFAULT_SUFFIX = ".html";
     11 
     12     /**
     13      * Check that the template exists before rendering it (Thymeleaf 3+).
     14      */
     15     private boolean checkTemplate = true;
     16 
     17     /**
     18      * Check that the templates location exists.
     19      */
     20     private boolean checkTemplateLocation = true;
     21 
     22     /**
     23      * Prefix that gets prepended to view names when building a URL.
     24      */
     25     private String prefix = DEFAULT_PREFIX;
     26 
     27     /**
     28      * Suffix that gets appended to view names when building a URL.
     29      */
     30     private String suffix = DEFAULT_SUFFIX;
     31 
     32     /**
     33      * Template mode to be applied to templates. See also StandardTemplateModeHandlers.
     34      */
     35     private String mode = "HTML5";
     36 
     37     /**
     38      * Template encoding.
     39      */
     40     private Charset encoding = DEFAULT_ENCODING;
     41 
     42     /**
     43      * Content-Type value.
     44      */
     45     private MimeType contentType = DEFAULT_CONTENT_TYPE;
     46 
     47     /**
     48      * Enable template caching.
     49      */
     50     private boolean cache = true;
     51 
     52     /**
     53      * Order of the template resolver in the chain. By default, the template resolver is
     54      * first in the chain. Order start at 1 and should only be set if you have defined
     55      * additional "TemplateResolver" beans.
     56      */
     57     private Integer templateResolverOrder;
     58 
     59     /**
     60      * Comma-separated list of view names that can be resolved.
     61      */
     62     private String[] viewNames;
     63 
     64     /**
     65      * Comma-separated list of view names that should be excluded from resolution.
     66      */
     67     private String[] excludedViewNames;
     68 
     69     /**
     70      * Enable MVC Thymeleaf view resolution.
     71      */
     72     private boolean enabled = true;
     73 
     74     public boolean isEnabled() {
     75         return this.enabled;
     76     }
     77 
     78     public void setEnabled(boolean enabled) {
     79         this.enabled = enabled;
     80     }
     81 
     82     public boolean isCheckTemplate() {
     83         return this.checkTemplate;
     84     }
     85 
     86     public void setCheckTemplate(boolean checkTemplate) {
     87         this.checkTemplate = checkTemplate;
     88     }
     89 
     90     public boolean isCheckTemplateLocation() {
     91         return this.checkTemplateLocation;
     92     }
     93 
     94     public void setCheckTemplateLocation(boolean checkTemplateLocation) {
     95         this.checkTemplateLocation = checkTemplateLocation;
     96     }
     97 
     98     public String getPrefix() {
     99         return this.prefix;
    100     }
    101 
    102     public void setPrefix(String prefix) {
    103         this.prefix = prefix;
    104     }
    105 
    106     public String getSuffix() {
    107         return this.suffix;
    108     }
    109 
    110     public void setSuffix(String suffix) {
    111         this.suffix = suffix;
    112     }
    113 
    114     public String getMode() {
    115         return this.mode;
    116     }
    117 
    118     public void setMode(String mode) {
    119         this.mode = mode;
    120     }
    121 
    122     public Charset getEncoding() {
    123         return this.encoding;
    124     }
    125 
    126     public void setEncoding(Charset encoding) {
    127         this.encoding = encoding;
    128     }
    129 
    130     public MimeType getContentType() {
    131         return this.contentType;
    132     }
    133 
    134     public void setContentType(MimeType contentType) {
    135         this.contentType = contentType;
    136     }
    137 
    138     public boolean isCache() {
    139         return this.cache;
    140     }
    141 
    142     public void setCache(boolean cache) {
    143         this.cache = cache;
    144     }
    145 
    146     public Integer getTemplateResolverOrder() {
    147         return this.templateResolverOrder;
    148     }
    149 
    150     public void setTemplateResolverOrder(Integer templateResolverOrder) {
    151         this.templateResolverOrder = templateResolverOrder;
    152     }
    153 
    154     public String[] getExcludedViewNames() {
    155         return this.excludedViewNames;
    156     }
    157 
    158     public void setExcludedViewNames(String[] excludedViewNames) {
    159         this.excludedViewNames = excludedViewNames;
    160     }
    161 
    162     public String[] getViewNames() {
    163         return this.viewNames;
    164     }
    165 
    166     public void setViewNames(String[] viewNames) {
    167         this.viewNames = viewNames;
    168     }
    169 
    170 }

    3. web相关配置

      3.1 spring boot提供的自动配置

      通过查看WebMvcAutoConfiguration及WebMvcProperties的源码,可以发现spring boot提供了如下的自动配置

      

      1 @Configuration
      2 @ConditionalOnWebApplication
      3 @ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
      4         WebMvcConfigurerAdapter.class })
      5 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
      6 @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
      7 @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
      8         ValidationAutoConfiguration.class })
      9 public class WebMvcAutoConfiguration {
     10 
     11     public static String DEFAULT_PREFIX = "";
     12 
     13     public static String DEFAULT_SUFFIX = "";
     14 
     15     @Bean
     16     @ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
     17     public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
     18         return new OrderedHiddenHttpMethodFilter();
     19     }
     20 
     21     @Bean
     22     @ConditionalOnMissingBean(HttpPutFormContentFilter.class)
     23     @ConditionalOnProperty(prefix = "spring.mvc.formcontent.putfilter", name = "enabled", matchIfMissing = true)
     24     public OrderedHttpPutFormContentFilter httpPutFormContentFilter() {
     25         return new OrderedHttpPutFormContentFilter();
     26     }
     27 
     28     // Defined as a nested config to ensure WebMvcConfigurerAdapter is not read when not
     29     // on the classpath
     30     @Configuration
     31     @Import(EnableWebMvcConfiguration.class)
     32     @EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
     33     public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter {
     34 
     35         private static final Log logger = LogFactory
     36                 .getLog(WebMvcConfigurerAdapter.class);
     37 
     38         private final ResourceProperties resourceProperties;
     39 
     40         private final WebMvcProperties mvcProperties;
     41 
     42         private final ListableBeanFactory beanFactory;
     43 
     44         private final HttpMessageConverters messageConverters;
     45 
     46         final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
     47 
     48         public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties,
     49                 WebMvcProperties mvcProperties, ListableBeanFactory beanFactory,
     50                 HttpMessageConverters messageConverters,
     51                 ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) {
     52             this.resourceProperties = resourceProperties;
     53             this.mvcProperties = mvcProperties;
     54             this.beanFactory = beanFactory;
     55             this.messageConverters = messageConverters;
     56             this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider
     57                     .getIfAvailable();
     58         }
     59 
     60         @Override
     61         public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
     62             converters.addAll(this.messageConverters.getConverters());
     63         }
     64 
     65         @Override
     66         public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
     67             Long timeout = this.mvcProperties.getAsync().getRequestTimeout();
     68             if (timeout != null) {
     69                 configurer.setDefaultTimeout(timeout);
     70             }
     71         }
     72 
     73         @Override
     74         public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
     75             Map<String, MediaType> mediaTypes = this.mvcProperties.getMediaTypes();
     76             for (Entry<String, MediaType> mediaType : mediaTypes.entrySet()) {
     77                 configurer.mediaType(mediaType.getKey(), mediaType.getValue());
     78             }
     79         }
     80 
     81         @Bean
     82         @ConditionalOnMissingBean
     83         public InternalResourceViewResolver defaultViewResolver() {
     84             InternalResourceViewResolver resolver = new InternalResourceViewResolver();
     85             resolver.setPrefix(this.mvcProperties.getView().getPrefix());
     86             resolver.setSuffix(this.mvcProperties.getView().getSuffix());
     87             return resolver;
     88         }
     89 
     90         @Bean
     91         @ConditionalOnBean(View.class)
     92         @ConditionalOnMissingBean
     93         public BeanNameViewResolver beanNameViewResolver() {
     94             BeanNameViewResolver resolver = new BeanNameViewResolver();
     95             resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
     96             return resolver;
     97         }
     98 
     99         @Bean
    100         @ConditionalOnBean(ViewResolver.class)
    101         @ConditionalOnMissingBean(name = "viewResolver", value = ContentNegotiatingViewResolver.class)
    102         public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
    103             ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
    104             resolver.setContentNegotiationManager(
    105                     beanFactory.getBean(ContentNegotiationManager.class));
    106             // ContentNegotiatingViewResolver uses all the other view resolvers to locate
    107             // a view so it should have a high precedence
    108             resolver.setOrder(Ordered.HIGHEST_PRECEDENCE);
    109             return resolver;
    110         }
    111 
    112         @Bean
    113         @ConditionalOnMissingBean
    114         @ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
    115         public LocaleResolver localeResolver() {
    116             if (this.mvcProperties
    117                     .getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
    118                 return new FixedLocaleResolver(this.mvcProperties.getLocale());
    119             }
    120             AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
    121             localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
    122             return localeResolver;
    123         }
    124 
    125         @Bean
    126         @ConditionalOnProperty(prefix = "spring.mvc", name = "date-format")
    127         public Formatter<Date> dateFormatter() {
    128             return new DateFormatter(this.mvcProperties.getDateFormat());
    129         }
    130 
    131         @Override
    132         public MessageCodesResolver getMessageCodesResolver() {
    133             if (this.mvcProperties.getMessageCodesResolverFormat() != null) {
    134                 DefaultMessageCodesResolver resolver = new DefaultMessageCodesResolver();
    135                 resolver.setMessageCodeFormatter(
    136                         this.mvcProperties.getMessageCodesResolverFormat());
    137                 return resolver;
    138             }
    139             return null;
    140         }
    141 
    142         @Override
    143         public void addFormatters(FormatterRegistry registry) {
    144             for (Converter<?, ?> converter : getBeansOfType(Converter.class)) {
    145                 registry.addConverter(converter);
    146             }
    147             for (GenericConverter converter : getBeansOfType(GenericConverter.class)) {
    148                 registry.addConverter(converter);
    149             }
    150             for (Formatter<?> formatter : getBeansOfType(Formatter.class)) {
    151                 registry.addFormatter(formatter);
    152             }
    153         }
    154 
    155         private <T> Collection<T> getBeansOfType(Class<T> type) {
    156             return this.beanFactory.getBeansOfType(type).values();
    157         }
    158 
    159         @Override
    160         public void addResourceHandlers(ResourceHandlerRegistry registry) {
    161             if (!this.resourceProperties.isAddMappings()) {
    162                 logger.debug("Default resource handling disabled");
    163                 return;
    164             }
    165             Integer cachePeriod = this.resourceProperties.getCachePeriod();
    166             if (!registry.hasMappingForPattern("/webjars/**")) {
    167                 customizeResourceHandlerRegistration(
    168                         registry.addResourceHandler("/webjars/**")
    169                                 .addResourceLocations(
    170                                         "classpath:/META-INF/resources/webjars/")
    171                         .setCachePeriod(cachePeriod));
    172             }
    173             String staticPathPattern = this.mvcProperties.getStaticPathPattern();
    174             if (!registry.hasMappingForPattern(staticPathPattern)) {
    175                 customizeResourceHandlerRegistration(
    176                         registry.addResourceHandler(staticPathPattern)
    177                                 .addResourceLocations(
    178                                         this.resourceProperties.getStaticLocations())
    179                         .setCachePeriod(cachePeriod));
    180             }
    181         }
    182 
    183         @Bean
    184         public WelcomePageHandlerMapping welcomePageHandlerMapping(
    185                 ResourceProperties resourceProperties) {
    186             return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage());
    187         }
    188 
    189         private void customizeResourceHandlerRegistration(
    190                 ResourceHandlerRegistration registration) {
    191             if (this.resourceHandlerRegistrationCustomizer != null) {
    192                 this.resourceHandlerRegistrationCustomizer.customize(registration);
    193             }
    194 
    195         }
    196 
    197         @Bean
    198         @ConditionalOnMissingBean({ RequestContextListener.class,
    199                 RequestContextFilter.class })
    200         public static RequestContextFilter requestContextFilter() {
    201             return new OrderedRequestContextFilter();
    202         }
    203 
    204         @Configuration
    205         @ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
    206         public static class FaviconConfiguration {
    207 
    208             private final ResourceProperties resourceProperties;
    209 
    210             public FaviconConfiguration(ResourceProperties resourceProperties) {
    211                 this.resourceProperties = resourceProperties;
    212             }
    213 
    214             @Bean
    215             public SimpleUrlHandlerMapping faviconHandlerMapping() {
    216                 SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
    217                 mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
    218                 mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
    219                         faviconRequestHandler()));
    220                 return mapping;
    221             }
    222 
    223             @Bean
    224             public ResourceHttpRequestHandler faviconRequestHandler() {
    225                 ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
    226                 requestHandler
    227                         .setLocations(this.resourceProperties.getFaviconLocations());
    228                 return requestHandler;
    229             }
    230 
    231         }
    232 
    233     }
    234 
    235     /**
    236      * Configuration equivalent to {@code @EnableWebMvc}.
    237      */
    238     @Configuration
    239     public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
    240 
    241         private final WebMvcProperties mvcProperties;
    242 
    243         private final ListableBeanFactory beanFactory;
    244 
    245         private final WebMvcRegistrations mvcRegistrations;
    246 
    247         public EnableWebMvcConfiguration(
    248                 ObjectProvider<WebMvcProperties> mvcPropertiesProvider,
    249                 ObjectProvider<WebMvcRegistrations> mvcRegistrationsProvider,
    250                 ListableBeanFactory beanFactory) {
    251             this.mvcProperties = mvcPropertiesProvider.getIfAvailable();
    252             this.mvcRegistrations = mvcRegistrationsProvider.getIfUnique();
    253             this.beanFactory = beanFactory;
    254         }
    255 
    256         @Bean
    257         @Override
    258         public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
    259             RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter();
    260             adapter.setIgnoreDefaultModelOnRedirect(this.mvcProperties == null ? true
    261                     : this.mvcProperties.isIgnoreDefaultModelOnRedirect());
    262             return adapter;
    263         }
    264 
    265         @Override
    266         protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {
    267             if (this.mvcRegistrations != null
    268                     && this.mvcRegistrations.getRequestMappingHandlerAdapter() != null) {
    269                 return this.mvcRegistrations.getRequestMappingHandlerAdapter();
    270             }
    271             return super.createRequestMappingHandlerAdapter();
    272         }
    273 
    274         @Bean
    275         @Primary
    276         @Override
    277         public RequestMappingHandlerMapping requestMappingHandlerMapping() {
    278             // Must be @Primary for MvcUriComponentsBuilder to work
    279             return super.requestMappingHandlerMapping();
    280         }
    281 
    282         @Bean
    283         @Override
    284         public Validator mvcValidator() {
    285             if (!ClassUtils.isPresent("javax.validation.Validator",
    286                     getClass().getClassLoader())) {
    287                 return super.mvcValidator();
    288             }
    289             return WebMvcValidator.get(getApplicationContext(),
    290                     getValidator());
    291         }
    292 
    293         @Override
    294         protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
    295             if (this.mvcRegistrations != null
    296                     && this.mvcRegistrations.getRequestMappingHandlerMapping() != null) {
    297                 return this.mvcRegistrations.getRequestMappingHandlerMapping();
    298             }
    299             return super.createRequestMappingHandlerMapping();
    300         }
    301 
    302         @Override
    303         protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
    304             try {
    305                 return this.beanFactory.getBean(ConfigurableWebBindingInitializer.class);
    306             }
    307             catch (NoSuchBeanDefinitionException ex) {
    308                 return super.getConfigurableWebBindingInitializer();
    309             }
    310         }
    311 
    312         @Override
    313         protected ExceptionHandlerExceptionResolver createExceptionHandlerExceptionResolver() {
    314             if (this.mvcRegistrations != null && this.mvcRegistrations
    315                     .getExceptionHandlerExceptionResolver() != null) {
    316                 return this.mvcRegistrations.getExceptionHandlerExceptionResolver();
    317             }
    318             return super.createExceptionHandlerExceptionResolver();
    319         }
    320 
    321         @Override
    322         protected void configureHandlerExceptionResolvers(
    323                 List<HandlerExceptionResolver> exceptionResolvers) {
    324             super.configureHandlerExceptionResolvers(exceptionResolvers);
    325             if (exceptionResolvers.isEmpty()) {
    326                 addDefaultHandlerExceptionResolvers(exceptionResolvers);
    327             }
    328             if (this.mvcProperties.isLogResolvedException()) {
    329                 for (HandlerExceptionResolver resolver : exceptionResolvers) {
    330                     if (resolver instanceof AbstractHandlerExceptionResolver) {
    331                         ((AbstractHandlerExceptionResolver) resolver)
    332                                 .setWarnLogCategory(resolver.getClass().getName());
    333                     }
    334                 }
    335             }
    336         }
    337 
    338     }
    339 
    340     @Configuration
    341     @ConditionalOnEnabledResourceChain
    342     static class ResourceChainCustomizerConfiguration {
    343 
    344         @Bean
    345         public ResourceChainResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer() {
    346             return new ResourceChainResourceHandlerRegistrationCustomizer();
    347         }
    348 
    349     }
    350 
    351     interface ResourceHandlerRegistrationCustomizer {
    352 
    353         void customize(ResourceHandlerRegistration registration);
    354 
    355     }
    356 
    357     private static class ResourceChainResourceHandlerRegistrationCustomizer
    358             implements ResourceHandlerRegistrationCustomizer {
    359 
    360         @Autowired
    361         private ResourceProperties resourceProperties = new ResourceProperties();
    362 
    363         @Override
    364         public void customize(ResourceHandlerRegistration registration) {
    365             ResourceProperties.Chain properties = this.resourceProperties.getChain();
    366             configureResourceChain(properties,
    367                     registration.resourceChain(properties.isCache()));
    368         }
    369 
    370         private void configureResourceChain(ResourceProperties.Chain properties,
    371                 ResourceChainRegistration chain) {
    372             Strategy strategy = properties.getStrategy();
    373             if (strategy.getFixed().isEnabled() || strategy.getContent().isEnabled()) {
    374                 chain.addResolver(getVersionResourceResolver(strategy));
    375             }
    376             if (properties.isGzipped()) {
    377                 chain.addResolver(new GzipResourceResolver());
    378             }
    379             if (properties.isHtmlApplicationCache()) {
    380                 chain.addTransformer(new AppCacheManifestTransformer());
    381             }
    382         }
    383 
    384         private ResourceResolver getVersionResourceResolver(
    385                 ResourceProperties.Strategy properties) {
    386             VersionResourceResolver resolver = new VersionResourceResolver();
    387             if (properties.getFixed().isEnabled()) {
    388                 String version = properties.getFixed().getVersion();
    389                 String[] paths = properties.getFixed().getPaths();
    390                 resolver.addFixedVersionStrategy(version, paths);
    391             }
    392             if (properties.getContent().isEnabled()) {
    393                 String[] paths = properties.getContent().getPaths();
    394                 resolver.addContentVersionStrategy(paths);
    395             }
    396             return resolver;
    397         }
    398 
    399     }
    400 
    401     static final class WelcomePageHandlerMapping extends AbstractUrlHandlerMapping {
    402 
    403         private static final Log logger = LogFactory
    404                 .getLog(WelcomePageHandlerMapping.class);
    405 
    406         private WelcomePageHandlerMapping(Resource welcomePage) {
    407             if (welcomePage != null) {
    408                 logger.info("Adding welcome page: " + welcomePage);
    409                 ParameterizableViewController controller = new ParameterizableViewController();
    410                 controller.setViewName("forward:index.html");
    411                 setRootHandler(controller);
    412                 setOrder(0);
    413             }
    414         }
    415 
    416         @Override
    417         public Object getHandlerInternal(HttpServletRequest request) throws Exception {
    418             for (MediaType mediaType : getAcceptedMediaTypes(request)) {
    419                 if (mediaType.includes(MediaType.TEXT_HTML)) {
    420                     return super.getHandlerInternal(request);
    421                 }
    422             }
    423             return null;
    424         }
    425 
    426         private List<MediaType> getAcceptedMediaTypes(HttpServletRequest request) {
    427             String acceptHeader = request.getHeader(HttpHeaders.ACCEPT);
    428             return MediaType.parseMediaTypes(
    429                     StringUtils.hasText(acceptHeader) ? acceptHeader : "*/*");
    430         }
    431 
    432     }
    433 
    434 }
      1 @ConfigurationProperties(prefix = "spring.mvc")
      2 public class WebMvcProperties {
      3 
      4     /**
      5      * Formatting strategy for message codes (PREFIX_ERROR_CODE, POSTFIX_ERROR_CODE).
      6      */
      7     private DefaultMessageCodesResolver.Format messageCodesResolverFormat;
      8 
      9     /**
     10      * Locale to use. By default, this locale is overridden by the "Accept-Language"
     11      * header.
     12      */
     13     private Locale locale;
     14 
     15     /**
     16      * Define how the locale should be resolved.
     17      */
     18     private LocaleResolver localeResolver = LocaleResolver.ACCEPT_HEADER;
     19 
     20     /**
     21      * Date format to use (e.g. dd/MM/yyyy).
     22      */
     23     private String dateFormat;
     24 
     25     /**
     26      * Dispatch TRACE requests to the FrameworkServlet doService method.
     27      */
     28     private boolean dispatchTraceRequest = false;
     29 
     30     /**
     31      * Dispatch OPTIONS requests to the FrameworkServlet doService method.
     32      */
     33     private boolean dispatchOptionsRequest = true;
     34 
     35     /**
     36      * If the content of the "default" model should be ignored during redirect scenarios.
     37      */
     38     private boolean ignoreDefaultModelOnRedirect = true;
     39 
     40     /**
     41      * If a "NoHandlerFoundException" should be thrown if no Handler was found to process
     42      * a request.
     43      */
     44     private boolean throwExceptionIfNoHandlerFound = false;
     45 
     46     /**
     47      * Enable warn logging of exceptions resolved by a "HandlerExceptionResolver".
     48      */
     49     private boolean logResolvedException = false;
     50 
     51     /**
     52      * Maps file extensions to media types for content negotiation, e.g. yml->text/yaml.
     53      */
     54     private Map<String, MediaType> mediaTypes = new LinkedHashMap<String, MediaType>();
     55 
     56     /**
     57      * Path pattern used for static resources.
     58      */
     59     private String staticPathPattern = "/**";
     60 
     61     private final Async async = new Async();
     62 
     63     private final Servlet servlet = new Servlet();
     64 
     65     private final View view = new View();
     66 
     67     public DefaultMessageCodesResolver.Format getMessageCodesResolverFormat() {
     68         return this.messageCodesResolverFormat;
     69     }
     70 
     71     public void setMessageCodesResolverFormat(
     72             DefaultMessageCodesResolver.Format messageCodesResolverFormat) {
     73         this.messageCodesResolverFormat = messageCodesResolverFormat;
     74     }
     75 
     76     public Locale getLocale() {
     77         return this.locale;
     78     }
     79 
     80     public void setLocale(Locale locale) {
     81         this.locale = locale;
     82     }
     83 
     84     public LocaleResolver getLocaleResolver() {
     85         return this.localeResolver;
     86     }
     87 
     88     public void setLocaleResolver(LocaleResolver localeResolver) {
     89         this.localeResolver = localeResolver;
     90     }
     91 
     92     public String getDateFormat() {
     93         return this.dateFormat;
     94     }
     95 
     96     public void setDateFormat(String dateFormat) {
     97         this.dateFormat = dateFormat;
     98     }
     99 
    100     public boolean isIgnoreDefaultModelOnRedirect() {
    101         return this.ignoreDefaultModelOnRedirect;
    102     }
    103 
    104     public void setIgnoreDefaultModelOnRedirect(boolean ignoreDefaultModelOnRedirect) {
    105         this.ignoreDefaultModelOnRedirect = ignoreDefaultModelOnRedirect;
    106     }
    107 
    108     public boolean isThrowExceptionIfNoHandlerFound() {
    109         return this.throwExceptionIfNoHandlerFound;
    110     }
    111 
    112     public void setThrowExceptionIfNoHandlerFound(
    113             boolean throwExceptionIfNoHandlerFound) {
    114         this.throwExceptionIfNoHandlerFound = throwExceptionIfNoHandlerFound;
    115     }
    116 
    117     public boolean isLogResolvedException() {
    118         return this.logResolvedException;
    119     }
    120 
    121     public void setLogResolvedException(boolean logResolvedException) {
    122         this.logResolvedException = logResolvedException;
    123     }
    124 
    125     public Map<String, MediaType> getMediaTypes() {
    126         return this.mediaTypes;
    127     }
    128 
    129     public void setMediaTypes(Map<String, MediaType> mediaTypes) {
    130         this.mediaTypes = mediaTypes;
    131     }
    132 
    133     public boolean isDispatchOptionsRequest() {
    134         return this.dispatchOptionsRequest;
    135     }
    136 
    137     public void setDispatchOptionsRequest(boolean dispatchOptionsRequest) {
    138         this.dispatchOptionsRequest = dispatchOptionsRequest;
    139     }
    140 
    141     public boolean isDispatchTraceRequest() {
    142         return this.dispatchTraceRequest;
    143     }
    144 
    145     public void setDispatchTraceRequest(boolean dispatchTraceRequest) {
    146         this.dispatchTraceRequest = dispatchTraceRequest;
    147     }
    148 
    149     public String getStaticPathPattern() {
    150         return this.staticPathPattern;
    151     }
    152 
    153     public void setStaticPathPattern(String staticPathPattern) {
    154         this.staticPathPattern = staticPathPattern;
    155     }
    156 
    157     public Async getAsync() {
    158         return this.async;
    159     }
    160 
    161     public Servlet getServlet() {
    162         return this.servlet;
    163     }
    164 
    165     public View getView() {
    166         return this.view;
    167     }
    168 
    169     public static class Async {
    170 
    171         /**
    172          * Amount of time (in milliseconds) before asynchronous request handling times
    173          * out. If this value is not set, the default timeout of the underlying
    174          * implementation is used, e.g. 10 seconds on Tomcat with Servlet 3.
    175          */
    176         private Long requestTimeout;
    177 
    178         public Long getRequestTimeout() {
    179             return this.requestTimeout;
    180         }
    181 
    182         public void setRequestTimeout(Long requestTimeout) {
    183             this.requestTimeout = requestTimeout;
    184         }
    185 
    186     }
    187 
    188     public static class Servlet {
    189 
    190         /**
    191          * Load on startup priority of the dispatcher servlet.
    192          */
    193         private int loadOnStartup = -1;
    194 
    195         public int getLoadOnStartup() {
    196             return this.loadOnStartup;
    197         }
    198 
    199         public void setLoadOnStartup(int loadOnStartup) {
    200             this.loadOnStartup = loadOnStartup;
    201         }
    202 
    203     }
    204 
    205     public static class View {
    206 
    207         /**
    208          * Spring MVC view prefix.
    209          */
    210         private String prefix;
    211 
    212         /**
    213          * Spring MVC view suffix.
    214          */
    215         private String suffix;
    216 
    217         public String getPrefix() {
    218             return this.prefix;
    219         }
    220 
    221         public void setPrefix(String prefix) {
    222             this.prefix = prefix;
    223         }
    224 
    225         public String getSuffix() {
    226             return this.suffix;
    227         }
    228 
    229         public void setSuffix(String suffix) {
    230             this.suffix = suffix;
    231         }
    232 
    233     }
    234 
    235     public enum LocaleResolver {
    236 
    237         /**
    238          * Always use the configured locale.
    239          */
    240         FIXED,
    241 
    242         /**
    243          * Use the "Accept-Language" header or the configured locale if the header is not
    244          * set.
    245          */
    246         ACCEPT_HEADER
    247 
    248     }
    249 
    250 }

     3.2 接管spring boot的web配置

      在既需要保留spring boot提供的便利,又需要增加自己的额外的配置的时候,可以定义一个配置类并继承WebMvcConfigurerAdapter,无须使用@EnableWebMvc注解,然后按照spring mvc的配置方法来添加spring boot其他配置。值得指出的是重写addViewControllers方法,并不会覆盖WebMvcConfigurerAdapter中的addViewControllers(在此方法中,spring boot 将“/”映射至index.html),这也就意味着我们自己的配置和spring boot的自动配置同时有效,这也是推荐添加自己的mvc配置的方式。

     3.3 注册servlet、filter、Listener

      当使用嵌入式的servlet容器(tomcat、jetty等)时,通过将servlet、filter和listener声明为spring bean而达到注册的效果;或者注册ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean的bean。

    3.4 Tomcat配置

      关于tomcat的所有属性都在org.springframework.boot.autoconfigure.web.ServerProperties配置类中做了定义,我们只需要在application.Properties配置属性做配置即可。通用的Servlet容器配置都以“server”作为前缀,而tomcat特有的配置都以“server.tomcat”作为前缀。配置tomcat还可以用代码的方式配置,以后再说。

  • 相关阅读:
    CodeForces 510C Fox And Names (拓扑排序)
    Codeforces 1153D Serval and Rooted Tree (简单树形DP)
    HDU 6437 Problem L.Videos (最大费用)【费用流】
    Luogu P3381 (模板题) 最小费用最大流
    Codeforces 741B Arpa's weak amphitheater and Mehrdad's valuable Hoses (并查集+分组背包)
    Codeforces 1144F Graph Without Long Directed Paths (DFS染色+构造)
    HDU 2204 Eddy's 爱好 (容斥原理)
    Codeforces 939E Maximize! (三分 || 尺取)
    Codeforces 938D. Buy a Ticket (最短路+建图)
    CodeForces 959E Mahmoud and Ehab and the xor-MST (MST+找规律)
  • 原文地址:https://www.cnblogs.com/kevin443/p/6719365.html
Copyright © 2011-2022 走看看