From 432cdd7802b9d1109eb02925d45782b6c99b9e01 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 15 Aug 2018 20:24:14 +0200 Subject: [PATCH] Add ResponseEntity.of(Optional) variant When dealing with `Optional` values in a Controller handler (for example, values coming from a Spring Data repository), developers might reuse this code snippet quite often: ``` @GetMapping("/user") public ResponseEntity> fetchUser() { Optional user = //... return user.map(ResponseEntity::ok).orElse(notFound().build()); } ``` This commit adds a new static method on `ResponseEntity` for that, simplifying the previous snippet with `return ResponseEntity.of(user);` Note that in case more specific HTTP response headers are required by the application, developers should use other static methods to explicitly tell which headers should be used in each case. Issue: SPR-17187 --- .../springframework/http/ResponseEntity.java | 13 +++++++++++ .../http/ResponseEntityTests.java | 22 ++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/http/ResponseEntity.java b/spring-web/src/main/java/org/springframework/http/ResponseEntity.java index 964f751e42..65c94c3b9b 100644 --- a/spring-web/src/main/java/org/springframework/http/ResponseEntity.java +++ b/spring-web/src/main/java/org/springframework/http/ResponseEntity.java @@ -19,6 +19,7 @@ package org.springframework.http; import java.net.URI; import java.util.Arrays; import java.util.LinkedHashSet; +import java.util.Optional; import java.util.Set; import org.springframework.lang.Nullable; @@ -213,6 +214,18 @@ public class ResponseEntity extends HttpEntity { return new DefaultBuilder(status); } + /** + * A shortcut for creating a {@code ResponseEntity} with the given body + * and the {@linkplain HttpStatus#OK OK} status, or an empty body and a + * {@linkplain HttpStatus#NOT_FOUND NOT FOUND} status in case of a + * {@linkplain Optional#empty()} parameter. + * @return the created {@code ResponseEntity} + * @since 5.1 + */ + public static ResponseEntity of(Optional body) { + return body.map(ResponseEntity::ok).orElse(notFound().build()); + } + /** * Create a builder with the status set to {@linkplain HttpStatus#OK OK}. * @return the created builder diff --git a/spring-web/src/test/java/org/springframework/http/ResponseEntityTests.java b/spring-web/src/test/java/org/springframework/http/ResponseEntityTests.java index 07ef76f89b..ec3414638f 100644 --- a/spring-web/src/test/java/org/springframework/http/ResponseEntityTests.java +++ b/spring-web/src/test/java/org/springframework/http/ResponseEntityTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ package org.springframework.http; import java.net.URI; import java.net.URISyntaxException; import java.util.List; +import java.util.Optional; import java.util.concurrent.TimeUnit; import org.hamcrest.Matchers; @@ -72,6 +73,25 @@ public class ResponseEntityTests { assertEquals(entity, responseEntity.getBody()); } + @Test + public void ofOptional() { + Integer entity = 42; + ResponseEntity responseEntity = ResponseEntity.of(Optional.of(entity)); + + assertNotNull(responseEntity); + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + assertEquals(entity, responseEntity.getBody()); + } + + @Test + public void ofEmptyOptional() { + ResponseEntity responseEntity = ResponseEntity.of(Optional.empty()); + + assertNotNull(responseEntity); + assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode()); + assertNull(responseEntity.getBody()); + } + @Test public void createdLocation() throws URISyntaxException { URI location = new URI("location");