11.23 Spring Boot Etag介紹及實現

  • 簡介

這篇文章將介紹Spring Boot Etag報文頭的示例。Etag主要用來減少瀏覽器對於相同內容進行反覆請求而帶來的不必要的網絡帶寬。

下面讓我們來了解下Etag是如何工作的:

在第一次請求的時候,服務端將對返回報文內容進行哈希,並將哈希值作為Etag的值放入返回報文的頭部一起返回給請求客戶端。

當瀏覽器再次發起同樣請求的時候,並在請求報文的頭部放入if-Non-match以及之前返回的Etag值的報文。當服務端接收到請求後,會根據報文頭中的if-Non-match和Etag值來判斷返回的內容是否一致,如果一致的話服務端就會返回304代碼,當瀏覽器接收到304返回代碼後就明白返回的內容和上次沒有任何改變,可以直接從瀏覽器的緩存中直接獲取即可。

簡而言之,如果同一個請求再次從同一個瀏覽器發送到服務端並且返回的結果相同,那麼服務端將發送304代碼,這樣瀏覽器就不會再從服務器重複獲取完整的響應而是使用以前的緩存數據。如果返回結果和以前的不同,那麼服務端將發送一個狀態代碼為200的新返回結果,因此瀏覽器將緩存新響應,這在功能中很有用。
Etag雖然不能提高服務器的性能,但它會降低網站的帶寬和網絡流量消耗。

  • 示例

利用Spring boot的ShallowEtagHeaderFilter我們可以實現Etag功。下面是一個完整的示例:

1.pom.xml


<project> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0/<modelversion>
<groupid>spring-boot-example/<groupid>
<artifactid>spring-etag-header-example/<artifactid>
<version>1.0-SNAPSHOT/<version>
<description>spring boot ETag header example/<description>

<parent>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-parent/<artifactid>
<version>1.5.4.RELEASE/<version>
/<parent>
<properties>
<maven.compiler.source>1.8/<maven.compiler.source>
<maven.compiler.target>1.8/<maven.compiler.target>
/<properties>
<dependencies>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-web/<artifactid>
/<dependency>
/<dependencies>

<build>
<plugins>
<plugin>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-maven-plugin/<artifactid>
/<plugin>
/<plugins>
/<build>
/<project>

2.SpringBootConfig

下面我們創建一個ShallowEtagHeaderFilter來將Etag值放入返回報文的頭部。

package com.javadeveloperzone;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.filter.ShallowEtagHeaderFilter;
import javax.servlet.Filter;
/**
* Created by JavaDeveloperZone on 19-07-2017.
*/
@SpringBootApplication
@ComponentScan // Using a root package also allows the @ComponentScan annotation to be used without needing to specify a basePackage attribute
public class SpringBootConfig {
public static void main(String[] args) throws Exception {
SpringApplication.run(SpringBootConfig.class, args); // it wil start application
}
@Bean
public Filter filter(){
ShallowEtagHeaderFilter filter=new ShallowEtagHeaderFilter();
return filter;
}
}

3.ETagController

package com.javadeveloperzone.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by JavaDeveloperZone on 19-07-2017.
*/
@RestController
public class ETagController {
@RequestMapping("/hello")
public String hello() {
return "Hello etag Header";
}
}

4.輸出:

第一次請求:正如我們前面所介紹的那樣,第一次請求的響應代碼將是200,響應頭包含ETag,ETag是響應報文的hashcode,它將由spring boot管理自動寫入響應頭部。


Spring Boot Etag介紹及實現

第二次請求:在第二次請求中,有相同的響應,因此服務器將發送304(未修改)狀態代碼,以便瀏覽器不會下載內容,而是使用本地瀏覽器緩存中的內容。

Spring Boot Etag介紹及實現

Spring Boot Etag介紹及實現

Spring Boot Etag介紹及實現

Spring Boot Etag介紹及實現


分享到:


相關文章: