From a8f31f5b9e3956ad9e696faf0709ac1cbb48c761 Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Thu, 6 Apr 2023 16:38:23 +0800 Subject: [PATCH] Improve ProblemDetail equals and hashCode Lazy computed title property should be taken into account See gh-30294 --- .../java/org/springframework/http/ProblemDetail.java | 5 +++-- .../org/springframework/http/ProblemDetailTests.java | 10 +++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/ProblemDetail.java b/spring-web/src/main/java/org/springframework/http/ProblemDetail.java index 3b0ee036f6b1..3044b0642d45 100644 --- a/spring-web/src/main/java/org/springframework/http/ProblemDetail.java +++ b/spring-web/src/main/java/org/springframework/http/ProblemDetail.java @@ -42,6 +42,7 @@ * * @author Rossen Stoyanchev * @author Juergen Hoeller + * @author Yanming Zhou * @since 6.0 * @see RFC 7807 * @see org.springframework.web.ErrorResponse @@ -239,7 +240,7 @@ public boolean equals(@Nullable Object other) { return false; } return (this.type.equals(otherDetail.type) && - ObjectUtils.nullSafeEquals(this.title, otherDetail.title) && + ObjectUtils.nullSafeEquals(this.getTitle(), otherDetail.getTitle()) && this.status == otherDetail.status && ObjectUtils.nullSafeEquals(this.detail, otherDetail.detail) && ObjectUtils.nullSafeEquals(this.instance, otherDetail.instance) && @@ -249,7 +250,7 @@ public boolean equals(@Nullable Object other) { @Override public int hashCode() { int result = this.type.hashCode(); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.title); + result = 31 * result + ObjectUtils.nullSafeHashCode(this.getTitle()); result = 31 * result + this.status; result = 31 * result + ObjectUtils.nullSafeHashCode(this.detail); result = 31 * result + ObjectUtils.nullSafeHashCode(this.instance); diff --git a/spring-web/src/test/java/org/springframework/http/ProblemDetailTests.java b/spring-web/src/test/java/org/springframework/http/ProblemDetailTests.java index 4b94d9786d6a..9785fd525945 100644 --- a/spring-web/src/test/java/org/springframework/http/ProblemDetailTests.java +++ b/spring-web/src/test/java/org/springframework/http/ProblemDetailTests.java @@ -16,6 +16,7 @@ package org.springframework.http; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -24,11 +25,12 @@ * Unit tests for {@link ProblemDetail}. * * @author Juergen Hoeller + * @author Yanming Zhou */ class ProblemDetailTests { @Test - void equalsAndHashCode() { + void equalsAndHashCode() throws Exception { ProblemDetail pd1 = ProblemDetail.forStatus(500); ProblemDetail pd2 = ProblemDetail.forStatus(HttpStatus.INTERNAL_SERVER_ERROR); ProblemDetail pd3 = ProblemDetail.forStatus(HttpStatus.NOT_FOUND); @@ -48,6 +50,12 @@ void equalsAndHashCode() { assertThat(pd2).isNotEqualTo(pd4); assertThat(pd1.hashCode()).isNotEqualTo(pd3.hashCode()); assertThat(pd1.hashCode()).isNotEqualTo(pd4.hashCode()); + + ObjectMapper om = new ObjectMapper(); + ProblemDetail pd5 = om.readValue(om.writeValueAsBytes(pd1), ProblemDetail.class); + assertThat(pd1).isEqualTo(pd5); + assertThat(pd5).isEqualTo(pd1); + assertThat(pd1.hashCode()).isEqualTo(pd5.hashCode()); } }