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 cbe60aa353e..1428f3d9d90 100644
--- a/spring-web/src/main/java/org/springframework/http/ProblemDetail.java
+++ b/spring-web/src/main/java/org/springframework/http/ProblemDetail.java
@@ -216,6 +216,18 @@ public class ProblemDetail {
this.properties.put(name, value);
}
+ /**
+ * Setter for the {@link #getProperties() properties map}.
+ *
By default, this is not set.
+ *
When Jackson JSON is present on the classpath, any properties set here
+ * are rendered as top level key-value pairs in the output JSON. Otherwise,
+ * they are rendered as a {@code "properties"} sub-map.
+ * @param properties the properties map
+ */
+ public void setProperties(@Nullable Map properties) {
+ this.properties = properties;
+ }
+
/**
* Return a generic map of properties that are not known ahead of time,
* possibly {@code null} if no properties have been added. To add a property,
diff --git a/spring-web/src/test/kotlin/org/springframework/http/KotlinProblemDetailTests.kt b/spring-web/src/test/kotlin/org/springframework/http/KotlinProblemDetailTests.kt
new file mode 100644
index 00000000000..a4669274f02
--- /dev/null
+++ b/spring-web/src/test/kotlin/org/springframework/http/KotlinProblemDetailTests.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2002-2023 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.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.http
+
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.jupiter.api.Test
+
+/**
+ * Kotlin tests for [ProblemDetail].
+ */
+class KotlinProblemDetailTests {
+
+ @Test // gh-31430
+ fun propertiesSetter() {
+ val problemDetail = ProblemDetail()
+ val map = mapOf("foo" to "bar")
+ problemDetail.properties = map
+ assertThat(problemDetail.properties).isEqualTo(map)
+ }
+
+}