mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Add JsonConverterDelegate
The JsonConverterDelegate interface replaces usages of HttpMessageContentConverter to provides the flexibility to use either message converters or WebFlux codecs. HttpMessageContentConverter is deprecated, and replaced with a package private copy (DefaultJsonConverterDelegate) in the org.springframework.test.json package that is accessible through a static method on JsonConverterDelegate. See gh-35737
This commit is contained in:
+19
-1
@@ -18,11 +18,13 @@ package org.springframework.test.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.GenericHttpMessageConverter;
|
||||
@@ -31,6 +33,7 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.http.converter.SmartHttpMessageConverter;
|
||||
import org.springframework.mock.http.MockHttpInputMessage;
|
||||
import org.springframework.mock.http.MockHttpOutputMessage;
|
||||
import org.springframework.test.json.JsonConverterDelegate;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.function.SingletonSupplier;
|
||||
|
||||
@@ -39,8 +42,10 @@ import org.springframework.util.function.SingletonSupplier;
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 6.2
|
||||
* @deprecated in favor of static factory methods in {@link JsonConverterDelegate}
|
||||
*/
|
||||
public class HttpMessageContentConverter {
|
||||
@Deprecated(since = "7.0", forRemoval = true)
|
||||
public class HttpMessageContentConverter implements JsonConverterDelegate {
|
||||
|
||||
private static final MediaType JSON = MediaType.APPLICATION_JSON;
|
||||
|
||||
@@ -69,6 +74,19 @@ public class HttpMessageContentConverter {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T> T read(String content, ResolvableType targetType) throws IOException{
|
||||
HttpInputMessage message = new MockHttpInputMessage(content.getBytes(StandardCharsets.UTF_8));
|
||||
message.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
|
||||
return convert(message, MediaType.APPLICATION_JSON, targetType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T map(Object value, ResolvableType targetType) throws IOException {
|
||||
return convertViaJson(value, targetType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert the given {@link HttpInputMessage} whose content must match the
|
||||
* given {@link MediaType} to the requested {@code targetType}.
|
||||
|
||||
+6
-19
@@ -20,7 +20,6 @@ import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -42,11 +41,6 @@ import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.InputStreamResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.http.MockHttpInputMessage;
|
||||
import org.springframework.test.http.HttpMessageContentConverter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -77,7 +71,7 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent
|
||||
private static final Failures failures = Failures.instance();
|
||||
|
||||
|
||||
private final @Nullable HttpMessageContentConverter contentConverter;
|
||||
private final @Nullable JsonConverterDelegate converterDelegate;
|
||||
|
||||
private @Nullable Class<?> resourceLoadClass;
|
||||
|
||||
@@ -92,7 +86,7 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent
|
||||
*/
|
||||
protected AbstractJsonContentAssert(@Nullable JsonContent actual, Class<?> selfType) {
|
||||
super(actual, selfType);
|
||||
this.contentConverter = (actual != null ? actual.getContentConverter() : null);
|
||||
this.converterDelegate = (actual != null ? actual.getJsonConverterDelegate() : null);
|
||||
this.jsonLoader = new JsonLoader(null, null);
|
||||
as("JSON content");
|
||||
}
|
||||
@@ -131,13 +125,12 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent
|
||||
|
||||
private <T> T convertToTargetType(Type targetType) {
|
||||
String json = this.actual.getJson();
|
||||
if (this.contentConverter == null) {
|
||||
if (this.converterDelegate == null) {
|
||||
throw new IllegalStateException(
|
||||
"No JSON message converter available to convert %s".formatted(json));
|
||||
}
|
||||
try {
|
||||
return this.contentConverter.convert(fromJson(json), MediaType.APPLICATION_JSON,
|
||||
ResolvableType.forType(targetType));
|
||||
return this.converterDelegate.read(json, ResolvableType.forType(targetType));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw failure(new ValueProcessingFailed(json,
|
||||
@@ -146,12 +139,6 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent
|
||||
}
|
||||
}
|
||||
|
||||
private HttpInputMessage fromJson(String json) {
|
||||
MockHttpInputMessage inputMessage = new MockHttpInputMessage(json.getBytes(StandardCharsets.UTF_8));
|
||||
inputMessage.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
|
||||
return inputMessage;
|
||||
}
|
||||
|
||||
|
||||
// JsonPath support
|
||||
|
||||
@@ -163,7 +150,7 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent
|
||||
*/
|
||||
public JsonPathValueAssert extractingPath(String path) {
|
||||
Object value = new JsonPathValue(path).getValue();
|
||||
return new JsonPathValueAssert(value, path, this.contentConverter);
|
||||
return new JsonPathValueAssert(value, path, this.converterDelegate);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,7 +161,7 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent
|
||||
*/
|
||||
public SELF hasPathSatisfying(String path, Consumer<AssertProvider<JsonPathValueAssert>> valueRequirements) {
|
||||
Object value = new JsonPathValue(path).assertHasPath();
|
||||
JsonPathValueAssert valueAssert = new JsonPathValueAssert(value, path, this.contentConverter);
|
||||
JsonPathValueAssert valueAssert = new JsonPathValueAssert(value, path, this.converterDelegate);
|
||||
valueRequirements.accept(() -> valueAssert);
|
||||
return this.myself;
|
||||
}
|
||||
|
||||
+15
-7
@@ -35,7 +35,6 @@ import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.http.converter.GenericHttpMessageConverter;
|
||||
import org.springframework.test.http.HttpMessageContentConverter;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -64,14 +63,23 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
|
||||
|
||||
private final Failures failures = Failures.instance();
|
||||
|
||||
private final @Nullable HttpMessageContentConverter contentConverter;
|
||||
private final @Nullable JsonConverterDelegate converterDelegate;
|
||||
|
||||
|
||||
protected AbstractJsonValueAssert(@Nullable Object actual, Class<?> selfType,
|
||||
@Nullable HttpMessageContentConverter contentConverter) {
|
||||
protected AbstractJsonValueAssert(
|
||||
@Nullable Object actual, Class<?> selfType, @Nullable JsonConverterDelegate converter) {
|
||||
|
||||
super(actual, selfType);
|
||||
this.contentConverter = contentConverter;
|
||||
this.converterDelegate = converter;
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(since = "7.0", forRemoval = true)
|
||||
protected AbstractJsonValueAssert(
|
||||
@Nullable Object actual, Class<?> selfType,
|
||||
org.springframework.test.http.@Nullable HttpMessageContentConverter converter) {
|
||||
|
||||
this(actual, selfType, (JsonConverterDelegate) converter);
|
||||
}
|
||||
|
||||
|
||||
@@ -196,12 +204,12 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
|
||||
}
|
||||
|
||||
private <T> T convertToTargetType(Type targetType) {
|
||||
if (this.contentConverter == null) {
|
||||
if (this.converterDelegate == null) {
|
||||
throw new IllegalStateException(
|
||||
"No JSON message converter available to convert %s".formatted(actualToString()));
|
||||
}
|
||||
try {
|
||||
return this.contentConverter.convertViaJson(this.actual, ResolvableType.forType(targetType));
|
||||
return this.converterDelegate.map(this.actual, ResolvableType.forType(targetType));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw valueProcessingFailed("To convert successfully to:%n %s%nBut it failed:%n %s%n"
|
||||
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2002-present 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.test.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.GenericHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.http.converter.SmartHttpMessageConverter;
|
||||
import org.springframework.mock.http.MockHttpInputMessage;
|
||||
import org.springframework.mock.http.MockHttpOutputMessage;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.function.SingletonSupplier;
|
||||
|
||||
/**
|
||||
* Default {@link JsonConverterDelegate} based on {@link HttpMessageConverter}s.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 7.0
|
||||
*/
|
||||
final class DefaultJsonConverterDelegate implements JsonConverterDelegate {
|
||||
|
||||
private static final MediaType JSON = MediaType.APPLICATION_JSON;
|
||||
|
||||
private final List<HttpMessageConverter<?>> messageConverters;
|
||||
|
||||
|
||||
DefaultJsonConverterDelegate(Iterable<HttpMessageConverter<?>> messageConverters) {
|
||||
this.messageConverters = StreamSupport.stream(messageConverters.spliterator(), false).toList();
|
||||
Assert.notEmpty(this.messageConverters, "At least one message converter needs to be specified");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T> T read(String content, ResolvableType targetType) throws IOException{
|
||||
HttpInputMessage message = new MockHttpInputMessage(content.getBytes(StandardCharsets.UTF_8));
|
||||
message.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
|
||||
return read(message, MediaType.APPLICATION_JSON, targetType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given {@link HttpInputMessage} whose content must match the
|
||||
* given {@link MediaType} to the requested {@code targetType}.
|
||||
* @param message an input message
|
||||
* @param mediaType the media type of the input
|
||||
* @param targetType the target type
|
||||
* @param <T> the converted object type
|
||||
* @return a value of the given {@code targetType}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T read(HttpInputMessage message, MediaType mediaType, ResolvableType targetType)
|
||||
throws IOException, HttpMessageNotReadableException {
|
||||
|
||||
Class<?> contextClass = targetType.getRawClass();
|
||||
SingletonSupplier<Type> javaType = SingletonSupplier.of(targetType::getType);
|
||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
|
||||
if (messageConverter instanceof GenericHttpMessageConverter<?> genericMessageConverter) {
|
||||
Type type = javaType.obtain();
|
||||
if (genericMessageConverter.canRead(type, contextClass, mediaType)) {
|
||||
return (T) genericMessageConverter.read(type, contextClass, message);
|
||||
}
|
||||
}
|
||||
else if (messageConverter instanceof SmartHttpMessageConverter<?> smartMessageConverter) {
|
||||
if (smartMessageConverter.canRead(targetType, mediaType)) {
|
||||
return (T) smartMessageConverter.read(targetType, message, null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Class<?> targetClass = (contextClass != null ? contextClass : Object.class);
|
||||
if (messageConverter.canRead(targetClass, mediaType)) {
|
||||
HttpMessageConverter<T> simpleMessageConverter = (HttpMessageConverter<T>) messageConverter;
|
||||
Class<? extends T> clazz = (Class<? extends T>) targetClass;
|
||||
return simpleMessageConverter.read(clazz, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("No converter found to read [%s] to [%s]".formatted(mediaType, targetType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given raw value to the given {@code targetType} by writing
|
||||
* it first to JSON and reading it back.
|
||||
* @param value the value to convert
|
||||
* @param targetType the target type
|
||||
* @param <T> the converted object type
|
||||
* @return a value of the given {@code targetType}
|
||||
*/
|
||||
@Override
|
||||
public <T> T map(Object value, ResolvableType targetType) throws IOException {
|
||||
MockHttpOutputMessage outputMessage = writeToJson(value, ResolvableType.forInstance(value));
|
||||
return read(fromHttpOutputMessage(outputMessage), JSON, targetType);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private MockHttpOutputMessage writeToJson(Object value, ResolvableType valueType) throws IOException {
|
||||
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
|
||||
Class<?> valueClass = value.getClass();
|
||||
SingletonSupplier<Type> javaType = SingletonSupplier.of(valueType::getType);
|
||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
|
||||
if (messageConverter instanceof GenericHttpMessageConverter genericMessageConverter) {
|
||||
Type type = javaType.obtain();
|
||||
if (genericMessageConverter.canWrite(type, valueClass, JSON)) {
|
||||
genericMessageConverter.write(value, type, JSON, outputMessage);
|
||||
return outputMessage;
|
||||
}
|
||||
}
|
||||
else if (messageConverter instanceof SmartHttpMessageConverter smartMessageConverter) {
|
||||
if (smartMessageConverter.canWrite(valueType, valueClass, JSON)) {
|
||||
smartMessageConverter.write(value, valueType, JSON, outputMessage, null);
|
||||
return outputMessage;
|
||||
}
|
||||
}
|
||||
else if (messageConverter.canWrite(valueClass, JSON)) {
|
||||
((HttpMessageConverter<Object>) messageConverter).write(value, JSON, outputMessage);
|
||||
return outputMessage;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("No converter found to convert [%s] to JSON".formatted(valueType));
|
||||
}
|
||||
|
||||
private static HttpInputMessage fromHttpOutputMessage(MockHttpOutputMessage message) {
|
||||
MockHttpInputMessage inputMessage = new MockHttpInputMessage(message.getBodyAsBytes());
|
||||
inputMessage.getHeaders().addAll(message.getHeaders());
|
||||
return inputMessage;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,19 +34,32 @@ public final class JsonContent implements AssertProvider<JsonContentAssert> {
|
||||
|
||||
private final String json;
|
||||
|
||||
private final @Nullable HttpMessageContentConverter contentConverter;
|
||||
private final @Nullable JsonConverterDelegate converterDelegate;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code JsonContent} instance with the message converter to
|
||||
* use to deserialize content.
|
||||
* @param json the actual JSON content
|
||||
* @param contentConverter the content converter to use
|
||||
* @param converterDelegate the content converter to use
|
||||
*/
|
||||
public JsonContent(String json, @Nullable HttpMessageContentConverter contentConverter) {
|
||||
public JsonContent(String json, @Nullable JsonConverterDelegate converterDelegate) {
|
||||
Assert.notNull(json, "JSON must not be null");
|
||||
this.json = json;
|
||||
this.contentConverter = contentConverter;
|
||||
this.converterDelegate = converterDelegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code JsonContent} instance with the message converter to
|
||||
* use to deserialize content.
|
||||
* @param json the actual JSON content
|
||||
* @param converter the content converter to use
|
||||
* @deprecated in favour of {@link #JsonContent(String, JsonConverterDelegate)}
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(since = "7.0", forRemoval = true)
|
||||
public JsonContent(String json, @Nullable HttpMessageContentConverter converter) {
|
||||
this(json, (JsonConverterDelegate) converter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +67,7 @@ public final class JsonContent implements AssertProvider<JsonContentAssert> {
|
||||
* @param json the actual JSON content
|
||||
*/
|
||||
public JsonContent(String json) {
|
||||
this(json, null);
|
||||
this(json, (JsonConverterDelegate) null);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,10 +88,21 @@ public final class JsonContent implements AssertProvider<JsonContentAssert> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link HttpMessageContentConverter} to use to deserialize content.
|
||||
* Return the {@link JsonConverterDelegate} to use to decode JSON content.
|
||||
* @since 7.0
|
||||
*/
|
||||
public @Nullable JsonConverterDelegate getJsonConverterDelegate() {
|
||||
return this.converterDelegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link HttpMessageContentConverter} to use to deserialize content.
|
||||
* @deprecated in favour of {@link #getJsonConverterDelegate()}
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(since = "7.0", forRemoval = true)
|
||||
@Nullable HttpMessageContentConverter getContentConverter() {
|
||||
return this.contentConverter;
|
||||
return (this.converterDelegate instanceof HttpMessageContentConverter cc ? cc : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2002-present 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.test.json;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
|
||||
/**
|
||||
* Delegate to abstract JSON type conversion in AssertJ support clases.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 7.0
|
||||
*/
|
||||
public interface JsonConverterDelegate {
|
||||
|
||||
/**
|
||||
* Convert JSON content to the given {@code targetType}.
|
||||
* @param content the JSON content
|
||||
* @param targetType the target type
|
||||
* @return the decoded object
|
||||
* @param <T> the target type
|
||||
*/
|
||||
<T> T read(String content, ResolvableType targetType) throws IOException;
|
||||
|
||||
/**
|
||||
* Map the given Object value to the given {@code targetType}, via
|
||||
* serialization and deserialization to and from JSON. This is useful for
|
||||
* mapping generic maps and lists to higher level Objects.
|
||||
* @param value the value to map
|
||||
* @param targetType the target tyep
|
||||
* @return the decoded object
|
||||
* @param <T> the target type
|
||||
*/
|
||||
<T> T map(Object value, ResolvableType targetType) throws IOException;
|
||||
|
||||
|
||||
/**
|
||||
* Create a {@link JsonConverterDelegate} from message converters.
|
||||
* @param candidates the candidates
|
||||
*/
|
||||
static JsonConverterDelegate of(Iterable<HttpMessageConverter<?>> candidates) {
|
||||
return new DefaultJsonConverterDelegate(candidates);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,8 +19,6 @@ package org.springframework.test.json;
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.test.http.HttpMessageContentConverter;
|
||||
|
||||
/**
|
||||
* AssertJ {@linkplain org.assertj.core.api.Assert assertions} that can be applied
|
||||
* to a JSON value produced by evaluating a {@linkplain JsonPath JSON path}
|
||||
@@ -34,10 +32,8 @@ public class JsonPathValueAssert extends AbstractJsonValueAssert<JsonPathValueAs
|
||||
private final String expression;
|
||||
|
||||
|
||||
JsonPathValueAssert(@Nullable Object actual, String expression,
|
||||
@Nullable HttpMessageContentConverter contentConverter) {
|
||||
|
||||
super(actual, JsonPathValueAssert.class, contentConverter);
|
||||
JsonPathValueAssert(@Nullable Object actual, String expression, @Nullable JsonConverterDelegate converter) {
|
||||
super(actual, JsonPathValueAssert.class, converter);
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
|
||||
+15
-5
@@ -26,10 +26,10 @@ import org.assertj.core.api.StringAssert;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.test.http.HttpMessageContentConverter;
|
||||
import org.springframework.test.json.AbstractJsonContentAssert;
|
||||
import org.springframework.test.json.JsonContent;
|
||||
import org.springframework.test.json.JsonContentAssert;
|
||||
import org.springframework.test.json.JsonConverterDelegate;
|
||||
import org.springframework.test.web.UriAssert;
|
||||
|
||||
/**
|
||||
@@ -44,13 +44,23 @@ import org.springframework.test.web.UriAssert;
|
||||
public abstract class AbstractMockHttpServletResponseAssert<SELF extends AbstractMockHttpServletResponseAssert<SELF, ACTUAL>, ACTUAL>
|
||||
extends AbstractHttpServletResponseAssert<MockHttpServletResponse, SELF, ACTUAL> {
|
||||
|
||||
private final @Nullable HttpMessageContentConverter contentConverter;
|
||||
private final @Nullable JsonConverterDelegate converterDelegate;
|
||||
|
||||
|
||||
protected AbstractMockHttpServletResponseAssert(
|
||||
@Nullable HttpMessageContentConverter contentConverter, ACTUAL actual, Class<?> selfType) {
|
||||
@Nullable JsonConverterDelegate converterDelegate, ACTUAL actual, Class<?> selfType) {
|
||||
|
||||
super(actual, selfType);
|
||||
this.contentConverter = contentConverter;
|
||||
this.converterDelegate = converterDelegate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(since = "7.0", forRemoval = true)
|
||||
protected AbstractMockHttpServletResponseAssert(
|
||||
org.springframework.test.http.@Nullable HttpMessageContentConverter converter,
|
||||
ACTUAL actual, Class<?> selfType) {
|
||||
|
||||
this((JsonConverterDelegate) converter, actual, selfType);
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +103,7 @@ public abstract class AbstractMockHttpServletResponseAssert<SELF extends Abstrac
|
||||
* </code></pre>
|
||||
*/
|
||||
public AbstractJsonContentAssert<?> bodyJson() {
|
||||
return new JsonContentAssert(new JsonContent(readBody(), this.contentConverter));
|
||||
return new JsonContentAssert(new JsonContent(readBody(), this.converterDelegate));
|
||||
}
|
||||
|
||||
private String readBody() {
|
||||
|
||||
+5
-5
@@ -18,7 +18,7 @@ package org.springframework.test.web.servlet.assertj;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.test.http.HttpMessageContentConverter;
|
||||
import org.springframework.test.json.JsonConverterDelegate;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
|
||||
/**
|
||||
@@ -33,15 +33,15 @@ final class DefaultMvcTestResult implements MvcTestResult {
|
||||
|
||||
private final @Nullable Exception unresolvedException;
|
||||
|
||||
private final @Nullable HttpMessageContentConverter contentConverter;
|
||||
private final @Nullable JsonConverterDelegate converterDelegate;
|
||||
|
||||
|
||||
DefaultMvcTestResult(@Nullable MvcResult mvcResult, @Nullable Exception unresolvedException,
|
||||
@Nullable HttpMessageContentConverter contentConverter) {
|
||||
@Nullable JsonConverterDelegate converterDelegate) {
|
||||
|
||||
this.mvcResult = mvcResult;
|
||||
this.unresolvedException = unresolvedException;
|
||||
this.contentConverter = contentConverter;
|
||||
this.converterDelegate = converterDelegate;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ final class DefaultMvcTestResult implements MvcTestResult {
|
||||
*/
|
||||
@Override
|
||||
public MvcTestResultAssert assertThat() {
|
||||
return new MvcTestResultAssert(this, this.contentConverter);
|
||||
return new MvcTestResultAssert(this, this.converterDelegate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-9
@@ -30,7 +30,7 @@ import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockMultipartHttpServletRequest;
|
||||
import org.springframework.test.http.HttpMessageContentConverter;
|
||||
import org.springframework.test.json.JsonConverterDelegate;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.RequestBuilder;
|
||||
@@ -132,13 +132,13 @@ public final class MockMvcTester {
|
||||
|
||||
private final MockMvc mockMvc;
|
||||
|
||||
private final @Nullable HttpMessageContentConverter contentConverter;
|
||||
private final @Nullable JsonConverterDelegate converterDelegate;
|
||||
|
||||
|
||||
private MockMvcTester(MockMvc mockMvc, @Nullable HttpMessageContentConverter contentConverter) {
|
||||
private MockMvcTester(MockMvc mockMvc, @Nullable JsonConverterDelegate converter) {
|
||||
Assert.notNull(mockMvc, "mockMVC should not be null");
|
||||
this.mockMvc = mockMvc;
|
||||
this.contentConverter = contentConverter;
|
||||
this.converterDelegate = converter;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,7 +232,7 @@ public final class MockMvcTester {
|
||||
* @return a new instance using the specified converters
|
||||
*/
|
||||
public MockMvcTester withHttpMessageConverters(Iterable<HttpMessageConverter<?>> httpMessageConverters) {
|
||||
return new MockMvcTester(this.mockMvc, HttpMessageContentConverter.of(httpMessageConverters));
|
||||
return new MockMvcTester(this.mockMvc, JsonConverterDelegate.of(httpMessageConverters));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -374,10 +374,10 @@ public final class MockMvcTester {
|
||||
public MvcTestResult perform(RequestBuilder requestBuilder) {
|
||||
Object result = getMvcResultOrFailure(requestBuilder);
|
||||
if (result instanceof MvcResult mvcResult) {
|
||||
return new DefaultMvcTestResult(mvcResult, null, this.contentConverter);
|
||||
return new DefaultMvcTestResult(mvcResult, null, this.converterDelegate);
|
||||
}
|
||||
else {
|
||||
return new DefaultMvcTestResult(null, (Exception) result, this.contentConverter);
|
||||
return new DefaultMvcTestResult(null, (Exception) result, this.converterDelegate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ public final class MockMvcTester {
|
||||
|
||||
@Override
|
||||
public MvcTestResultAssert assertThat() {
|
||||
return new MvcTestResultAssert(exchange(), MockMvcTester.this.contentConverter);
|
||||
return new MvcTestResultAssert(exchange(), MockMvcTester.this.converterDelegate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,7 +541,7 @@ public final class MockMvcTester {
|
||||
|
||||
@Override
|
||||
public MvcTestResultAssert assertThat() {
|
||||
return new MvcTestResultAssert(exchange(), MockMvcTester.this.contentConverter);
|
||||
return new MvcTestResultAssert(exchange(), MockMvcTester.this.converterDelegate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -34,7 +34,7 @@ import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.test.http.HttpMessageContentConverter;
|
||||
import org.springframework.test.json.JsonConverterDelegate;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.ResultHandler;
|
||||
import org.springframework.test.web.servlet.ResultMatcher;
|
||||
@@ -51,8 +51,8 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
*/
|
||||
public class MvcTestResultAssert extends AbstractMockHttpServletResponseAssert<MvcTestResultAssert, MvcTestResult> {
|
||||
|
||||
MvcTestResultAssert(MvcTestResult actual, @Nullable HttpMessageContentConverter contentConverter) {
|
||||
super(contentConverter, actual, MvcTestResultAssert.class);
|
||||
MvcTestResultAssert(MvcTestResult actual, @Nullable JsonConverterDelegate converterDelegate) {
|
||||
super(converterDelegate, actual, MvcTestResultAssert.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+7
-7
@@ -39,10 +39,10 @@ import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.converter.HttpMessageConverters;
|
||||
import org.springframework.test.http.HttpMessageContentConverter;
|
||||
import org.springframework.test.json.JsonAssert;
|
||||
import org.springframework.test.json.JsonComparator;
|
||||
import org.springframework.test.json.JsonCompareMode;
|
||||
import org.springframework.test.json.JsonConverterDelegate;
|
||||
import org.springframework.test.util.AssertionErrors;
|
||||
import org.springframework.test.util.ExceptionCollector;
|
||||
import org.springframework.test.util.XmlExpectationsHelper;
|
||||
@@ -69,7 +69,7 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
|
||||
private final DefaultRestTestClientBuilder<?> restTestClientBuilder;
|
||||
|
||||
private final @Nullable HttpMessageContentConverter messageContentConverter;
|
||||
private final @Nullable JsonConverterDelegate converterDelegate;
|
||||
|
||||
private final AtomicLong requestIndex = new AtomicLong();
|
||||
|
||||
@@ -81,7 +81,7 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
this.restClient = builder.requestInterceptor(this.wiretapInterceptor).build();
|
||||
this.entityResultConsumer = entityResultConsumer;
|
||||
this.restTestClientBuilder = restTestClientBuilder;
|
||||
this.messageContentConverter = new ConverterCallback(this.restClient).getConverter();
|
||||
this.converterDelegate = new ConverterCallback(this.restClient).getConverter();
|
||||
}
|
||||
|
||||
|
||||
@@ -138,20 +138,20 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
|
||||
private static class ConverterCallback {
|
||||
|
||||
private @Nullable HttpMessageContentConverter converter;
|
||||
private @Nullable JsonConverterDelegate converter;
|
||||
|
||||
ConverterCallback(RestClient client) {
|
||||
client.mutate()
|
||||
.configureMessageConverters(convertersBuilder -> {
|
||||
HttpMessageConverters converters = convertersBuilder.build();
|
||||
if (converters.iterator().hasNext()) {
|
||||
this.converter = HttpMessageContentConverter.of(converters);
|
||||
this.converter = JsonConverterDelegate.of(converters);
|
||||
}
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
public @Nullable HttpMessageContentConverter getConverter() {
|
||||
public @Nullable JsonConverterDelegate getConverter() {
|
||||
return this.converter;
|
||||
}
|
||||
}
|
||||
@@ -290,7 +290,7 @@ class DefaultRestTestClient implements RestTestClient {
|
||||
(request, response) -> {
|
||||
byte[] requestBody = wiretapInterceptor.getRequestContent(this.requestId);
|
||||
return new ExchangeResult(
|
||||
request, response, this.uriTemplate, requestBody, messageContentConverter);
|
||||
request, response, this.uriTemplate, requestBody, converterDelegate);
|
||||
}, false),
|
||||
DefaultRestTestClient.this.entityResultConsumer);
|
||||
}
|
||||
|
||||
+8
-8
@@ -38,7 +38,7 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseCookie;
|
||||
import org.springframework.test.http.HttpMessageContentConverter;
|
||||
import org.springframework.test.json.JsonConverterDelegate;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
@@ -75,7 +75,7 @@ public class ExchangeResult {
|
||||
|
||||
private final byte[] requestBody;
|
||||
|
||||
private final @Nullable HttpMessageContentConverter messageContentConverter;
|
||||
private final @Nullable JsonConverterDelegate converterDelegate;
|
||||
|
||||
/** Ensure single logging; for example, for expectAll. */
|
||||
private boolean diagnosticsLogged;
|
||||
@@ -83,7 +83,7 @@ public class ExchangeResult {
|
||||
|
||||
ExchangeResult(
|
||||
HttpRequest request, ConvertibleClientHttpResponse response, @Nullable String uriTemplate,
|
||||
byte[] requestBody, @Nullable HttpMessageContentConverter messageContentConverter) {
|
||||
byte[] requestBody, @Nullable JsonConverterDelegate converter) {
|
||||
|
||||
Assert.notNull(request, "HttpRequest must not be null");
|
||||
Assert.notNull(response, "ClientHttpResponse must not be null");
|
||||
@@ -91,11 +91,11 @@ public class ExchangeResult {
|
||||
this.clientResponse = response;
|
||||
this.uriTemplate = uriTemplate;
|
||||
this.requestBody = requestBody;
|
||||
this.messageContentConverter = messageContentConverter;
|
||||
this.converterDelegate = converter;
|
||||
}
|
||||
|
||||
ExchangeResult(ExchangeResult result) {
|
||||
this(result.request, result.clientResponse, result.uriTemplate, result.requestBody, result.messageContentConverter);
|
||||
this(result.request, result.clientResponse, result.uriTemplate, result.requestBody, result.converterDelegate);
|
||||
this.diagnosticsLogged = result.diagnosticsLogged;
|
||||
}
|
||||
|
||||
@@ -202,11 +202,11 @@ public class ExchangeResult {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a content converter that delegates to the configured HTTP message converters.
|
||||
* Return a {@link JsonConverterDelegate} based on the configured HTTP message converters.
|
||||
* Mainly for internal use from AssertJ support.
|
||||
*/
|
||||
public @Nullable HttpMessageContentConverter getMessageContentConverter() {
|
||||
return this.messageContentConverter;
|
||||
public @Nullable JsonConverterDelegate getConverterDelegate() {
|
||||
return this.converterDelegate;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -342,7 +342,7 @@ public class RestTestClientResponseAssert
|
||||
* </code></pre>
|
||||
*/
|
||||
public AbstractJsonContentAssert<?> bodyJson() {
|
||||
return new JsonContentAssert(new JsonContent(readBody(), getExchangeResult().getMessageContentConverter()));
|
||||
return new JsonContentAssert(new JsonContent(readBody(), getExchangeResult().getConverterDelegate()));
|
||||
}
|
||||
|
||||
private String readBody() {
|
||||
|
||||
Reference in New Issue
Block a user