[英]Spring boot response compression not working
我有一些非常大的 javascript 捆绑文件,~1MB。 我正在尝试在我的 yml 文件中使用以下应用程序属性打开响应压缩:
server.compression.enabled: true
server.compression.mime-types: application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
但它不起作用。 没有压缩发生。
请求标头:
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Accept: */*
Accept-Encoding: gzip, deflate, sdch, br
响应头
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Connection:keep-alive
Content-Length:842821
Content-Type:application/javascript;charset=UTF-8
响应中没有内容编码 header。
我正在使用 spring 启动版本 1.3.5.RELEASE
我错过了什么?
=== 编辑 4 === 我正计划创建一个独立的应用程序来进一步调查为什么内容压缩属性不起作用。 但突然间它开始工作,我没有改变任何配置方面的东西,不是 POM 文件更改,不是 application.yml 文件更改。 所以我不知道是什么改变让它起作用了……
===编辑 3===进一步遵循@chimmi 的建议。 我在建议的地方放置了断点。 看起来对 static 资源(js 文件)的请求从未在这些断点处停止。 只有 rest API 请求可以。 对于那些请求,内容长度由于某种原因为零,导致内容压缩被跳过。
===编辑 2===由于@chimmi 的建议,我在 osbawServerProperties 的第 180 行设置了一个断点,它显示所有属性都已设置,但不知何故服务器不遵守该设置...:(
===编辑1===
不确定这是否重要,但我在此处粘贴了我的应用程序主要代码和配置代码:
应用.java:
@SpringBootApplication
public class TuangouApplication extends SpringBootServletInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(TuangouApplication.class, args);
}
// this is for WAR file deployment
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(TuangouApplication.class);
}
@Bean
public javax.validation.Validator localValidatorFactoryBean() {
return new LocalValidatorFactoryBean();
}
}
配置:
@Configuration
public class TuangouConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.antMatcher("/**").authorizeRequests().antMatchers("/", "/login**").permitAll()
.and().antMatcher("/**").authorizeRequests().antMatchers("/api/**").permitAll()
.and().exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/"))
.and().formLogin().loginPage("/login").failureUrl("/login?error").permitAll()
.and().logout().logoutSuccessUrl("/").permitAll()
.and().csrf().csrfTokenRepository(csrfTokenRepository())
.and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
.headers().defaultsDisabled().cacheControl();
// @formatter:on
}
@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled=true)
protected static class AuthenticationSecurity extends GlobalAuthenticationConfigurerAdapter {
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService()).passwordEncoder(new BCryptPasswordEncoder());
}
@Bean
public UserDetailsService userDetailsService() {
return new DatabaseUserServiceDetails();
}
}
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request
.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null
|| token != null && !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
}
资源服务器配置:
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{
@Autowired
private TokenStore tokenStore;
@Override
public void configure(ResourceServerSecurityConfigurer resources)
throws Exception {
resources.tokenStore(tokenStore);
}
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.antMatcher("/**").authorizeRequests().antMatchers("/api/**").permitAll();
// @formatter:on
}
}
也许问题出在 YAML 配置上。 如果您使用 'Starters' SnakeYAML 将通过spring-boot-starter
自动提供。 如果不这样做 - 您必须在 application.properties 中使用属性约定。 使用 YAML 而不是属性
编辑:在你的 yml 文件中试试这个:
server:
compression:
enabled: true
mime-types: text/html,text/xml,text/plain,text/css,application/javascript,application/json
min-response-size: 1024
Spring Boot 压缩从来没有好运。 一个简单的解决方案可能是使用第三方库,如 ziplet。
添加到 pom.xml
<dependency>
<groupId>com.github.ziplet</groupId>
<artifactId>ziplet</artifactId>
<version>2.0.0</version>
<exclusions>
<exclusion>
<artifactId>servlet-api</artifactId>
<groupId>javax.servlet</groupId>
</exclusion>
</exclusions>
</dependency>
添加到您的 @Config 类:
@Bean
public Filter compressingFilter() {
return new CompressingFilter();
}
如果您使用非嵌入式 Tomcat,您应该将其添加到您的 server.xml 中:
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,application/javascript"
您是否尝试过使用不同的浏览器? 这可能是因为防病毒软件正在解压缩文件,如 SO post Spring boot http response compression 不适用于某些 User-Agents
您必须像 http2 模式一样启用 ssl,当配置了 ssl 模式时,响应压缩(内容编码)才能工作。
应用程序.yml
server:
compression:
enabled: true
mime-types: text/html,text/xml,text/plain,text/css, application/javascript, application/json
min-response-size: 1024
ssl:
enabled: true
key-store: keystore.p12
key-store-password: pass
keyStoreType: PKCS12
keyAlias: name
spring:
resources:
chain:
gzipped: true
我在生产上遇到了同样的问题。 我的配置文件如下:
server:
port: 8080
compression:
enabled: true
mime-types: text/html,text/xml,text/plain,text/css, application/javascript, application/json
min-response-size: 1024
由于我没有使用嵌入式 tomcat,我必须通过编辑server.xml
文件的以下部分来启用 Tomcat 本身的压缩:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" compression="on"/>
确保此部分有compression="on"
部分,问题应该已解决
升级到 Spring Boot 2.6 时,我必须将以下内容添加到我的application.yml
以允许压缩 static 资源:
spring:
web:
resources:
chain:
compressed: true
server.compression
设置似乎对此没有影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.