Skip to content

Commit c77801e

Browse files
authored
Merge pull request eugenp#1111 from mogronalol/BAEL-542
Bael 542
2 parents b57cf0c + 3f81460 commit c77801e

8 files changed

Lines changed: 255 additions & 0 deletions

File tree

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
<module>spring-rest-docs</module>
148148
<module>spring-rest</module>
149149
<module>spring-security-basic-auth</module>
150+
<module>spring-security-cache-control</module>
150151
<module>spring-security-client/spring-security-jsp-authentication</module>
151152
<module>spring-security-client/spring-security-jsp-authorize</module>
152153
<module>spring-security-client/spring-security-jsp-config</module>
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.baeldung</groupId>
8+
<artifactId>spring-security-cache-control</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<parent>
12+
<groupId>org.springframework.boot</groupId>
13+
<artifactId>spring-boot-starter-parent</artifactId>
14+
<version>1.4.3.RELEASE</version>
15+
</parent>
16+
17+
<dependencies>
18+
<dependency>
19+
<groupId>org.springframework.boot</groupId>
20+
<artifactId>spring-boot-starter-actuator</artifactId>
21+
</dependency>
22+
<dependency>
23+
<groupId>org.springframework.boot</groupId>
24+
<artifactId>spring-boot-starter-web</artifactId>
25+
</dependency>
26+
<dependency>
27+
<groupId>org.springframework.security</groupId>
28+
<artifactId>spring-security-core</artifactId>
29+
</dependency>
30+
<dependency>
31+
<groupId>org.springframework.security</groupId>
32+
<artifactId>spring-security-config</artifactId>
33+
</dependency>
34+
<dependency>
35+
<groupId>org.springframework.security</groupId>
36+
<artifactId>spring-security-web</artifactId>
37+
</dependency>
38+
<dependency>
39+
<groupId>org.springframework.boot</groupId>
40+
<artifactId>spring-boot-starter-test</artifactId>
41+
</dependency>
42+
<dependency>
43+
<groupId>javax.servlet</groupId>
44+
<artifactId>javax.servlet-api</artifactId>
45+
<version>${javax.servlet-api.version}</version>
46+
</dependency>
47+
48+
<dependency>
49+
<groupId>junit</groupId>
50+
<artifactId>junit</artifactId>
51+
<scope>test</scope>
52+
</dependency>
53+
54+
<dependency>
55+
<groupId>org.hamcrest</groupId>
56+
<artifactId>hamcrest-core</artifactId>
57+
<scope>test</scope>
58+
</dependency>
59+
<dependency>
60+
<groupId>org.hamcrest</groupId>
61+
<artifactId>hamcrest-library</artifactId>
62+
<scope>test</scope>
63+
</dependency>
64+
65+
<dependency>
66+
<groupId>org.mockito</groupId>
67+
<artifactId>mockito-core</artifactId>
68+
<scope>test</scope>
69+
</dependency>
70+
71+
<dependency>
72+
<groupId>org.springframework</groupId>
73+
<artifactId>spring-test</artifactId>
74+
</dependency>
75+
76+
<dependency>
77+
<groupId>com.jayway.restassured</groupId>
78+
<artifactId>rest-assured</artifactId>
79+
<version>${rest-assured.version}</version>
80+
</dependency>
81+
</dependencies>
82+
83+
<properties>
84+
<javax.servlet-api.version>3.1.0</javax.servlet-api.version>
85+
<rest-assured.version>2.9.0</rest-assured.version>
86+
</properties>
87+
88+
</project>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.baeldung.cachecontrol;
2+
3+
4+
import org.springframework.boot.SpringApplication;
5+
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
7+
@SpringBootApplication
8+
public class AppRunner {
9+
public static void main(String[] args) {
10+
SpringApplication.run(AppRunner.class, args);
11+
}
12+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.baeldung.cachecontrol;
2+
3+
4+
import com.baeldung.cachecontrol.model.TimestampDto;
5+
import com.baeldung.cachecontrol.model.UserDto;
6+
import org.springframework.http.CacheControl;
7+
import org.springframework.http.ResponseEntity;
8+
import org.springframework.stereotype.Controller;
9+
import org.springframework.web.bind.annotation.PathVariable;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RequestMethod;
12+
13+
import java.time.LocalDateTime;
14+
import java.time.ZoneOffset;
15+
import java.util.concurrent.TimeUnit;
16+
17+
@Controller
18+
public class ResourceEndpoint {
19+
20+
@RequestMapping(value = "/default/users/{name}", method = RequestMethod.GET)
21+
public ResponseEntity<UserDto> getUserWithDefaultCaching(@PathVariable(value = "name") String name) {
22+
return ResponseEntity.ok(new UserDto(name));
23+
}
24+
25+
@RequestMapping(value = "/users/{name}", method = RequestMethod.GET)
26+
public ResponseEntity<UserDto> getUser(@PathVariable(value = "name") String name) {
27+
return ResponseEntity.ok()
28+
.cacheControl(CacheControl.maxAge(60, TimeUnit.SECONDS))
29+
.body(new UserDto(name));
30+
}
31+
32+
@RequestMapping(value = "/timestamp", method = RequestMethod.GET)
33+
public ResponseEntity<TimestampDto> getServerTimestamp() {
34+
return ResponseEntity.ok()
35+
.cacheControl(CacheControl.noStore())
36+
.body(new TimestampDto(LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli()));
37+
}
38+
39+
@RequestMapping(value = "/private/users/{name}", method = RequestMethod.GET)
40+
public ResponseEntity<UserDto> getUserNotCached(@PathVariable("name") String name) {
41+
return ResponseEntity.ok()
42+
.body(new UserDto(name));
43+
}
44+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.baeldung.cachecontrol.config;
2+
3+
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
6+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
7+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
8+
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
9+
10+
@Configuration
11+
@EnableWebSecurity
12+
@EnableGlobalMethodSecurity(prePostEnabled = true)
13+
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
14+
15+
@Override
16+
protected void configure(HttpSecurity http) throws Exception {}
17+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.baeldung.cachecontrol.model;
2+
3+
4+
public class TimestampDto {
5+
public final Long timestamp;
6+
7+
public TimestampDto(Long timestamp) {
8+
this.timestamp = timestamp;
9+
}
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.baeldung.cachecontrol.model;
2+
3+
4+
public class UserDto {
5+
public final String name;
6+
7+
public UserDto(String name) {
8+
this.name = name;
9+
}
10+
11+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.baeldung.cachecontrol;
2+
3+
import com.jayway.restassured.http.ContentType;
4+
import org.junit.Test;
5+
import org.junit.runner.RunWith;
6+
import org.springframework.boot.context.embedded.LocalServerPort;
7+
import org.springframework.boot.test.context.SpringBootTest;
8+
import org.springframework.test.context.junit4.SpringRunner;
9+
10+
import static com.jayway.restassured.RestAssured.given;
11+
12+
@RunWith(SpringRunner.class)
13+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = AppRunner.class)
14+
public class ResourceEndpointLiveTest {
15+
16+
@LocalServerPort
17+
private int serverPort;
18+
19+
@Test
20+
public void whenGetRequestForUser_shouldRespondWithDefaultCacheHeaders() {
21+
given()
22+
.when()
23+
.get(getBaseUrl() + "/default/users/Michael")
24+
.then()
25+
.headers("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate")
26+
.header("Pragma", "no-cache");
27+
}
28+
29+
@Test
30+
public void whenGetRequestForUser_shouldRespondMaxAgeCacheControl() {
31+
given()
32+
.when()
33+
.get(getBaseUrl() + "/users/Michael")
34+
.then()
35+
.header("Cache-Control", "max-age=60");
36+
}
37+
38+
@Test
39+
public void givenServiceEndpoint_whenGetRequestForUser_shouldResponseWithCacheControlMaxAge() {
40+
given()
41+
.when()
42+
.get(getBaseUrl() + "/users/Michael")
43+
.then()
44+
.contentType(ContentType.JSON).and().statusCode(200).and()
45+
.header("Cache-Control", "max-age=60");
46+
}
47+
48+
@Test
49+
public void givenServiceEndpoint_whenGetRequestForNotCacheableContent_shouldResponseWithCacheControlNoCache() {
50+
given()
51+
.when()
52+
.get(getBaseUrl() + "/timestamp")
53+
.then()
54+
.contentType(ContentType.JSON).and().statusCode(200).and()
55+
.header("Cache-Control", "no-store");
56+
}
57+
58+
@Test
59+
public void givenServiceEndpoint_whenGetRequestForPrivateUser_shouldResponseWithSecurityDefaultCacheControl() {
60+
given()
61+
.when()
62+
.get(getBaseUrl() + "/private/users/Michael")
63+
.then()
64+
.contentType(ContentType.JSON).and().statusCode(200).and()
65+
.header("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate");
66+
}
67+
68+
private String getBaseUrl() {
69+
return "http://localhost:" + serverPort;
70+
}
71+
72+
}

0 commit comments

Comments
 (0)