Spring Boot has the ability to host static resources (https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot- There is features-spring-mvc-static-content), but unlike the response from Controller, I was addicted to not giving charset to Content-Type in the response header of the static resource.
Expected response header
Content-Type: text/html;charset=UTF-8
Actual response header
Content-Type: text/html
You can specify the encoding for files with a specific extension by implementing WebServerFactoryCustomizer to customize the behavior of the built-in Tomcat container. However, only if the charset is uniquely determined for the extension.
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.MimeMappings;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
@Component
public class ServletCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory factory) {
MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
mappings.add("html", "text/html;charset=UTF-8");
factory.setMimeMappings(mappings);
}
}
I will leave a few ideas I tried before I got here.
By adjusting the setting of application.properties, the behavior of CharacterEncodingFilter can be changed. You can change it and force the charset to be output.
application.properties
# Charset of HTTP requests and responses.
spring.http.encoding.charset=UTF-8
# Whether to force the encoding to the configured charset on HTTP responses.
spring.http.encoding.force-response=true
It works as expected for HTML files, but as the name suggests, it is forcibly added to image files, etc., which is a shame.
Content-Type: image/jpeg;charset=UTF-8
CharacterEncodingFilter outputs uniformly, so it seems good to derive this class and implement your own filter.
At first glance it seems to work, but this method is limited to cases where it can be uniquely determined from the request URL.
If you are doing something like returning index.html as a fallback page if the path cannot be resolved (as I did in my case), the request URL will not necessarily include the extension. Not always, so there is not enough information to make the decision.
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**/*")
.addResourceLocations("classpath:/static/")
.resourceChain(true)
.addResolver(new PathResourceResolver() {
@Override
protected Resource getResource(String resourcePath, Resource location) throws IOException {
Resource requestedResource = location.createRelative(resourcePath);
return requestedResource.exists() && requestedResource.isReadable()
? requestedResource : new ClassPathResource("/static/index.html");
}
});
}
}
Recommended Posts