diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java index 7ea688eede..33ad75dd11 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java @@ -311,7 +311,8 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener JsonEncoding encoding = getJsonEncoding(contentType); OutputStream outputStream = StreamUtils.nonClosing(outputMessage.getBody()); - try (JsonGenerator generator = this.objectMapper.getFactory().createGenerator(outputStream, encoding)) { + JsonGenerator generator = this.objectMapper.getFactory().createGenerator(outputStream, encoding); + try { writePrefix(generator, object); Object value = object; @@ -346,6 +347,7 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener writeSuffix(generator, object); generator.flush(); + generator.close(); } catch (InvalidDefinitionException ex) { throw new HttpMessageConversionException("Type definition error: " + ex.getType(), ex); diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java index 79b1b8ba36..5b5c63c49d 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java @@ -16,11 +16,13 @@ package org.springframework.http.converter.json; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.reflect.Type; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -135,13 +137,7 @@ public class MappingJackson2HttpMessageConverterTests { @Test public void write() throws IOException { MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); - MyBean body = new MyBean(); - body.setString("Foo"); - body.setNumber(42); - body.setFraction(42F); - body.setArray(new String[] {"Foo", "Bar"}); - body.setBool(true); - body.setBytes(new byte[] {0x1, 0x2}); + MyBean body = createSampleBean(); converter.write(body, null, outputMessage); String result = outputMessage.getBodyAsString(StandardCharsets.UTF_8); assertThat(result.contains("\"string\":\"Foo\"")).isTrue(); @@ -157,13 +153,7 @@ public class MappingJackson2HttpMessageConverterTests { @Test public void writeWithBaseType() throws IOException { MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); - MyBean body = new MyBean(); - body.setString("Foo"); - body.setNumber(42); - body.setFraction(42F); - body.setArray(new String[] {"Foo", "Bar"}); - body.setBool(true); - body.setBytes(new byte[] {0x1, 0x2}); + MyBean body = createSampleBean(); converter.write(body, MyBase.class, null, outputMessage); String result = outputMessage.getBodyAsString(StandardCharsets.UTF_8); assertThat(result.contains("\"string\":\"Foo\"")).isTrue(); @@ -194,6 +184,16 @@ public class MappingJackson2HttpMessageConverterTests { converter.read(MyBean.class, inputMessage)); } + @Test // See gh-26246 + public void writeInvalidJson() throws IOException { + MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); + MyBean bean = createSampleBean(); + List body = Arrays.asList(bean, new ByteArrayOutputStream()); + assertThatExceptionOfType(HttpMessageConversionException.class) + .isThrownBy(() -> converter.write(body, null, outputMessage)); + assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_8)).isEmpty(); + } + @Test public void readValidJsonWithUnknownProperty() throws IOException { String body = "{\"string\":\"string\",\"unknownProperty\":\"value\"}"; @@ -492,6 +492,17 @@ public class MappingJackson2HttpMessageConverterTests { assertThat(outputMessage.getHeaders().getContentType()).as("Invalid content-type").isEqualTo(contentType); } + private MyBean createSampleBean() { + MyBean body = new MyBean(); + body.setString("Foo"); + body.setNumber(42); + body.setFraction(42F); + body.setArray(new String[] {"Foo", "Bar"}); + body.setBool(true); + body.setBytes(new byte[] {0x1, 0x2}); + return body; + } + interface MyInterface {