初入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还可以用代码的方式配置,以后再说。

时间: 04-16

初入spring boot(四 )web项目的相关文章

初入spring boot(八 )Spring Data REST

1. 什么是Spring Data REST Spring Data JPA是基于Spring Data 的Repository之上,可以将Repository自动输出为REST资源.目前Spring Data REST支持将Spring Data JPA.Spring Data MongoDB.Spring Data Neo4j.Spring Data Gemfire以及Spring Data Cassandra的Repository自动转换成REST服务. 2. Spring mvc中配置使

初入spring boot(五 )Spring Data JPA

Spring Data JPA通过提供基于JPA的Repository极大地减少JPA作为数据访问方案的代码量. 1.定义数据访问层 使用Spring Data JPA建立数据访问层十分简单,只需定义一个继承JpaRepository的接口即可,接口如下: 1 @RepositoryRestResource(path = "people") 2 public interface PersonRepository extends JpaRepository<Person, Long

从零一起学Spring Boot之LayIM项目长成记(一) 初见 Spring Boot

项目背景 之前写过LayIM的.NET版后端实现,后来又写过一版Java的.当时用的是servlet,websocket和jdbc.虽然时间过去很久了,但是仍有些同学在关注.偶然间我听说了SpringBoot这么个东东,据说是省去了很多繁杂的配置.可以傻瓜式的创建项目,轻轻松松做出一个网站来,那么出于我对LayIM的情有独钟,于是乎想借用它来帮助我学习SpringBoot,并且全程记录,省的以后再走弯路和掌握解决问题的方法.(当然,我也是新手,我的解决方法就是百度,stackovreflow等网

Spring Boot 多模块项目创建与配置 (一) (转)

最近在负责的是一个比较复杂项目,模块很多,代码中的二级模块就有9个,部分二级模块下面还分了多个模块.代码中的多模块是用maven管理的,每个模块都使用spring boot框架.之前有零零散散学过一些maven多模块配置的知识,但没自己从头到尾创建和配置过,也快忘得差不多了.这次正好对照着这个项目,动手实践一下,下面我们就开始吧. maven多模块项目通常由一个父模块和若干个子模块构成,每个模块都对应着一个pom.xml.它们之间通过继承和聚合(也称作多模块)相互关联.多模块适用于一些比较大的项

Spring Boot -05- 多模块结构项目构建与测试(详细图文教程)IDEA 版

Spring Boot -05- 多模块结构项目构建与测试(详细图文教程)IDEA 版 百度很多博客都不详细,弄了半天才把 Spring Boot 多模块项目构建开发整的差不多,特地重新创建配置,记录一下,也分享给有需要的人 本篇也会非常详细的介绍涉及的基础知识点,更多都写在注释上了 先放成功截图: (1)项目结构: (2)启动: (3)测试主子模块: (4)测试子模块依赖: 第一步:创建父模块,子模块 (1)打开创建项目窗口,点击 Create New Project (2)填写 (3)填写

【Spring Boot】利用 Spring Boot Admin 进行项目监控管理

利用 Spring Boot Admin 进行项目监控管理 一.Spring Boot Admin 是什么 Spring Boot Admin (SBA) 是一个社区开源项目,用于管理和监视 Spring Boot 应用程序.应用程序通过 http 的方式注册到 Spring Boot 管理客户端,或者通过 Spring Cloud 的服务发现机制,然后针对 actuator 接口将数据通过 Vue.js 进行可视化管理. 对于我们来说,我们可以通过 Spring Boot Admin 浏览所有

Github 上 Star 最多的个人 Spring Boot 开源学习项目

2016年,在一次技术调研的过程中认识到了 Spring Boot ,试用之后便一发不可收拾的爱上它.为了防止学习之后忘记,就在网上连载了 Spring Boot 系列文章,没想到这一开始便与 Spring Boot 深度结缘. 近三年的时间写了一百多篇关于 Spring Boot 的文章(包含两个课程),在写文章的过程中将文中的示例项目托管在 Github 上面,随着学习 Spring Boot 的朋友越来越多,在 Github 上面的关注(Star)人数也越来越多,到现在已经高达 8300

Spring Boot开发Web应用之Thymeleaf篇

前言 Web开发是我们平时开发中至关重要的,这里就来介绍一下Spring Boot对Web开发的支持. 正文 Spring Boot提供了spring-boot-starter-web为Web开发予以支持,spring-boot-starter-web为我们提供了嵌入的Tomcat以及Spring MVC的依赖. 项目结构推荐 一个好的项目结构会让你开发少一些问题,特别是Spring Boot中启动类要放在root package下面,我的web工程项目结构如下: root package结构:

Spring Boot 整合web层之JSON的使用

Spring Boot对web层进行了一系列的自动化配置,只需要引入web依赖,零配置,就可以直接使用spring  mvc 里面的东西,这篇看一下它对json的自动化配置: 创建一个web项目,勾选web的依赖,就可以看到依赖里面引入了json 在前后端分离的项目中,前后端的交互是通过json格式进行的.那么在Spring Boot中如何使用呢? 我们先看一个消息转化工具(HttpMessageConverter),所用的json生成都离不开它,它的作用: 1.将服务端返回的对象序列化成JSO