From c0264072ab4605f4f52e4f8bb473927347be5a3e Mon Sep 17 00:00:00 2001 From: Sebastien Deleuze Date: Fri, 6 Jul 2018 12:50:47 +0200 Subject: [PATCH] Avoid ServerResponse static imports in WebFlux router DSL Provide functions like ok() in RouterFunctionDsl to avoid ServerResponse static imports. Issue: SPR-17009 --- .../function/server/RouterFunctionDsl.kt | 118 ++++++++++++++++++ .../function/server/RouterFunctionDslTests.kt | 12 +- 2 files changed, 125 insertions(+), 5 deletions(-) diff --git a/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/RouterFunctionDsl.kt b/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/RouterFunctionDsl.kt index 171c9b3d33..61803b8695 100644 --- a/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/RouterFunctionDsl.kt +++ b/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/RouterFunctionDsl.kt @@ -18,8 +18,10 @@ package org.springframework.web.reactive.function.server import org.springframework.core.io.Resource import org.springframework.http.HttpMethod +import org.springframework.http.HttpStatus import org.springframework.http.MediaType import reactor.core.publisher.Mono +import java.net.URI /** * Allow to create easily a `RouterFunction` from a Kotlin router DSL based @@ -421,6 +423,122 @@ open class RouterFunctionDsl(private val init: RouterFunctionDsl.() -> Unit) : ( routes += RouterFunctions.resources(lookupFunction) } + /** + * Create a builder with the status code and headers of the given response. + * @param other the response to copy the status and headers from + * @return the created builder + * @since 5.1 + */ + fun from(other: ServerResponse): ServerResponse.BodyBuilder = + ServerResponse.from(other) + + /** + * Create a builder with the given HTTP status. + * @param status the response status + * @return the created builder + * @since 5.1 + */ + fun status(status: HttpStatus): ServerResponse.BodyBuilder = + ServerResponse.status(status) + + /** + * Create a builder with the given HTTP status. + * @param status the response status + * @return the created builder + * @since 5.1 + */ + fun status(status: Int): ServerResponse.BodyBuilder = + ServerResponse.status(status) + + /** + * Create a builder with the status set to [200 OK][HttpStatus.OK]. + * @return the created builder + * @since 5.1 + */ + fun ok(): ServerResponse.BodyBuilder = + ServerResponse.ok() + + /** + * Create a new builder with a [201 Created][HttpStatus.CREATED] status + * and a location header set to the given URI. + * @param location the location URI + * @return the created builder + * @since 5.1 + */ + fun created(location: URI): ServerResponse.BodyBuilder = + ServerResponse.created(location) + + /** + * Create a builder with an [202 Accepted][HttpStatus.ACCEPTED] status. + * @return the created builder + * @since 5.1 + */ + fun accepted(): ServerResponse.BodyBuilder = + ServerResponse.accepted() + + /** + * Create a builder with a [204 No Content][HttpStatus.NO_CONTENT] status. + * @return the created builder + * @since 5.1 + */ + fun noContent(): ServerResponse.HeadersBuilder<*> = + ServerResponse.noContent() + + /** + * Create a builder with a [303 See Other][HttpStatus.SEE_OTHER] + * status and a location header set to the given URI. + * @param location the location URI + * @return the created builder + * @since 5.1 + */ + fun seeOther(location: URI): ServerResponse.BodyBuilder = + ServerResponse.seeOther(location) + + /** + * Create a builder with a [307 Temporary Redirect][HttpStatus.TEMPORARY_REDIRECT] + * status and a location header set to the given URI. + * @param location the location URI + * @return the created builder + * @since 5.1 + */ + fun temporaryRedirect(location: URI): ServerResponse.BodyBuilder = + ServerResponse.temporaryRedirect(location) + + /** + * Create a builder with a [308 Permanent Redirect][HttpStatus.PERMANENT_REDIRECT] + * status and a location header set to the given URI. + * @param location the location URI + * @return the created builder + * @since 5.1 + */ + fun permanentRedirect(location: URI): ServerResponse.BodyBuilder = + ServerResponse.permanentRedirect(location) + + /** + * Create a builder with a [400 Bad Request][HttpStatus.BAD_REQUEST] status. + * @return the created builder + * @since 5.1 + */ + fun badRequest(): ServerResponse.BodyBuilder = + ServerResponse.badRequest() + + /** + * Create a builder with a [404 Not Found][HttpStatus.NOT_FOUND] status. + * @return the created builder + * @since 5.1 + */ + fun notFound(): ServerResponse.HeadersBuilder<*> = + ServerResponse.notFound() + + /** + * Create a builder with an + * [422 Unprocessable Entity][HttpStatus.UNPROCESSABLE_ENTITY] status. + * @return the created builder + * @since 5.1 + */ + fun unprocessableEntity(): ServerResponse.BodyBuilder = + ServerResponse.unprocessableEntity() + /** * Return a composed routing function created from all the registered routes. * @since 5.1 diff --git a/spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/RouterFunctionDslTests.kt b/spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/RouterFunctionDslTests.kt index d9a9842659..2eceb5b59f 100644 --- a/spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/RouterFunctionDslTests.kt +++ b/spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/RouterFunctionDslTests.kt @@ -22,7 +22,6 @@ import org.springframework.http.HttpHeaders.* import org.springframework.http.HttpMethod.* import org.springframework.http.MediaType.* import org.springframework.web.reactive.function.server.MockServerRequest.builder -import org.springframework.web.reactive.function.server.ServerResponse.ok import reactor.core.publisher.Mono import reactor.test.StepVerifier import java.net.URI @@ -114,17 +113,20 @@ class RouterFunctionDslTests { } - fun sampleRouter() = router { + private fun sampleRouter() = router { (GET("/foo/") or GET("/foos/")) { req -> handle(req) } "/api".nest { POST("/foo/", ::handleFromClass) PUT("/foo/", :: handleFromClass) + PATCH("/foo/") { + ok().build() + } "/foo/" { handleFromClass(it) } } accept(APPLICATION_ATOM_XML, ::handle) contentType(APPLICATION_OCTET_STREAM, ::handle) method(PATCH, ::handle) - headers({ it.accept().contains(APPLICATION_JSON) }).nest { + headers { it.accept().contains(APPLICATION_JSON) }.nest { GET("/api/foo/", ::handle) } headers({ it.header("bar").isNotEmpty() }, ::handle) @@ -143,7 +145,7 @@ class RouterFunctionDslTests { } @Suppress("UNUSED_PARAMETER") -fun handleFromClass(req: ServerRequest) = ok().build() +fun handleFromClass(req: ServerRequest) = ServerResponse.ok().build() @Suppress("UNUSED_PARAMETER") -fun handle(req: ServerRequest) = ok().build() +fun handle(req: ServerRequest) = ServerResponse.ok().build()