2014-09-04 113 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); 
     } 
    } 

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