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

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

  1. 使用Spring Boot开发Web项目(二)之添加HTTPS支持

    上篇博客使用Spring Boot开发Web项目我们简单介绍了使用如何使用Spring Boot创建一个使用了Thymeleaf模板引擎的Web项目,当然这还远远不够.今天我们再来看看如何给我们的We ...

  2. 【spring boot】5.spring boot 创建web项目并使用jsp作前台页面

    贼烦的是,使用spring boot 创建web项目,然后我再idea下创建的,but 仅仅启动spring boot的启动类,就算整个项目都是好着的,就算是能够进入controller中,也不能成功 ...

  3. 使用Spring Boot开发Web项目

    前面两篇博客中我们简单介绍了Spring Boot项目的创建.并且也带小伙伴们来DIY了一个Spring Boot自动配置功能,那么这些东西说到底最终还是要回归到Web上才能体现出它的更大的价值,so ...

  4. spring boot 搭建web项目常见五种返回形式

    在web项目中一般常见的五种返回形式: 返回页面,使用模板引擎,spring boot推荐使用thymeleaf,类似的还有freemarker等. 返回字符串(json),一般用于完全的前后端分离开 ...

  5. Spring Boot搭建Web项目常用功能

    搭建WEB项目过程中,哪些点需要注意: 1.技术选型: 前端:freemarker.vue 后端:spring boot.spring mvc 2.如何包装返回统一结构结果数据? 首先要弄清楚为什么要 ...

  6. 初入spring boot(七 )Spring Data JPA

    Spring Data JPA通过提供基于JPA的Repository极大地减少JPA作为数据访问方案的代码量. 1.定义数据访问层 使用Spring Data JPA建立数据访问层十分简单,只需定义 ...

  7. 基于Spring boot的web项目搭建教程(一)

    前言: 本教程参考了大量前辈的代码,在此不方便一一列举.本教程使用IDEA开发工具搭建项目,对于本人的IDEA已经集成了某些插件,比如Lombok,Thymeleaf,yml等插件,这些插件不在文中提 ...

  8. 初入spring boot(八 )Spring Data REST

    1. 什么是Spring Data REST Spring Data JPA是基于Spring Data 的Repository之上,可以将Repository自动输出为REST资源.目前Spring ...

  9. 初入spring boot(五 )websocket

    一.广播式 广播式即服务端有消息时,会将消息发送给所有连接了当前endpoint的浏览器 1.配置websocket,需要在配置类上使用@EnableWebSocketMessageBroker开启w ...

随机推荐

  1. windows程序查看可以行文件依赖库

    通常在做windows下开发程序,发布的时候需要同时打包一些依赖库:我们可以通过工具直接查看需要发布的程序依赖的程序,这样可以方便快捷的打包程序 这里我们推荐使用:dependencywalker 下 ...

  2. delphi 事件记录

    delphi常用事件 序号 事件 描述 1. OnActive 焦点称到窗体或控件时发生 2. OnClick 鼠标单击事件 3. OnDbClick 鼠标双击事件 4. OnClose和OnClos ...

  3. 在Sql Server中使用证书加密数据

    IF NOT EXISTS () CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'QWE23987zxJKL569&agf1$94467GRkjg5k3 ...

  4. use getters and setters Learning PHP Design Patterns

    w Learning PHP Design Patterns Much of what passes as OOP misuses getters and setters, and making ac ...

  5. <2014 03 18> Term BreakPoint

  6. VS c++ opencv画图

    任务:用c++在图片上画线 之前用过python的opencv,所以直接想到了用c++的opencv来画线. 但关键就是VS中如何配置c++ opencv库的问题: vs中opencv库的配置:htt ...

  7. 在容器最前面添加DOM元素 parent.insertBefore(new, parent.children[0])

    //判断容器当前有没有子级元素,如果没有直接appendChild就行了; if (p.children[0]) { p.insertBefore(span, p.children[0]); } el ...

  8. 解决python中write()函数向文件中写中文时出现乱码的问题

    今天看<python编程从入门到实践>的第10章文件.异常,在做练习的时候,向文件中写内容,但是写中文就不行,后来在百度上查了众多资料,解决方法如下: 解决:在open()函数中添加一个e ...

  9. Linux学习笔记(4)磁盘分区(fdisk)、挂载与文件系统命令

    Linux学习笔记(4)磁盘分区(fdisk).挂载与文件系统命令 1.磁盘分区是怎么表示的? 1.1 对于IDE接口,第一主盘为hda,第1从盘为hdb,第1从盘的第1个分区为hdb1 1.2 对于 ...

  10. HTML5 canvas绘图基本使用方法

    <canvas></canvas>是HTML5中新增的标签,用于绘制图形,实际上,这个标签和其他的标签一样,其特殊之处在于该标签可以获取一个CanvasRenderingCon ...