Spring启动响应压缩无法正常工作

Qua*_*ing 23 java spring spring-mvc spring-boot

我有一些相当大的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
Run Code Online (Sandbox Code Playgroud)

但它不起作用.没有压缩发生.

请求标头:

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
Run Code Online (Sandbox Code Playgroud)

响应标头

Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Connection:keep-alive
Content-Length:842821
Content-Type:application/javascript;charset=UTF-8
Run Code Online (Sandbox Code Playgroud)

响应中没有内容编码标头.

我正在使用spring boot version 1.3.5.RELEASE

我错过了什么?

===编辑4 ===我计划创建一个独立的应用程序,以进一步调查内容压缩属性无法正常工作的原因.但突然之间它开始工作了,我没有改变配置方面的任何事情,不是POM文件更改,而不是application.yml文件更改.所以我不知道发生了什么变化让它发挥作用......

===编辑3 === 进一步关注@ chimmi的建议.我在建议的地方放了断点.看起来对静态资源(js文件)的请求从未在这些断点处停止.只有休息API请求才能执行.并且对于那些请求,由于某种原因,内容长度为零,这导致跳过内容压缩.

在此输入图像描述

===编辑2 === 我在osbawServerProperties第180行设置了一个断点,感谢@ chimmi的建议,它显示所有属性都设置但不知何故服务器不尊重设置...... :(

在osbawServerProperties第180行打印压缩对象

===编辑1 ===

不确定是否重要,但我在这里粘贴我的应用程序主要和配置代码:

Application.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();
    }
}
Run Code Online (Sandbox Code Playgroud)

组态:

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

资源服务器配置:

@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
    }
}
Run Code Online (Sandbox Code Playgroud)

Pat*_*ski 7

也许问题出在 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
Run Code Online (Sandbox Code Playgroud)


Gan*_*alf 5

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>
Run Code Online (Sandbox Code Playgroud)

添加到您的 @Config 类:

@Bean
public Filter compressingFilter() {
    return new CompressingFilter();
}
Run Code Online (Sandbox Code Playgroud)

  • Spring 已经包含了一个 servlet 库,这就是您排除这个库的原因。另外这篇文章已经有 4 年历史了,我确信 Spring Boot 中的压缩现在可以正常工作了。 (2认同)

Pat*_*ski 2

如果您使用非嵌入式 Tomcat,您应该将其添加到您的 server.xml 中:

compression="on" 
compressionMinSize="2048" 
compressableMimeType="text/html,text/xml,application/javascript"
Run Code Online (Sandbox Code Playgroud)

更多 tomcat 8 配置变量