Spring Boot, static resources and mime type config

2020-07-13 06:36发布

问题:

I'm facing a Spring Boot configuration issue I can't deal with... I'm trying to build an HelloWorld example for HbbTV with Spring Boot, so I need to serve my "index.html" page with mime-type="application/vnd.hbbtv.xhtml+xml"

my index.html will be accessed as a static page, for instance http://myserver.com/index.html?param=value.

with the following code, no matter how hard I try, I get a text/html content type.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//HbbTV//1.1.1//EN" "http://www.hbbtv.org/dtd/HbbTV-1.1.1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>MyApp HBBTV</title>
    <meta http-equiv="content-type" content="Content-Type: application/vnd.hbbtv.xhtml+xml; charset=UTF-8" />
</head>
<body>
...
</body>
</html>

So I tried to add a "home()" endpoint into a @Controller to force the correct mime-type, and that works.

@RestController
public class HbbTVController {

    @RequestMapping(value = "/hbbtv", produces = "application/vnd.hbbtv.xhtml+xml")
    String home() {
        return "someText";
    }
...
}

"That works" mean the jetty server serves me a html file with the correct content-type containing the test someText.

My next try were to replace the @RestController by @Controller (same produce config), and replace "someText" by index.html

@Controller
public class HbbTVController {

    @RequestMapping(value = "/hbbtv", produces = "application/vnd.hbbtv.xhtml+xml")
    String home() {
        return "index.html";
    }
...
}

Well, it serves my index.html correctly, but the Content-Type is wrong : text/html instead of application/vnd.hbbtv.xhtml+xml. Furthermore, I don't want to access to myserver.com/hbbtv to get index.html, but directly to myserver.com/index.html.

How could I do that ?

Thanks...

回答1:

Well, finally, I found the "Spring boot compliant solution". It's the same as Jamie Birch suggested, but realized with Spring mechanisms.

Spring Boot 1:

@Configuration
public class HbbtvMimeMapping implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
        mappings.add("html", "application/vnd.hbbtv.xhtml+xml; charset=utf-8");
        mappings.add("xhtml", "application/vnd.hbbtv.xhtml+xml; charset=utf-8");
        container.setMimeMappings(mappings);
    }

}

Spring Boot 2:

@Configuration
public class HbbtvMimeMapping implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {
        MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
        mappings.add("html", "application/vnd.hbbtv.xhtml+xml; charset=utf-8");
        mappings.add("xhtml", "application/vnd.hbbtv.xhtml+xml; charset=utf-8");
        factory.setMimeMappings(mappings);
    }
}


回答2:

Can't help with the Spring Boot side, but if you get no other responses, try these:

  • Set the file-type as .xhtml rather than .html.

  • Provide a mapping from .xhtml to MIME type application/vnd.hbbtv.xhtml+xml on your Jetty server's mime.properties file. A few more details on how to do that here.



回答3:

I'll extend comment providen by @Cheloute Sping boot have default mime types https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/MimeMappings.java

to override already setted mime type you should remove it first

Here is example what I used to override js and css

@Configuration
public class CustomServletConfiguration implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {
        MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
        mappings.remove("js");
        mappings.add("js", "application/javascript;charset=utf-8");
        mappings.remove("css");
        mappings.add("css", "text/css;charset=utf-8");
        factory.setMimeMappings(mappings);
        factory.setPort(9000);

    }
}