初入spring boot(四 )web项目

Posted kevin_shen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初入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 以上是关于初入spring boot(四 )web项目的主要内容,如果未能解决你的问题,请参考以下文章

初入Spring-boot

初入spring boot(五 )Spring Data JPA

初入spring boot(八 )Spring Data REST

Spring boot 默认首页配置 Spring boot web默认首页配置 Spring boot web项目默认首页配置

Spring boot Sample 012之spring-boot-web-upload

Spring boot Sample 012之spring-boot-web-upload