diff --git a/spring-web/src/main/java/org/springframework/http/RequestEntity.java b/spring-web/src/main/java/org/springframework/http/RequestEntity.java index 4c77123332c..6dd27d02db2 100644 --- a/spring-web/src/main/java/org/springframework/http/RequestEntity.java +++ b/spring-web/src/main/java/org/springframework/http/RequestEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -194,15 +194,15 @@ public class RequestEntity extends HttpEntity { return false; } RequestEntity otherEntity = (RequestEntity) other; - return (ObjectUtils.nullSafeEquals(getMethod(), otherEntity.getMethod()) && - ObjectUtils.nullSafeEquals(getUrl(), otherEntity.getUrl())); + return (ObjectUtils.nullSafeEquals(this.method, otherEntity.method) && + ObjectUtils.nullSafeEquals(this.url, otherEntity.url)); } @Override public int hashCode() { int hashCode = super.hashCode(); hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.method); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getUrl()); + hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.url); return hashCode; } @@ -544,13 +544,13 @@ public class RequestEntity extends HttpEntity { private final URI uri; @Nullable - String uriTemplate; + private final String uriTemplate; @Nullable - private Object[] uriVarsArray; + private final Object[] uriVarsArray; @Nullable - Map uriVarsMap; + private final Map uriVarsMap; DefaultBodyBuilder(HttpMethod method, URI url) { this.method = method; @@ -661,7 +661,7 @@ public class RequestEntity extends HttpEntity { return buildInternal(body, type); } - private RequestEntity buildInternal(@Nullable T body, @Nullable Type type) { + private RequestEntity buildInternal(@Nullable T body, @Nullable Type type) { if (this.uri != null) { return new RequestEntity<>(body, this.headers, this.method, this.uri, type); } @@ -716,6 +716,25 @@ public class RequestEntity extends HttpEntity { return this.uriVarsMap; } + @Override + public boolean equals(@Nullable Object other) { + if (this == other) { + return true; + } + if (!super.equals(other)) { + return false; + } + UriTemplateRequestEntity otherEntity = (UriTemplateRequestEntity) other; + return (ObjectUtils.nullSafeEquals(this.uriTemplate, otherEntity.uriTemplate) && + ObjectUtils.nullSafeEquals(this.uriVarsArray, otherEntity.uriVarsArray) && + ObjectUtils.nullSafeEquals(this.uriVarsMap, otherEntity.uriVarsMap)); + } + + @Override + public int hashCode() { + return (29 * super.hashCode() + ObjectUtils.nullSafeHashCode(this.uriTemplate)); + } + @Override public String toString() { return format(getMethod(), getUriTemplate(), getBody(), getHeaders()); diff --git a/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java b/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java index e165ef8082d..1c979728f9b 100644 --- a/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java +++ b/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -20,6 +20,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -175,4 +176,37 @@ class RequestEntityTests { assertThat(entity.getType()).isEqualTo(typeReference.getType()); } + @Test + void equalityWithUrl() { + RequestEntity requestEntity1 = RequestEntity.method(HttpMethod.GET, "http://test.api/path/").build(); + RequestEntity requestEntity2 = RequestEntity.method(HttpMethod.GET, "http://test.api/path/").build(); + RequestEntity requestEntity3 = RequestEntity.method(HttpMethod.GET, "http://test.api/pathX/").build(); + + assertThat(requestEntity1).isEqualTo(requestEntity2); + assertThat(requestEntity2).isEqualTo(requestEntity1); + assertThat(requestEntity1).isNotEqualTo(requestEntity3); + assertThat(requestEntity3).isNotEqualTo(requestEntity2); + assertThat(requestEntity1.hashCode()).isEqualTo(requestEntity2.hashCode()); + assertThat(requestEntity1.hashCode()).isNotEqualTo(requestEntity3.hashCode()); + } + + @Test // gh-27531 + void equalityWithUriTemplate() { + Map vars = Collections.singletonMap("id", "1"); + + RequestEntity requestEntity1 = + RequestEntity.method(HttpMethod.GET, "http://test.api/path/{id}", vars).build(); + RequestEntity requestEntity2 = + RequestEntity.method(HttpMethod.GET, "http://test.api/path/{id}", vars).build(); + RequestEntity requestEntity3 = + RequestEntity.method(HttpMethod.GET, "http://test.api/pathX/{id}", vars).build(); + + assertThat(requestEntity1).isEqualTo(requestEntity2); + assertThat(requestEntity2).isEqualTo(requestEntity1); + assertThat(requestEntity1).isNotEqualTo(requestEntity3); + assertThat(requestEntity3).isNotEqualTo(requestEntity2); + assertThat(requestEntity1.hashCode()).isEqualTo(requestEntity2.hashCode()); + assertThat(requestEntity1.hashCode()).isNotEqualTo(requestEntity3.hashCode()); + } + }