Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ class ExceptionController {

// tag::narrow[]
@ExceptionHandler(FileSystemException::class, RemoteException::class)
fun handleIoException(ex: IOException): ResponseEntity<String> {
fun handleIoException(ex: IOException): ResponseEntity<String?> {
return ResponseEntity.internalServerError().body(ex.message)
}
// end::narrow[]


// tag::general[]
@ExceptionHandler(FileSystemException::class, RemoteException::class)
fun handleExceptions(ex: Exception): ResponseEntity<String> {
fun handleExceptions(ex: Exception): ResponseEntity<String?> {
return ResponseEntity.internalServerError().body(ex.message)
}
// end::general[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
* @see #getBody()
* @see #getHeaders()
*/
public class HttpEntity<T> {
public class HttpEntity<T extends @Nullable Object> {

/**
* An {@code HttpEntity} instance with a {@code null} body and
Expand All @@ -67,12 +67,13 @@ public class HttpEntity<T> {

private final HttpHeaders headers;

private final @Nullable T body;
private final T body;


/**
* Create a new, empty {@code HttpEntity}.
*/
@SuppressWarnings("NullAway")
protected HttpEntity() {
this(null, (HttpHeaders) null);
}
Expand All @@ -90,6 +91,7 @@ public HttpEntity(T body) {
* @param headers the entity headers
* @since 7.0
*/
@SuppressWarnings("NullAway")
public HttpEntity(HttpHeaders headers) {
this(null, headers);
}
Expand All @@ -100,7 +102,7 @@ public HttpEntity(HttpHeaders headers) {
* @param headers the entity headers
* @since 7.0
*/
public HttpEntity(@Nullable T body, @Nullable HttpHeaders headers) {
public HttpEntity(T body, @Nullable HttpHeaders headers) {
this.body = body;
this.headers = (headers != null) ? headers : new HttpHeaders();
}
Expand All @@ -110,6 +112,7 @@ public HttpEntity(@Nullable T body, @Nullable HttpHeaders headers) {
* @param headers the entity headers
* @deprecated in favor of {@link #HttpEntity(HttpHeaders)}
*/
@SuppressWarnings("NullAway")
@Deprecated(since = "7.0", forRemoval = true)
public HttpEntity(MultiValueMap<String, String> headers) {
this(null, headers);
Expand All @@ -122,7 +125,7 @@ public HttpEntity(MultiValueMap<String, String> headers) {
* @deprecated in favor of {@link #HttpEntity(Object, HttpHeaders)}
*/
@Deprecated(since = "7.0", forRemoval = true)
public HttpEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers) {
public HttpEntity(T body, @Nullable MultiValueMap<String, String> headers) {
this(body, (headers != null) ? new HttpHeaders(headers) : new HttpHeaders());
}

Expand All @@ -137,7 +140,7 @@ public HttpHeaders getHeaders() {
/**
* Returns the body of this entity.
*/
public @Nullable T getBody() {
public T getBody() {
return this.body;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
* @see org.springframework.web.client.RestOperations#exchange(RequestEntity, Class)
* @see ResponseEntity
*/
public class RequestEntity<T> extends HttpEntity<T> {
public class RequestEntity<T extends @Nullable Object> extends HttpEntity<T> {

private final @Nullable HttpMethod method;

Expand All @@ -78,6 +78,7 @@ public class RequestEntity<T> extends HttpEntity<T> {
* @param method the method
* @param url the URL
*/
@SuppressWarnings("NullAway")
public RequestEntity(HttpMethod method, URI url) {
this(null, (HttpHeaders) null, method, url, null);
}
Expand All @@ -88,7 +89,7 @@ public RequestEntity(HttpMethod method, URI url) {
* @param method the method
* @param url the URL
*/
public RequestEntity(@Nullable T body, HttpMethod method, URI url) {
public RequestEntity(T body, HttpMethod method, URI url) {
this(body, (HttpHeaders) null, method, url, null);
}

Expand All @@ -100,7 +101,7 @@ public RequestEntity(@Nullable T body, HttpMethod method, URI url) {
* @param type the type used for generic type resolution
* @since 4.3
*/
public RequestEntity(@Nullable T body, HttpMethod method, URI url, Type type) {
public RequestEntity(T body, HttpMethod method, URI url, Type type) {
this(body, (HttpHeaders) null, method, url, type);
}

Expand All @@ -111,6 +112,7 @@ public RequestEntity(@Nullable T body, HttpMethod method, URI url, Type type) {
* @param url the URL
* @since 7.0
*/
@SuppressWarnings("NullAway")
public RequestEntity(HttpHeaders headers, HttpMethod method, URI url) {
this(null, headers, method, url, null);
}
Expand All @@ -123,7 +125,7 @@ public RequestEntity(HttpHeaders headers, HttpMethod method, URI url) {
* @param url the URL
* @since 7.0
*/
public RequestEntity(@Nullable T body, @Nullable HttpHeaders headers,
public RequestEntity(T body, @Nullable HttpHeaders headers,
@Nullable HttpMethod method, URI url) {

this(body, headers, method, url, null);
Expand All @@ -138,7 +140,7 @@ public RequestEntity(@Nullable T body, @Nullable HttpHeaders headers,
* @param type the type used for generic type resolution
* @since 7.0
*/
public RequestEntity(@Nullable T body, @Nullable HttpHeaders headers,
public RequestEntity(T body, @Nullable HttpHeaders headers,
@Nullable HttpMethod method, @Nullable URI url, @Nullable Type type) {

super(body, headers);
Expand All @@ -154,6 +156,7 @@ public RequestEntity(@Nullable T body, @Nullable HttpHeaders headers,
* @param url the URL
* @deprecated in favor of {@link #RequestEntity(HttpHeaders, HttpMethod, URI)}
*/
@SuppressWarnings("NullAway")
@Deprecated(since = "7.0", forRemoval = true)
public RequestEntity(MultiValueMap<String, String> headers, HttpMethod method, URI url) {
this(null, headers, method, url, null);
Expand All @@ -169,7 +172,7 @@ public RequestEntity(MultiValueMap<String, String> headers, HttpMethod method, U
*/
@Deprecated(since = "7.0", forRemoval = true)
public RequestEntity(
@Nullable T body, @Nullable MultiValueMap<String, String> headers,
T body, @Nullable MultiValueMap<String, String> headers,
@Nullable HttpMethod method, URI url) {

this(body, headers, method, url, null);
Expand All @@ -187,7 +190,7 @@ public RequestEntity(
*/
@SuppressWarnings("removal")
@Deprecated(since = "7.0", forRemoval = true)
public RequestEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers,
public RequestEntity(T body, @Nullable MultiValueMap<String, String> headers,
@Nullable HttpMethod method, @Nullable URI url, @Nullable Type type) {

super(body, headers);
Expand Down Expand Up @@ -546,7 +549,7 @@ public interface HeadersBuilder<B extends HeadersBuilder<B>> {
* @return the request entity
* @see BodyBuilder#body(Object)
*/
RequestEntity<Void> build();
RequestEntity<@Nullable Void> build();
}


Expand Down Expand Up @@ -702,7 +705,7 @@ public BodyBuilder ifNoneMatch(String... ifNoneMatches) {
}

@Override
public RequestEntity<Void> build() {
public RequestEntity<@Nullable Void> build() {
return buildInternal(null, null);
}

Expand All @@ -716,7 +719,7 @@ public <T> RequestEntity<T> body(T body, Type type) {
return buildInternal(body, type);
}

private <T> RequestEntity<T> buildInternal(@Nullable T body, @Nullable Type type) {
private <T extends @Nullable Object> RequestEntity<T> buildInternal(T body, @Nullable Type type) {
if (this.uri != null) {
return new RequestEntity<>(body, this.headers, this.method, this.uri, type);
}
Expand All @@ -736,7 +739,7 @@ else if (this.uriTemplate != null){
* @since 5.3
* @param <T> the body type
*/
public static class UriTemplateRequestEntity<T> extends RequestEntity<T> {
public static class UriTemplateRequestEntity<T extends @Nullable Object> extends RequestEntity<T> {

private final String uriTemplate;

Expand All @@ -745,7 +748,7 @@ public static class UriTemplateRequestEntity<T> extends RequestEntity<T> {
private final @Nullable Map<String, ? extends @Nullable Object> uriVarsMap;

UriTemplateRequestEntity(
@Nullable T body, @Nullable HttpHeaders headers,
T body, @Nullable HttpHeaders headers,
@Nullable HttpMethod method, @Nullable Type type, String uriTemplate,
@Nullable Object @Nullable [] uriVarsArray, @Nullable Map<String, ?> uriVarsMap) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
* @see org.springframework.web.client.RestOperations#getForEntity(URI, Class)
* @see RequestEntity
*/
public class ResponseEntity<T> extends HttpEntity<T> {
public class ResponseEntity<T extends @Nullable Object> extends HttpEntity<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check how ResponseEntity of "empty value" translates in a sample application checked with NullAway, using https://github.com/sdeleuze/jspecify-nullaway-demo as a basis maybe?

I guess that would be ResponseEntity<@Nullable Void> based on jspecify/jspecify#51 but worth to check.


private final HttpStatusCode status;

Expand All @@ -87,6 +87,7 @@ public class ResponseEntity<T> extends HttpEntity<T> {
* Create a {@code ResponseEntity} with a status code only.
* @param status the status code
*/
@SuppressWarnings("NullAway")
public ResponseEntity(HttpStatusCode status) {
this(null, (HttpHeaders) null, status);
}
Expand All @@ -96,7 +97,7 @@ public ResponseEntity(HttpStatusCode status) {
* @param body the entity body
* @param status the status code
*/
public ResponseEntity(@Nullable T body, HttpStatusCode status) {
public ResponseEntity(T body, HttpStatusCode status) {
this(body, (HttpHeaders) null, status);
}

Expand All @@ -106,6 +107,7 @@ public ResponseEntity(@Nullable T body, HttpStatusCode status) {
* @param status the status code
* @since 7.0
*/
@SuppressWarnings("NullAway")
public ResponseEntity(HttpHeaders headers, HttpStatusCode status) {
this(null, headers, status);
}
Expand All @@ -117,7 +119,7 @@ public ResponseEntity(HttpHeaders headers, HttpStatusCode status) {
* @param rawStatus the status code value
* @since 7.0
*/
public ResponseEntity(@Nullable T body, @Nullable HttpHeaders headers, int rawStatus) {
public ResponseEntity(T body, @Nullable HttpHeaders headers, int rawStatus) {
this(body, headers, HttpStatusCode.valueOf(rawStatus));
}

Expand All @@ -128,7 +130,7 @@ public ResponseEntity(@Nullable T body, @Nullable HttpHeaders headers, int rawSt
* @param statusCode the status code
* @since 7.0
*/
public ResponseEntity(@Nullable T body, @Nullable HttpHeaders headers, HttpStatusCode statusCode) {
public ResponseEntity(T body, @Nullable HttpHeaders headers, HttpStatusCode statusCode) {
super(body, headers);
Assert.notNull(statusCode, "HttpStatusCode must not be null");

Expand All @@ -141,6 +143,7 @@ public ResponseEntity(@Nullable T body, @Nullable HttpHeaders headers, HttpStatu
* @param status the status code
* @deprecated in favor of {@link #ResponseEntity(HttpHeaders, HttpStatusCode)}
*/
@SuppressWarnings("NullAway")
@Deprecated(since = "7.0", forRemoval = true)
public ResponseEntity(MultiValueMap<String, String> headers, HttpStatusCode status) {
this(null, headers, status);
Expand All @@ -155,7 +158,7 @@ public ResponseEntity(MultiValueMap<String, String> headers, HttpStatusCode stat
* @deprecated in favor of {@link #ResponseEntity(Object, HttpHeaders, int)}
*/
@Deprecated(since = "7.0", forRemoval = true)
public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, int rawStatus) {
public ResponseEntity(T body, @Nullable MultiValueMap<String, String> headers, int rawStatus) {
this(body, headers, HttpStatusCode.valueOf(rawStatus));
}

Expand All @@ -168,7 +171,7 @@ public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String>
*/
@SuppressWarnings("removal")
@Deprecated(since = "7.0", forRemoval = true)
public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, HttpStatusCode statusCode) {
public ResponseEntity(T body, @Nullable MultiValueMap<String, String> headers, HttpStatusCode statusCode) {
super(body, headers);
Assert.notNull(statusCode, "HttpStatusCode must not be null");

Expand Down Expand Up @@ -261,7 +264,7 @@ public static BodyBuilder ok() {
* @return the created {@code ResponseEntity}
* @since 4.1
*/
public static <T> ResponseEntity<T> ok(@Nullable T body) {
public static <T extends @Nullable Object> ResponseEntity<T> ok(T body) {
return ok().body(body);
}

Expand Down Expand Up @@ -294,7 +297,7 @@ public static HeadersBuilder<?> of(ProblemDetail body) {

@SuppressWarnings("unchecked")
@Override
public <T> ResponseEntity<T> build() {
public <T extends @Nullable Object> ResponseEntity<T> build() {
return (ResponseEntity<T>) body(body);
}
};
Expand All @@ -308,7 +311,7 @@ public <T> ResponseEntity<T> build() {
* @return the created {@code ResponseEntity}
* @since 6.0.5
*/
public static <T> ResponseEntity<T> ofNullable(@Nullable T body) {
public static <T extends @Nullable Object> ResponseEntity<T> ofNullable(@Nullable T body) {
if (body == null) {
return notFound().build();
}
Expand Down Expand Up @@ -516,7 +519,7 @@ public interface HeadersBuilder<B extends HeadersBuilder<B>> {
* @return the response entity
* @see BodyBuilder#body(Object)
*/
<T> ResponseEntity<T> build();
<T extends @Nullable Object> ResponseEntity<T> build();
}


Expand Down Expand Up @@ -550,7 +553,7 @@ public interface BodyBuilder extends HeadersBuilder<BodyBuilder> {
* @param body the body of the response entity
* @return the built response entity
*/
<T> ResponseEntity<T> body(@Nullable T body);
<T extends @Nullable Object> ResponseEntity<T> body(T body);
}


Expand Down Expand Up @@ -652,13 +655,14 @@ public BodyBuilder varyBy(String... requestHeaders) {
return this;
}

@SuppressWarnings("NullAway")
@Override
public <T> ResponseEntity<T> build() {
public <T extends @Nullable Object> ResponseEntity<T> build() {
return body(null);
}

@Override
public <T> ResponseEntity<T> body(@Nullable T body) {
public <T extends @Nullable Object> ResponseEntity<T> body(T body) {
return new ResponseEntity<>(body, this.headers, this.statusCode);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ private HttpHeaders initHeadersIfNecessary() {
}

public HttpEntity<?> build() {
return new HttpEntity<>(this.body, this.headers);
return new HttpEntity<@Nullable Object>(this.body, this.headers);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,7 @@ private void logBody(Object body, @Nullable MediaType mediaType, HttpMessageConv
/**
* Response extractor for {@link HttpEntity}.
*/
private class ResponseEntityResponseExtractor<T> implements ResponseExtractor<ResponseEntity<T>> {
private class ResponseEntityResponseExtractor<T> implements ResponseExtractor<ResponseEntity<@Nullable T>> {

private final @Nullable HttpMessageConverterExtractor<T> delegate;

Expand All @@ -1030,7 +1030,7 @@ public ResponseEntityResponseExtractor(@Nullable Type responseType) {
}

@Override
public ResponseEntity<T> extractData(ClientHttpResponse response) throws IOException {
public ResponseEntity<@Nullable T> extractData(ClientHttpResponse response) throws IOException {
if (this.delegate != null) {
T body = this.delegate.extractData(response);
return ResponseEntity.status(response.getStatusCode()).headers(response.getHeaders()).body(body);
Expand Down
Loading
Loading