2014-09-04 86 views
4

我已在thymeleaf html页面如下:春天启动不提供静态内容与Thymeleaf

<head th:fragment="header"> 

    <meta charset="utf-8" /> 
    <link rel="stylesheet" href="../../css/main.css" th:href="@{/css/main.css}" /> 
    <title th:text="#{device.page.title}">Title</title> 
</head> 

<body> 
<div> 
    <h1 th:text="#{device.table.caption}"></h1> 
    <hr class="fineline"/> 
    Select devices using the checkboxes, you can update the client version or add client commands. 
    <form action="#" th:action="@{/devices/modify}" th:object="${deviceCommand}" method="post"> 
    <table border="0" cellpadding="0" cellspacing="0" class="touchTable"> 
     <!--<thead> --> 
      <tr> 
       <td scope="col" th:text="#{device.check.label}">Select</td> 
       <td width="300" scope="col"><span th:text="#{device.id.label}"></span>&nbsp;(<span th:text="#{device.retailer.name.label}"></span>)</td> 
       <td scope="col" th:text="#{device.current.label}">Curr Version</td> 
       <td scope="col" th:text="#{device.next.label}">Next Version</td> 
       <td scope="col" th:text="#{device.commands.label}">Commands</td> 
      </tr> 
     <!--</thead>--> 
     <!--<tbody> --> 
      <tr th:each="d : ${devices}"> 
       <td><input type="checkbox" th:field="*{deviceModificationIds}" th:value="${d.id}"/></td> 
       <td><span th:text="${d.id}"></span>&nbsp;(<span th:text="${d.retailerName}"></span>)</td> 
       <td th:text="${d.currentClientVersion}">Washington</td> 
       <td th:text="${d.nextClientVersion}">gwash</td> 
       <td th:text="${d.commands}">gwash</td> 
      </tr> 
      <tr> 
       <td colspan="2"></td> 
       <td><span th:text="#{device.change.version.label}"></span><br/><input type="text" th:field="*{newVersion}"/></td> 
       <td><span th:text="#{device.add.command.label}"></span><br/><input type="text" th:field="*{newCommand}"/></td> 
       <td><br/><button type="submit" th:text="#{device.modify.action.button}">Action</button></td> 
      </tr> 
     <!--</tbody> --> 
    </table> 
    </form> 


</div> 
</body> 

的问题是与CSS样式表。基本上春天似乎并不能够找到它,despit我将文件放到/resources/static/css/main.css

它返回错误(在日志):

o.s.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/css/main.css] in DispatcherServlet with name 'dispatcherServlet' 

现在DOCO所有说,春季启动应自动发球局中/资源的事物/静态

这里是我的WebConfig:

@Configuration 
@ComponentScan("com.txxxxcorp.txxxxpoint.resource") 
@EnableWebMvc 
public class WebConfig { 

    @Bean 
    MultipartConfigElement multipartConfigElement() { 
     MultiPartConfigFactory factory = new MultiPartConfigFactory(); 
     factory.setMaxFileSize("4096KB"); 
     factory.setMaxRequestSize("4096KB"); 
     return factory.createMultipartConfig(); 
    } 

    @Bean 
    public ViewResolver viewResolver() { 
     ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver(); 
     templateResolver.setTemplateMode("XHTML"); 
     templateResolver.setPrefix("templates/"); 
     templateResolver.setSuffix(".html"); 

     SpringTemplateEngine engine = new SpringTemplateEngine(); 
     engine.setTemplateResolver(templateResolver); 

     ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); 
     viewResolver.setTemplateEngine(engine); 

     String[] excludedViews = new String[]{ 
      "/resources/static/**"}; 
     viewResolver.setExcludedViewNames(excludedViews); 

     return viewResolver; 
    } 

    @Bean 
    public EmbeddedServletContainerCustomizer servletContainerCustomizer() { 
     return new EmbeddedServletContainerCustomizer() { 
      @Override 
      public void customize(ConfigurableEmbeddedServletContainer servletContainer) { 
       ((TomcatEmbeddedServletContainerFactory) servletContainer).addConnectorCustomizers(
         new TomcatConnectorCustomizer() { 
          @Override 
          public void customize(Connector connector) { 
           AbstractHttp11Protocol httpProtocol = (AbstractHttp11Protocol) connector.getProtocolHandler(); 
           httpProtocol.setCompression("on"); 
           httpProtocol.setCompressionMinSize(256); 
           String mimeTypes = httpProtocol.getCompressableMimeTypes(); 
           String mimeTypesWithJson = mimeTypes + "," + MediaType.APPLICATION_JSON_VALUE; 
           httpProtocol.setCompressableMimeTypes(mimeTypesWithJson); 
          } 
         } 
       ); 
      } 
     }; 
    } 

    @Bean 
    public ResourceBundleMessageSource messageSource() { 
     ResourceBundleMessageSource source = new ResourceBundleMessageSource(); 
     source.setBasename("messages"); 
     return source; 
    } 

出于某种原因,该编辑器不会让我插入spring安全配置没有抱怨它没有正确格式化(IntelliJ,Maven和Spring Boot不同意这个,因为它编译和工作),请放心,我已允许/css/main.css路径经过

任何人都知道为什么我无法解决的CSS文件?

+0

是否有你有一些特殊原因不使用'@ EnableAutoConfiguration',你自己配置Spring MVC?我很确定Spring Boot没有提供静态内容,因为你的所有自动配置已被禁用 – geoand 2014-09-04 09:35:30

+0

我在应用程序启动器上有@EnableAutoConfiguration,我认为这是你需要的唯一地方吗? – 2014-09-04 09:43:14

+0

好吧,我明白了。但是,您拥有'@ EnableWebMvc'会禁用MVC自动配置。参见http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-spring-mvc-auto-configuration – geoand 2014-09-04 09:45:10

回答

10

您使用@EnableWebMvc的事实关闭了Spring Boot的MVC自动配置(以及因此静态资源处理)。

要启用静态资源处理,最好的解决方案是删除@EnableWebMvc并让Spring Boot做它最擅长的功能 - 自动配置。

变更后,你应该做一些回归测试,以确保没有别的爆发

+0

如果你使用spring安全性,你需要在antMatchers()中添加“/ css/**”。permitAll() – fjkjava 2015-10-26 20:10:50

+0

@fjkjava这是真的。然而,在这个问题中没有提到Spring安全问题,所以我没有在答案中提出任何这样的问题 – geoand 2015-10-26 20:38:53

1

@ geoand的答案是正确的,你的应用程序的静态资源是关掉当你使用@enablWebMvc。所以你在这里使用被解析的thyemeleaf任何CSS文件,你需要声明的类继承了该WebMvcAutoConfigurationAdapter并覆盖addResourceHandlers方法, 代码可能是象下面这样:

@Configuration 
    @ComponentScan("com.txxxxcorp.txxxxpoint.resource") 
    @EnableWebMvc 
    public class WebConfig extends WebMvcConfigurerAdapter { 

@Override 
    public void addResourceHandlers(ResourceHandlerRegistry registry) { 
     String[] STATIC_RESOURCE = {"/","classpath:/","classpath:/META-INF/resources/", "classpath:/META-INF/resources/webjars/", 
       "classpath:/resources/", "classpath:/static/", "classpath:/public/"}; 

     if (!registry.hasMappingForPattern("/**")) { 
      registry.addResourceHandler("/**").addResourceLocations(STATIC_RESOURCE); 
     } 
    } 

....................... 
}