Ответ 1
Если вы используете не встроенный Tomcat, вы должны добавить его на свой сервер. xml:
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,application/javascript"
У меня есть файл с javascript, который довольно большой, ~ 1 МБ. Я пытаюсь включить сжатие ответов со следующими свойствами приложения в моем 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
В ответе нет заголовка кодировки содержимого.
Я использую spring версию для загрузки 1.3.5.RELEASE
Что мне не хватает?
=== РЕДАКТИРОВАТЬ 4 === Я планировал создать автономное приложение для дальнейшего исследования, почему свойства сжатия содержимого не работали. Но внезапно он начал работать, и я не изменил ничего конфигурационного, а не изменения файла POM, а не изменения файла application.yml. Поэтому я не знаю, что изменилось, что заставило его работать...
=== РЕДАКТИРОВАТЬ 3 === Следуйте дальнейшим предложениям @chimmi. Я поставил точки разрыва в предложенных местах. Похоже, что запросы на статические ресурсы (файлы js) никогда не останавливались в этих точках разрыва. Выполняются только запросы API для отдыха. И для этого запроса длина контента по какой-то причине была нулевой, что заставляло пропускать содержимое.
=== РЕДАКТИРОВАТЬ 2 === Я поставил точку останова на строке 180 o.s.b.a.ServerProperties благодаря предложению @chimmi, и он показывает, что все свойства установлены, но почему-то сервер не соблюдает настройки...: (
=== РЕДАКТИРОВАТЬ 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();
}
}
Конфигурация:
@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
}
}
Если вы используете не встроенный Tomcat, вы должны добавить его на свой сервер. xml:
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,application/javascript"
Возможно, проблема связана с конфигурацией YAML.
Если вы используете "Стартеры SnakeYAML будут автоматически предоставляться через spring-boot-starter
. Если вы этого не сделаете - вы должны использовать соглашение свойств в application.properties.
Использование YAML вместо свойств
EDIT: Попробуйте это в вашем файле yml:
server:
compression:
enabled: true
mime-types: text/html,text/xml,text/plain,text/css,application/javascript,application/json
min-response-size: 1024
Вы пытались использовать разные браузеры? Это может быть из-за антивируса, который распаковывает файл, как указано в сообщении SO post Spring, для некоторых пользовательских агентов не работает сжатие HTTP-ответов
Никогда не было большой удачи с Spring загрузочным сжатием. Простым решением может быть использование сторонней библиотеки, такой как 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();
}