mirror of
https://gitee.com/dcren/initializr.git
synced 2025-05-03 12:18:04 +08:00
Improve resources caching
Update controllers to add an ETag information so that meta-data is cached on the client. Also enables the compression for json, css and html resources. Closes gh-165
This commit is contained in:
parent
89330da312
commit
5fb8c84e5e
@ -6,6 +6,12 @@ info:
|
||||
spring-boot:
|
||||
version: 1.3.0.RELEASE
|
||||
|
||||
server:
|
||||
compression:
|
||||
enabled: true
|
||||
mime-types: application/json,text/css,text/html
|
||||
min-response-size: 2048
|
||||
|
||||
initializr:
|
||||
env:
|
||||
boms:
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
package io.spring.initializr.web
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import groovy.util.logging.Slf4j
|
||||
import io.spring.initializr.generator.CommandLineHelpGenerator
|
||||
import io.spring.initializr.mapper.InitializrMetadataJsonMapper
|
||||
@ -27,11 +30,13 @@ import io.spring.initializr.generator.ProjectRequest
|
||||
import io.spring.initializr.metadata.InitializrMetadata
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.http.CacheControl
|
||||
import org.springframework.http.HttpHeaders
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.stereotype.Controller
|
||||
import org.springframework.util.DigestUtils
|
||||
import org.springframework.web.bind.annotation.ModelAttribute
|
||||
import org.springframework.web.bind.annotation.RequestHeader
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
@ -86,16 +91,20 @@ class MainController extends AbstractInitializrController {
|
||||
def builder = ResponseEntity.ok().contentType(MediaType.TEXT_PLAIN)
|
||||
if (userAgent) {
|
||||
if (userAgent.startsWith(WebConfig.CURL_USER_AGENT_PREFIX)) {
|
||||
return builder.body(commandLineHelpGenerator.generateCurlCapabilities(metadata, appUrl))
|
||||
def content = commandLineHelpGenerator.generateCurlCapabilities(metadata, appUrl)
|
||||
return builder.eTag(createUniqueId(content)).body(content)
|
||||
}
|
||||
if (userAgent.startsWith(WebConfig.HTTPIE_USER_AGENT_PREFIX)) {
|
||||
return builder.body(commandLineHelpGenerator.generateHttpieCapabilities(metadata, appUrl))
|
||||
def content = commandLineHelpGenerator.generateHttpieCapabilities(metadata, appUrl)
|
||||
return builder.eTag(createUniqueId(content)).body(content)
|
||||
}
|
||||
if (userAgent.startsWith(WebConfig.SPRING_BOOT_CLI_AGENT_PREFIX)) {
|
||||
return builder.body(commandLineHelpGenerator.generateSpringBootCliCapabilities(metadata, appUrl))
|
||||
def content = commandLineHelpGenerator.generateSpringBootCliCapabilities(metadata, appUrl)
|
||||
return builder.eTag(createUniqueId(content)).body(content)
|
||||
}
|
||||
}
|
||||
builder.body(commandLineHelpGenerator.generateGenericCapabilities(metadata, appUrl))
|
||||
def content = commandLineHelpGenerator.generateGenericCapabilities(metadata, appUrl)
|
||||
builder.eTag(createUniqueId(content)).body(content)
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/", produces = ["application/hal+json"])
|
||||
@ -120,7 +129,8 @@ class MainController extends AbstractInitializrController {
|
||||
private ResponseEntity<String> serviceCapabilitiesFor(InitializrMetadataVersion version, MediaType contentType) {
|
||||
String appUrl = generateAppUrl()
|
||||
def content = getJsonMapper(version).write(metadataProvider.get(), appUrl)
|
||||
return ResponseEntity.ok().contentType(contentType).body(content)
|
||||
return ResponseEntity.ok().contentType(contentType).eTag(createUniqueId(content))
|
||||
.cacheControl(CacheControl.maxAge(7, TimeUnit.DAYS)).body(content)
|
||||
}
|
||||
|
||||
private static InitializrMetadataJsonMapper getJsonMapper(InitializrMetadataVersion version) {
|
||||
@ -220,4 +230,10 @@ class MainController extends AbstractInitializrController {
|
||||
result
|
||||
}
|
||||
|
||||
private String createUniqueId(String content) {
|
||||
StringBuilder builder = new StringBuilder()
|
||||
DigestUtils.appendMd5DigestAsHex(content.getBytes(StandardCharsets.UTF_8), builder)
|
||||
builder.toString()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package io.spring.initializr.web
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
import groovy.json.JsonBuilder
|
||||
import io.spring.initializr.metadata.Dependency
|
||||
import io.spring.initializr.metadata.InitializrMetadataProvider
|
||||
@ -23,6 +25,9 @@ import io.spring.initializr.util.Version
|
||||
import io.spring.initializr.util.VersionRange
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.util.DigestUtils
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RequestParam
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
@ -40,7 +45,7 @@ class UiController {
|
||||
protected InitializrMetadataProvider metadataProvider
|
||||
|
||||
@RequestMapping(value = "/ui/dependencies", produces = ["application/json"])
|
||||
String dependencies(@RequestParam(required = false) String version) {
|
||||
ResponseEntity<String> dependencies(@RequestParam(required = false) String version) {
|
||||
def dependencyGroups = metadataProvider.get().dependencies.content
|
||||
def content = []
|
||||
Version v = version ? Version.parse(version) : null
|
||||
@ -55,7 +60,9 @@ class UiController {
|
||||
}
|
||||
}
|
||||
}
|
||||
writeDependencies(content)
|
||||
def json = writeDependencies(content)
|
||||
ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).
|
||||
eTag(createUniqueId(json)).body(json)
|
||||
}
|
||||
|
||||
private static String writeDependencies(List<DependencyItem> items) {
|
||||
@ -96,4 +103,10 @@ class UiController {
|
||||
}
|
||||
}
|
||||
|
||||
private String createUniqueId(String content) {
|
||||
StringBuilder builder = new StringBuilder()
|
||||
DigestUtils.appendMd5DigestAsHex(content.getBytes(StandardCharsets.UTF_8), builder)
|
||||
builder.toString()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.skyscreamer.jsonassert.JSONCompareMode
|
||||
|
||||
import org.springframework.http.HttpHeaders
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.ResponseEntity
|
||||
@ -32,6 +33,7 @@ import org.springframework.web.client.HttpClientErrorException
|
||||
|
||||
import static org.hamcrest.CoreMatchers.allOf
|
||||
import static org.hamcrest.CoreMatchers.containsString
|
||||
import static org.hamcrest.CoreMatchers.nullValue
|
||||
import static org.hamcrest.core.IsNot.not
|
||||
import static org.junit.Assert.assertEquals
|
||||
import static org.junit.Assert.assertFalse
|
||||
@ -169,6 +171,7 @@ class MainControllerIntegrationTests extends AbstractInitializrControllerIntegra
|
||||
@Test
|
||||
void metadataWithCurrentAcceptHeader() {
|
||||
ResponseEntity<String> response = invokeHome(null, 'application/vnd.initializr.v2.1+json')
|
||||
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()))
|
||||
validateContentType(response, CURRENT_METADATA_MEDIA_TYPE)
|
||||
validateCurrentMetadata(new JSONObject(response.body))
|
||||
}
|
||||
@ -184,6 +187,7 @@ class MainControllerIntegrationTests extends AbstractInitializrControllerIntegra
|
||||
@Test
|
||||
void metadataWithHalAcceptHeader() {
|
||||
ResponseEntity<String> response = invokeHome(null, 'application/hal+json')
|
||||
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()))
|
||||
validateContentType(response, MainController.HAL_JSON_CONTENT_TYPE)
|
||||
validateCurrentMetadata(new JSONObject(response.body))
|
||||
}
|
||||
@ -283,6 +287,7 @@ class MainControllerIntegrationTests extends AbstractInitializrControllerIntegra
|
||||
|
||||
private void validateCurlHelpContent(ResponseEntity<String> response) {
|
||||
validateContentType(response, MediaType.TEXT_PLAIN)
|
||||
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()))
|
||||
assertThat(response.body, allOf(
|
||||
containsString("Spring Initializr"),
|
||||
containsString('Examples:'),
|
||||
@ -291,6 +296,7 @@ class MainControllerIntegrationTests extends AbstractInitializrControllerIntegra
|
||||
|
||||
private void validateHttpIeHelpContent(ResponseEntity<String> response) {
|
||||
validateContentType(response, MediaType.TEXT_PLAIN)
|
||||
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()))
|
||||
assertThat(response.body, allOf(
|
||||
containsString("Spring Initializr"),
|
||||
containsString('Examples:'),
|
||||
@ -300,6 +306,7 @@ class MainControllerIntegrationTests extends AbstractInitializrControllerIntegra
|
||||
|
||||
private void validateGenericHelpContent(ResponseEntity<String> response) {
|
||||
validateContentType(response, MediaType.TEXT_PLAIN)
|
||||
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()))
|
||||
assertThat(response.body, allOf(
|
||||
containsString("Spring Initializr"),
|
||||
not(containsString('Examples:')),
|
||||
@ -308,6 +315,7 @@ class MainControllerIntegrationTests extends AbstractInitializrControllerIntegra
|
||||
|
||||
private void validateSpringBootHelpContent(ResponseEntity<String> response) {
|
||||
validateContentType(response, MediaType.TEXT_PLAIN)
|
||||
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()))
|
||||
assertThat(response.body, allOf(
|
||||
containsString("Service capabilities"),
|
||||
containsString("Supported dependencies"),
|
||||
|
Loading…
Reference in New Issue
Block a user