Browse Source

Deprecate MediaType.APPLICATION_JSON_UTF8

This commit deprecates MediaType.APPLICATION_JSON_UTF8 and
MediaType.APPLICATION_PROBLEM_JSON_UTF8 in favor of
MediaType.APPLICATION_JSON and MediaType.APPLICATION_PROBLEM_JSON since
UTF-8 encoding is now handled correctly by most browsers
(related bug has been fixed in Chrome since September 2017).

MediaType.APPLICATION_JSON is now used as the default JSON content type.

Closes gh-22788
pull/22870/head
Sebastien Deleuze 6 years ago
parent
commit
89454e69c3
  1. 3
      spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java
  2. 4
      spring-messaging/src/test/java/org/springframework/messaging/converter/MappingJackson2MessageConverterTests.java
  3. 4
      spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/ContentRequestMatchersIntegrationTests.java
  4. 20
      spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/JsonPathRequestMatchersIntegrationTests.java
  5. 8
      spring-test/src/test/java/org/springframework/test/web/reactive/server/HeaderAssertionTests.java
  6. 4
      spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ErrorTests.java
  7. 10
      spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/JsonContentTests.java
  8. 10
      spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java
  9. 18
      spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java
  10. 4
      spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/RequestParameterTests.java
  11. 2
      spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/ResponseBodyTests.java
  12. 4
      spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/JsonPathAssertionTests.java
  13. 6
      spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt
  14. 38
      spring-web/src/main/java/org/springframework/http/MediaType.java
  15. 5
      spring-web/src/main/java/org/springframework/http/codec/json/Jackson2CodecSupport.java
  16. 6
      spring-web/src/main/java/org/springframework/http/codec/json/Jackson2SmileDecoder.java
  17. 7
      spring-web/src/main/java/org/springframework/http/codec/json/Jackson2SmileEncoder.java
  18. 12
      spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java
  19. 10
      spring-web/src/main/java/org/springframework/http/converter/xml/MappingJackson2XmlHttpMessageConverter.java
  20. 1
      spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java
  21. 4
      spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java
  22. 4
      spring-web/src/test/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriterTests.java
  23. 6
      spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java
  24. 4
      spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverterTests.java
  25. 5
      spring-web/src/test/java/org/springframework/http/converter/smile/MappingJackson2SmileHttpMessageConverterTests.java
  26. 4
      spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensions.kt
  27. 4
      spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxConfigurationSupportTests.java
  28. 8
      spring-webflux/src/test/java/org/springframework/web/reactive/result/HandlerResultHandlerTests.java
  29. 20
      spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/JacksonHintsIntegrationTests.java
  30. 12
      spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageWriterResultHandlerTests.java
  31. 4
      spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingExceptionHandlingIntegrationTests.java
  32. 6
      spring-webflux/src/test/java/org/springframework/web/reactive/result/view/HttpMessageWriterViewTests.java
  33. 4
      spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensionsTests.kt
  34. 2
      spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java
  35. 2
      spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java
  36. 4
      src/docs/asciidoc/languages/kotlin.adoc
  37. 4
      src/docs/asciidoc/testing-webtestclient.adoc
  38. 9
      src/docs/asciidoc/web/webflux.adoc
  39. 9
      src/docs/asciidoc/web/webmvc.adoc

3
spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java

@ -22,7 +22,6 @@ import java.io.StringWriter; @@ -22,7 +22,6 @@ import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReference;
@ -74,7 +73,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter { @@ -74,7 +73,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
* the {@code application/json} MIME type with {@code UTF-8} character set.
*/
public MappingJackson2MessageConverter() {
super(new MimeType("application", "json", StandardCharsets.UTF_8));
super(new MimeType("application", "json"));
this.objectMapper = initObjectMapper();
}

4
spring-messaging/src/test/java/org/springframework/messaging/converter/MappingJackson2MessageConverterTests.java

@ -48,7 +48,7 @@ public class MappingJackson2MessageConverterTests { @@ -48,7 +48,7 @@ public class MappingJackson2MessageConverterTests {
public void defaultConstructor() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
assertThat(converter.getSupportedMimeTypes(),
contains(new MimeType("application", "json", StandardCharsets.UTF_8)));
contains(new MimeType("application", "json")));
assertFalse(converter.getObjectMapper().getDeserializationConfig()
.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));
}
@ -183,7 +183,7 @@ public class MappingJackson2MessageConverterTests { @@ -183,7 +183,7 @@ public class MappingJackson2MessageConverterTests {
assertTrue(actual.contains("\"array\":[\"Foo\",\"Bar\"]"));
assertTrue(actual.contains("\"bool\":true"));
assertTrue(actual.contains("\"bytes\":\"AQI=\""));
assertEquals("Invalid content-type", new MimeType("application", "json", StandardCharsets.UTF_8),
assertEquals("Invalid content-type", new MimeType("application", "json"),
message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class));
}

4
spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/ContentRequestMatchersIntegrationTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -66,7 +66,7 @@ public class ContentRequestMatchersIntegrationTests { @@ -66,7 +66,7 @@ public class ContentRequestMatchersIntegrationTests {
@Test
public void contentType() throws Exception {
this.mockServer.expect(content().contentType("application/json;charset=UTF-8")).andRespond(withSuccess());
this.mockServer.expect(content().contentType("application/json")).andRespond(withSuccess());
executeAndVerify(new Person());
}

20
spring-test/src/test/java/org/springframework/test/web/client/samples/matchers/JsonPathRequestMatchersIntegrationTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -66,7 +66,7 @@ public class JsonPathRequestMatchersIntegrationTests { @@ -66,7 +66,7 @@ public class JsonPathRequestMatchersIntegrationTests {
@Test
public void exists() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.composers[0]").exists())
.andExpect(jsonPath("$.composers[1]").exists())
.andExpect(jsonPath("$.composers[2]").exists())
@ -79,7 +79,7 @@ public class JsonPathRequestMatchersIntegrationTests { @@ -79,7 +79,7 @@ public class JsonPathRequestMatchersIntegrationTests {
@Test
public void doesNotExist() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.composers[?(@.name == 'Edvard Grieeeeeeg')]").doesNotExist())
.andExpect(jsonPath("$.composers[?(@.name == 'Robert Schuuuuuuman')]").doesNotExist())
.andExpect(jsonPath("$.composers[4]").doesNotExist())
@ -91,7 +91,7 @@ public class JsonPathRequestMatchersIntegrationTests { @@ -91,7 +91,7 @@ public class JsonPathRequestMatchersIntegrationTests {
@Test
public void value() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.composers[0].name").value("Johann Sebastian Bach"))
.andExpect(jsonPath("$.performers[1].name").value("Yehudi Menuhin"))
.andRespond(withSuccess());
@ -102,7 +102,7 @@ public class JsonPathRequestMatchersIntegrationTests { @@ -102,7 +102,7 @@ public class JsonPathRequestMatchersIntegrationTests {
@Test
public void hamcrestMatchers() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.composers[0].name").value(equalTo("Johann Sebastian Bach")))
.andExpect(jsonPath("$.performers[1].name").value(equalTo("Yehudi Menuhin")))
.andExpect(jsonPath("$.composers[0].name", startsWith("Johann")))
@ -121,7 +121,7 @@ public class JsonPathRequestMatchersIntegrationTests { @@ -121,7 +121,7 @@ public class JsonPathRequestMatchersIntegrationTests {
String performerName = "$.performers[%s].name";
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath(composerName, 0).value(startsWith("Johann")))
.andExpect(jsonPath(performerName, 0).value(endsWith("Ashkenazy")))
.andExpect(jsonPath(performerName, 1).value(containsString("di Me")))
@ -134,7 +134,7 @@ public class JsonPathRequestMatchersIntegrationTests { @@ -134,7 +134,7 @@ public class JsonPathRequestMatchersIntegrationTests {
@Test
public void isArray() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.composers").isArray())
.andRespond(withSuccess());
@ -144,7 +144,7 @@ public class JsonPathRequestMatchersIntegrationTests { @@ -144,7 +144,7 @@ public class JsonPathRequestMatchersIntegrationTests {
@Test
public void isString() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.composers[0].name").isString())
.andRespond(withSuccess());
@ -154,7 +154,7 @@ public class JsonPathRequestMatchersIntegrationTests { @@ -154,7 +154,7 @@ public class JsonPathRequestMatchersIntegrationTests {
@Test
public void isNumber() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.composers[0].someDouble").isNumber())
.andRespond(withSuccess());
@ -164,7 +164,7 @@ public class JsonPathRequestMatchersIntegrationTests { @@ -164,7 +164,7 @@ public class JsonPathRequestMatchersIntegrationTests {
@Test
public void isBoolean() throws Exception {
this.mockServer.expect(requestTo("/composers"))
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.composers[0].someBoolean").isBoolean())
.andRespond(withSuccess());

8
spring-test/src/test/java/org/springframework/test/web/reactive/server/HeaderAssertionTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -109,7 +109,7 @@ public class HeaderAssertionTests { @@ -109,7 +109,7 @@ public class HeaderAssertionTests {
@Test
public void valueMatches() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8"));
HeaderAssertions assertions = headerAssertions(headers);
// Success
@ -139,7 +139,7 @@ public class HeaderAssertionTests { @@ -139,7 +139,7 @@ public class HeaderAssertionTests {
@Test
public void exists() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.setContentType(MediaType.APPLICATION_JSON);
HeaderAssertions assertions = headerAssertions(headers);
// Success
@ -159,7 +159,7 @@ public class HeaderAssertionTests { @@ -159,7 +159,7 @@ public class HeaderAssertionTests {
@Test
public void doesNotExist() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8"));
HeaderAssertions assertions = headerAssertions(headers);
// Success

4
spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ErrorTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 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.
@ -62,7 +62,7 @@ public class ErrorTests { @@ -62,7 +62,7 @@ public class ErrorTests {
public void badRequestBeforeRequestBodyConsumed() {
EntityExchangeResult<Void> result = this.client.post()
.uri("/post")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON)
.syncBody(new Person("Dan"))
.exchange()
.expectStatus().isBadRequest()

10
spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/JsonContentTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -48,7 +48,7 @@ public class JsonContentTests { @@ -48,7 +48,7 @@ public class JsonContentTests {
@Test
public void jsonContent() {
this.client.get().uri("/persons")
.accept(MediaType.APPLICATION_JSON_UTF8)
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBody().json("[{\"name\":\"Jane\"},{\"name\":\"Jason\"},{\"name\":\"John\"}]");
@ -57,7 +57,7 @@ public class JsonContentTests { @@ -57,7 +57,7 @@ public class JsonContentTests {
@Test
public void jsonPathIsEqualTo() {
this.client.get().uri("/persons")
.accept(MediaType.APPLICATION_JSON_UTF8)
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBody()
@ -69,7 +69,7 @@ public class JsonContentTests { @@ -69,7 +69,7 @@ public class JsonContentTests {
@Test
public void jsonPathMatches() {
this.client.get().uri("/persons/John")
.accept(MediaType.APPLICATION_JSON_UTF8)
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBody()
@ -79,7 +79,7 @@ public class JsonContentTests { @@ -79,7 +79,7 @@ public class JsonContentTests {
@Test
public void postJsonContent() {
this.client.post().uri("/persons")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON)
.syncBody("{\"name\":\"John\"}")
.exchange()
.expectStatus().isCreated()

10
spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java

@ -63,7 +63,7 @@ public class ResponseEntityTests { @@ -63,7 +63,7 @@ public class ResponseEntityTests {
this.client.get().uri("/John")
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody(Person.class).isEqualTo(new Person("John"));
}
@ -72,7 +72,7 @@ public class ResponseEntityTests { @@ -72,7 +72,7 @@ public class ResponseEntityTests {
this.client.get().uri("/John")
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody(Person.class).value(Person::getName, startsWith("Joh"));
}
@ -81,7 +81,7 @@ public class ResponseEntityTests { @@ -81,7 +81,7 @@ public class ResponseEntityTests {
this.client.get().uri("/John")
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody(Person.class)
.consumeWith(result -> assertEquals(new Person("John"), result.getResponseBody()));
}
@ -95,7 +95,7 @@ public class ResponseEntityTests { @@ -95,7 +95,7 @@ public class ResponseEntityTests {
this.client.get()
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBodyList(Person.class).isEqualTo(expected);
}
@ -105,7 +105,7 @@ public class ResponseEntityTests { @@ -105,7 +105,7 @@ public class ResponseEntityTests {
this.client.get()
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBodyList(Person.class).value(people -> {
MatcherAssert.assertThat(people, hasItem(new Person("Jason")));
});

18
spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2019 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.
@ -70,7 +70,7 @@ public class AsyncTests { @@ -70,7 +70,7 @@ public class AsyncTests {
this.mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"));
}
@ -98,7 +98,7 @@ public class AsyncTests { @@ -98,7 +98,7 @@ public class AsyncTests {
.andExpect(request().asyncStarted())
.andDo(MvcResult::getAsyncResult)
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.5}"));
}
@ -112,7 +112,7 @@ public class AsyncTests { @@ -112,7 +112,7 @@ public class AsyncTests {
this.mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"));
}
@ -125,7 +125,7 @@ public class AsyncTests { @@ -125,7 +125,7 @@ public class AsyncTests {
this.mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"));
}
@ -150,7 +150,7 @@ public class AsyncTests { @@ -150,7 +150,7 @@ public class AsyncTests {
this.mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"));
}
@ -162,7 +162,7 @@ public class AsyncTests { @@ -162,7 +162,7 @@ public class AsyncTests {
this.mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"));
}
@ -183,7 +183,7 @@ public class AsyncTests { @@ -183,7 +183,7 @@ public class AsyncTests {
this.mockMvc.perform(asyncDispatch(mvcResult))
.andDo(print(writer))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"));
assertTrue(writer.toString().contains("Async started = false"));
@ -224,7 +224,7 @@ public class AsyncTests { @@ -224,7 +224,7 @@ public class AsyncTests {
@RequestMapping(params = "streamingJson")
public ResponseEntity<StreamingResponseBody> getStreamingJson() {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON_UTF8)
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON)
.body(os -> os.write("{\"name\":\"Joe\",\"someDouble\":0.5}".getBytes(StandardCharsets.UTF_8)));
}

4
spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/RequestParameterTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2019 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.
@ -41,7 +41,7 @@ public class RequestParameterTests { @@ -41,7 +41,7 @@ public class RequestParameterTests {
standaloneSetup(new PersonController()).build()
.perform(get("/search?name=George").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.name").value("George"));
}

2
spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/ResponseBodyTests.java

@ -41,7 +41,7 @@ public class ResponseBodyTests { @@ -41,7 +41,7 @@ public class ResponseBodyTests {
standaloneSetup(new PersonController()).build()
.perform(get("/person/Lee").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.name").value("Lee"));
}

4
spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/JsonPathAssertionTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2019 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.
@ -51,7 +51,7 @@ public class JsonPathAssertionTests { @@ -51,7 +51,7 @@ public class JsonPathAssertionTests {
this.mockMvc = standaloneSetup(new MusicController())
.defaultRequest(get("/").accept(MediaType.APPLICATION_JSON))
.alwaysExpect(status().isOk())
.alwaysExpect(content().contentType("application/json;charset=UTF-8"))
.alwaysExpect(content().contentType("application/json"))
.build();
}

6
spring-test/src/test/kotlin/org/springframework/test/web/servlet/MockMvcExtensionsTests.kt

@ -51,7 +51,7 @@ class MockMvcExtensionsTests { @@ -51,7 +51,7 @@ class MockMvcExtensionsTests {
principal = Principal { "foo" }
}.andExpect {
status { isOk }
content { contentType(APPLICATION_JSON_UTF8) }
content { contentType(APPLICATION_JSON) }
jsonPath("$.name") { value("Lee") }
content { json("""{"someBoolean": false}""", false) }
}.andDo {
@ -89,14 +89,14 @@ class MockMvcExtensionsTests { @@ -89,14 +89,14 @@ class MockMvcExtensionsTests {
fun get() {
mockMvc.get("/person/{name}", "Lee") {
secure = true
accept = APPLICATION_JSON_UTF8
accept = APPLICATION_JSON
headers {
contentLanguage = Locale.FRANCE
}
principal = Principal { "foo" }
}.andExpect {
status { isOk }
content { contentType(APPLICATION_JSON_UTF8) }
content { contentType(APPLICATION_JSON) }
jsonPath("$.name") { value("Lee") }
content { json("""{"someBoolean": false}""", false) }
}.andDo {

38
spring-web/src/main/java/org/springframework/http/MediaType.java

@ -48,6 +48,7 @@ import org.springframework.util.StringUtils; @@ -48,6 +48,7 @@ import org.springframework.util.StringUtils;
* @see <a href="https://tools.ietf.org/html/rfc7231#section-3.1.1.1">
* HTTP 1.1: Semantics and Content, section 3.1.1.1</a>
*/
@SuppressWarnings("deprecation")
public class MediaType extends MimeType implements Serializable {
private static final long serialVersionUID = 2069937152339670231L;
@ -84,7 +85,6 @@ public class MediaType extends MimeType implements Serializable { @@ -84,7 +85,6 @@ public class MediaType extends MimeType implements Serializable {
/**
* Public constant media type for {@code application/json}.
* @see #APPLICATION_JSON_UTF8
*/
public static final MediaType APPLICATION_JSON;
@ -96,24 +96,24 @@ public class MediaType extends MimeType implements Serializable { @@ -96,24 +96,24 @@ public class MediaType extends MimeType implements Serializable {
/**
* Public constant media type for {@code application/json;charset=UTF-8}.
*
* <p>This {@link MediaType#APPLICATION_JSON} variant should be used to set JSON
* content type because while
* <a href="https://tools.ietf.org/html/rfc7159#section-11">RFC7159</a>
* clearly states that "no charset parameter is defined for this registration", some
* browsers require it for interpreting correctly UTF-8 special characters.
* @deprecated Deprecated as of Spring Framework 5.2 in favor of {@link #APPLICATION_JSON}
* since major browsers like Chrome
* <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=438464">
* now comply with the specification</a> and interpret correctly UTF-8 special
* characters without requiring a {@code charset=UTF-8} parameter.
*/
@Deprecated
public static final MediaType APPLICATION_JSON_UTF8;
/**
* A String equivalent of {@link MediaType#APPLICATION_JSON_UTF8}.
*
* <p>This {@link MediaType#APPLICATION_JSON_VALUE} variant should be used to set JSON
* content type because while
* <a href="https://tools.ietf.org/html/rfc7159#section-11">RFC7159</a>
* clearly states that "no charset parameter is defined for this registration", some
* browsers require it for interpreting correctly UTF-8 special characters.
* @deprecated Deprecated as of Spring Framework 5.2 in favor of {@link #APPLICATION_JSON_VALUE}
* since major browsers like Chrome
* <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=438464">
* now comply with the specification</a> and interpret correctly UTF-8 special
* characters without requiring a {@code charset=UTF-8} parameter.
*/
@Deprecated
public static final String APPLICATION_JSON_UTF8_VALUE = "application/json;charset=UTF-8";
/**
@ -157,13 +157,25 @@ public class MediaType extends MimeType implements Serializable { @@ -157,13 +157,25 @@ public class MediaType extends MimeType implements Serializable {
* @since 5.0
* @see <a href="https://tools.ietf.org/html/rfc7807#section-6.1">
* Problem Details for HTTP APIs, 6.1. application/problem+json</a>
* @deprecated Deprecated as of Spring Framework 5.2 in favor of {@link #APPLICATION_PROBLEM_JSON}
* since major browsers like Chrome
* <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=438464">
* now comply with the specification</a> and interpret correctly UTF-8 special
* characters without requiring a {@code charset=UTF-8} parameter.
*/
@Deprecated
public static final MediaType APPLICATION_PROBLEM_JSON_UTF8;
/**
* A String equivalent of {@link MediaType#APPLICATION_PROBLEM_JSON_UTF8}.
* @since 5.0
* @deprecated Deprecated as of Spring Framework 5.2 in favor of {@link #APPLICATION_PROBLEM_JSON_VALUE}
* since major browsers like Chrome
* <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=438464">
* now comply with the specification</a> and interpret correctly UTF-8 special
* characters without requiring a {@code charset=UTF-8} parameter.
*/
@Deprecated
public static final String APPLICATION_PROBLEM_JSON_UTF8_VALUE = "application/problem+json;charset=UTF-8";
/**

5
spring-web/src/main/java/org/springframework/http/codec/json/Jackson2CodecSupport.java

@ -18,7 +18,6 @@ package org.springframework.http.codec.json; @@ -18,7 +18,6 @@ package org.springframework.http.codec.json;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -61,8 +60,8 @@ public abstract class Jackson2CodecSupport { @@ -61,8 +60,8 @@ public abstract class Jackson2CodecSupport {
private static final List<MimeType> DEFAULT_MIME_TYPES = Collections.unmodifiableList(
Arrays.asList(
new MimeType("application", "json", StandardCharsets.UTF_8),
new MimeType("application", "*+json", StandardCharsets.UTF_8)));
new MimeType("application", "json"),
new MimeType("application", "*+json")));
protected final Log logger = HttpLogging.forLogName(getClass());

6
spring-web/src/main/java/org/springframework/http/codec/json/Jackson2SmileDecoder.java

@ -16,8 +16,6 @@ @@ -16,8 +16,6 @@
package org.springframework.http.codec.json;
import java.nio.charset.StandardCharsets;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.smile.SmileFactory;
@ -37,8 +35,8 @@ import org.springframework.util.MimeType; @@ -37,8 +35,8 @@ import org.springframework.util.MimeType;
public class Jackson2SmileDecoder extends AbstractJackson2Decoder {
private static final MimeType[] DEFAULT_SMILE_MIME_TYPES = new MimeType[] {
new MimeType("application", "x-jackson-smile", StandardCharsets.UTF_8),
new MimeType("application", "*+x-jackson-smile", StandardCharsets.UTF_8)};
new MimeType("application", "x-jackson-smile"),
new MimeType("application", "*+x-jackson-smile")};
public Jackson2SmileDecoder() {

7
spring-web/src/main/java/org/springframework/http/codec/json/Jackson2SmileEncoder.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
package org.springframework.http.codec.json;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
@ -41,8 +40,8 @@ import org.springframework.util.MimeType; @@ -41,8 +40,8 @@ import org.springframework.util.MimeType;
public class Jackson2SmileEncoder extends AbstractJackson2Encoder {
private static final MimeType[] DEFAULT_SMILE_MIME_TYPES = new MimeType[] {
new MimeType("application", "x-jackson-smile", StandardCharsets.UTF_8),
new MimeType("application", "*+x-jackson-smile", StandardCharsets.UTF_8)};
new MimeType("application", "x-jackson-smile"),
new MimeType("application", "*+x-jackson-smile")};
public Jackson2SmileEncoder() {

12
spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -19,7 +19,6 @@ package org.springframework.http.converter.json; @@ -19,7 +19,6 @@ package org.springframework.http.converter.json;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicReference;
@ -49,6 +48,7 @@ import org.springframework.http.converter.HttpMessageConversionException; @@ -49,6 +48,7 @@ import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.TypeUtils;
@ -72,7 +72,9 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener @@ -72,7 +72,9 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
/**
* The default charset used by the converter.
*/
public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
@Nullable
@Deprecated
public static final Charset DEFAULT_CHARSET = null;
protected ObjectMapper objectMapper;
@ -86,7 +88,6 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener @@ -86,7 +88,6 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
protected AbstractJackson2HttpMessageConverter(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
setDefaultCharset(DEFAULT_CHARSET);
DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter();
prettyPrinter.indentObjectsWith(new DefaultIndenter(" ", "\ndata:"));
this.ssePrettyPrinter = prettyPrinter;
@ -250,6 +251,9 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener @@ -250,6 +251,9 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
protected void writeInternal(Object object, @Nullable Type type, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
if (getDefaultCharset() == null && outputMessage instanceof ServletServerHttpResponse) {
((ServletServerHttpResponse)outputMessage).getServletResponse().setCharacterEncoding("UTF-8");
}
MediaType contentType = outputMessage.getHeaders().getContentType();
JsonEncoding encoding = getJsonEncoding(contentType);
JsonGenerator generator = this.objectMapper.getFactory().createGenerator(outputMessage.getBody(), encoding);

10
spring-web/src/main/java/org/springframework/http/converter/xml/MappingJackson2XmlHttpMessageConverter.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 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.
@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.http.converter.xml;
import java.nio.charset.StandardCharsets;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
@ -57,9 +59,9 @@ public class MappingJackson2XmlHttpMessageConverter extends AbstractJackson2Http @@ -57,9 +59,9 @@ public class MappingJackson2XmlHttpMessageConverter extends AbstractJackson2Http
* @see Jackson2ObjectMapperBuilder#xml()
*/
public MappingJackson2XmlHttpMessageConverter(ObjectMapper objectMapper) {
super(objectMapper, new MediaType("application", "xml"),
new MediaType("text", "xml"),
new MediaType("application", "*+xml"));
super(objectMapper, new MediaType("application", "xml", StandardCharsets.UTF_8),
new MediaType("text", "xml", StandardCharsets.UTF_8),
new MediaType("application", "*+xml", StandardCharsets.UTF_8));
Assert.isInstanceOf(XmlMapper.class, objectMapper, "XmlMapper required");
}

1
spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java

@ -72,7 +72,6 @@ public class Jackson2JsonDecoderTests extends AbstractDecoderTestCase<Jackson2Js @@ -72,7 +72,6 @@ public class Jackson2JsonDecoderTests extends AbstractDecoderTestCase<Jackson2Js
@Test
public void canDecode() {
assertTrue(decoder.canDecode(forClass(Pojo.class), APPLICATION_JSON));
assertTrue(decoder.canDecode(forClass(Pojo.class), APPLICATION_JSON_UTF8));
assertTrue(decoder.canDecode(forClass(Pojo.class), APPLICATION_STREAM_JSON));
assertTrue(decoder.canDecode(forClass(Pojo.class), null));

4
spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -44,7 +44,6 @@ import org.springframework.util.MimeTypeUtils; @@ -44,7 +44,6 @@ import org.springframework.util.MimeTypeUtils;
import static java.util.Collections.singletonMap;
import static org.junit.Assert.*;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM;
import static org.springframework.http.MediaType.APPLICATION_STREAM_JSON;
import static org.springframework.http.MediaType.APPLICATION_XML;
@ -67,7 +66,6 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTestCase<Jackson2Js @@ -67,7 +66,6 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTestCase<Jackson2Js
public void canEncode() {
ResolvableType pojoType = ResolvableType.forClass(Pojo.class);
assertTrue(this.encoder.canEncode(pojoType, APPLICATION_JSON));
assertTrue(this.encoder.canEncode(pojoType, APPLICATION_JSON_UTF8));
assertTrue(this.encoder.canEncode(pojoType, APPLICATION_STREAM_JSON));
assertTrue(this.encoder.canEncode(pojoType, null));

4
spring-web/src/test/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriterTests.java

@ -102,7 +102,7 @@ public class MultipartHttpMessageWriterTests extends AbstractLeakCheckingTestCas @@ -102,7 +102,7 @@ public class MultipartHttpMessageWriterTests extends AbstractLeakCheckingTestCas
bodyBuilder.part("name 2", "value 2+2");
bodyBuilder.part("logo", logo);
bodyBuilder.part("utf8", utf8);
bodyBuilder.part("json", new Foo("bar"), MediaType.APPLICATION_JSON_UTF8);
bodyBuilder.part("json", new Foo("bar"), MediaType.APPLICATION_JSON);
bodyBuilder.asyncPart("publisher", publisher, String.class);
Mono<MultiValueMap<String, HttpEntity<?>>> result = Mono.just(bodyBuilder.build());
@ -144,7 +144,7 @@ public class MultipartHttpMessageWriterTests extends AbstractLeakCheckingTestCas @@ -144,7 +144,7 @@ public class MultipartHttpMessageWriterTests extends AbstractLeakCheckingTestCas
part = requestParts.getFirst("json");
assertEquals("json", part.name());
assertEquals(MediaType.APPLICATION_JSON_UTF8, part.headers().getContentType());
assertEquals(MediaType.APPLICATION_JSON, part.headers().getContentType());
String value = StringDecoder.textPlainOnly(false).decodeToMono(part.content(),
ResolvableType.forClass(String.class), MediaType.TEXT_PLAIN,

6
spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -139,7 +139,7 @@ public class MappingJackson2HttpMessageConverterTests { @@ -139,7 +139,7 @@ public class MappingJackson2HttpMessageConverterTests {
assertTrue(result.contains("\"array\":[\"Foo\",\"Bar\"]"));
assertTrue(result.contains("\"bool\":true"));
assertTrue(result.contains("\"bytes\":\"AQI=\""));
assertEquals("Invalid content-type", new MediaType("application", "json", StandardCharsets.UTF_8),
assertEquals("Invalid content-type", MediaType.APPLICATION_JSON,
outputMessage.getHeaders().getContentType());
}
@ -161,7 +161,7 @@ public class MappingJackson2HttpMessageConverterTests { @@ -161,7 +161,7 @@ public class MappingJackson2HttpMessageConverterTests {
assertTrue(result.contains("\"array\":[\"Foo\",\"Bar\"]"));
assertTrue(result.contains("\"bool\":true"));
assertTrue(result.contains("\"bytes\":\"AQI=\""));
assertEquals("Invalid content-type", new MediaType("application", "json", StandardCharsets.UTF_8),
assertEquals("Invalid content-type", MediaType.APPLICATION_JSON,
outputMessage.getHeaders().getContentType());
}

4
spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverterTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -143,7 +143,7 @@ public class ProtobufHttpMessageConverterTests { @@ -143,7 +143,7 @@ public class ProtobufHttpMessageConverterTests {
new ProtobufHttpMessageConverter.ProtobufJavaUtilSupport(null, null),
this.extensionRegistry);
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
MediaType contentType = MediaType.APPLICATION_JSON_UTF8;
MediaType contentType = MediaType.APPLICATION_JSON;
this.converter.write(this.testMsg, contentType, outputMessage);
assertEquals(contentType, outputMessage.getHeaders().getContentType());

5
spring-web/src/test/java/org/springframework/http/converter/smile/MappingJackson2SmileHttpMessageConverterTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2019 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.
@ -17,7 +17,6 @@ @@ -17,7 +17,6 @@
package org.springframework.http.converter.smile;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.smile.SmileFactory;
@ -90,7 +89,7 @@ public class MappingJackson2SmileHttpMessageConverterTests { @@ -90,7 +89,7 @@ public class MappingJackson2SmileHttpMessageConverterTests {
body.setBytes(new byte[]{0x1, 0x2});
converter.write(body, null, outputMessage);
assertArrayEquals(mapper.writeValueAsBytes(body), outputMessage.getBodyAsBytes());
assertEquals("Invalid content-type", new MediaType("application", "x-jackson-smile", StandardCharsets.UTF_8),
assertEquals("Invalid content-type", new MediaType("application", "x-jackson-smile"),
outputMessage.getHeaders().getContentType());
}

4
spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensions.kt

@ -48,11 +48,11 @@ inline fun <reified T : Any> ServerResponse.BodyBuilder.bodyToServerSentEvents(p @@ -48,11 +48,11 @@ inline fun <reified T : Any> ServerResponse.BodyBuilder.bodyToServerSentEvents(p
contentType(MediaType.TEXT_EVENT_STREAM).body(publisher, object : ParameterizedTypeReference<T>() {})
/**
* Shortcut for setting [MediaType.APPLICATION_JSON_UTF8] `Content-Type` header.
* Shortcut for setting [MediaType.APPLICATION_JSON] `Content-Type` header.
* @author Sebastien Deleuze
* @since 5.1
*/
fun ServerResponse.BodyBuilder.json() = contentType(MediaType.APPLICATION_JSON_UTF8)
fun ServerResponse.BodyBuilder.json() = contentType(MediaType.APPLICATION_JSON)
/**
* Shortcut for setting [MediaType.APPLICATION_XML] `Content-Type` header.

4
spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxConfigurationSupportTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -267,7 +267,7 @@ public class WebFluxConfigurationSupportTests { @@ -267,7 +267,7 @@ public class WebFluxConfigurationSupportTests {
List<View> views = handler.getDefaultViews();
assertEquals(1, views.size());
MimeType type = MimeTypeUtils.parseMimeType("application/json;charset=UTF-8");
MimeType type = MimeTypeUtils.parseMimeType("application/json");
assertEquals(type, views.get(0).getSupportedMediaTypes().get(0));
}

8
spring-webflux/src/test/java/org/springframework/web/reactive/result/HandlerResultHandlerTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 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.
@ -33,7 +33,7 @@ import org.springframework.web.reactive.accept.RequestedContentTypeResolver; @@ -33,7 +33,7 @@ import org.springframework.web.reactive.accept.RequestedContentTypeResolver;
import static org.junit.Assert.assertEquals;
import static org.springframework.http.MediaType.ALL;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM;
import static org.springframework.http.MediaType.IMAGE_GIF;
import static org.springframework.http.MediaType.IMAGE_JPEG;
@ -76,10 +76,10 @@ public class HandlerResultHandlerTests { @@ -76,10 +76,10 @@ public class HandlerResultHandlerTests {
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/path")
.header("Accept", "text/plain; q=0.5, application/json"));
List<MediaType> mediaTypes = Arrays.asList(TEXT_PLAIN, APPLICATION_JSON_UTF8);
List<MediaType> mediaTypes = Arrays.asList(TEXT_PLAIN, APPLICATION_JSON);
MediaType actual = this.resultHandler.selectMediaType(exchange, () -> mediaTypes);
assertEquals(APPLICATION_JSON_UTF8, actual);
assertEquals(APPLICATION_JSON, actual);
}
@Test

20
spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/JacksonHintsIntegrationTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 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.
@ -56,39 +56,39 @@ public class JacksonHintsIntegrationTests extends AbstractRequestMappingIntegrat @@ -56,39 +56,39 @@ public class JacksonHintsIntegrationTests extends AbstractRequestMappingIntegrat
@Test
public void jsonViewResponse() throws Exception {
String expected = "{\"withView1\":\"with\"}";
assertEquals(expected, performGet("/response/raw", MediaType.APPLICATION_JSON_UTF8, String.class).getBody());
assertEquals(expected, performGet("/response/raw", MediaType.APPLICATION_JSON, String.class).getBody());
}
@Test
public void jsonViewWithMonoResponse() throws Exception {
String expected = "{\"withView1\":\"with\"}";
assertEquals(expected, performGet("/response/mono", MediaType.APPLICATION_JSON_UTF8, String.class).getBody());
assertEquals(expected, performGet("/response/mono", MediaType.APPLICATION_JSON, String.class).getBody());
}
@Test // SPR-16098
public void jsonViewWithMonoResponseEntity() throws Exception {
String expected = "{\"withView1\":\"with\"}";
assertEquals(expected, performGet("/response/entity", MediaType.APPLICATION_JSON_UTF8, String.class).getBody());
assertEquals(expected, performGet("/response/entity", MediaType.APPLICATION_JSON, String.class).getBody());
}
@Test
public void jsonViewWithFluxResponse() throws Exception {
String expected = "[{\"withView1\":\"with\"},{\"withView1\":\"with\"}]";
assertEquals(expected, performGet("/response/flux", MediaType.APPLICATION_JSON_UTF8, String.class).getBody());
assertEquals(expected, performGet("/response/flux", MediaType.APPLICATION_JSON, String.class).getBody());
}
@Test
public void jsonViewWithRequest() throws Exception {
String expected = "{\"withView1\":\"with\",\"withView2\":null,\"withoutView\":null}";
assertEquals(expected, performPost("/request/raw", MediaType.APPLICATION_JSON,
new JacksonViewBean("with", "with", "without"), MediaType.APPLICATION_JSON_UTF8, String.class).getBody());
new JacksonViewBean("with", "with", "without"), MediaType.APPLICATION_JSON, String.class).getBody());
}
@Test
public void jsonViewWithMonoRequest() throws Exception {
String expected = "{\"withView1\":\"with\",\"withView2\":null,\"withoutView\":null}";
assertEquals(expected, performPost("/request/mono", MediaType.APPLICATION_JSON,
new JacksonViewBean("with", "with", "without"), MediaType.APPLICATION_JSON_UTF8, String.class).getBody());
new JacksonViewBean("with", "with", "without"), MediaType.APPLICATION_JSON, String.class).getBody());
}
@Test // SPR-16098
@ -96,7 +96,7 @@ public class JacksonHintsIntegrationTests extends AbstractRequestMappingIntegrat @@ -96,7 +96,7 @@ public class JacksonHintsIntegrationTests extends AbstractRequestMappingIntegrat
String expected = "{\"withView1\":\"with\",\"withView2\":null,\"withoutView\":null}";
assertEquals(expected, performPost("/request/entity/mono", MediaType.APPLICATION_JSON,
new JacksonViewBean("with", "with", "without"),
MediaType.APPLICATION_JSON_UTF8, String.class).getBody());
MediaType.APPLICATION_JSON, String.class).getBody());
}
@Test // SPR-16098
@ -107,7 +107,7 @@ public class JacksonHintsIntegrationTests extends AbstractRequestMappingIntegrat @@ -107,7 +107,7 @@ public class JacksonHintsIntegrationTests extends AbstractRequestMappingIntegrat
assertEquals(expected, performPost("/request/entity/flux", MediaType.APPLICATION_JSON,
Arrays.asList(new JacksonViewBean("with", "with", "without"),
new JacksonViewBean("with", "with", "without")),
MediaType.APPLICATION_JSON_UTF8, String.class).getBody());
MediaType.APPLICATION_JSON, String.class).getBody());
}
@Test
@ -119,7 +119,7 @@ public class JacksonHintsIntegrationTests extends AbstractRequestMappingIntegrat @@ -119,7 +119,7 @@ public class JacksonHintsIntegrationTests extends AbstractRequestMappingIntegrat
new JacksonViewBean("with", "with", "without"),
new JacksonViewBean("with", "with", "without"));
assertEquals(expected, performPost("/request/flux", MediaType.APPLICATION_JSON, beans,
MediaType.APPLICATION_JSON_UTF8, String.class).getBody());
MediaType.APPLICATION_JSON, String.class).getBody());
}

12
spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MessageWriterResultHandlerTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 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.
@ -41,6 +41,7 @@ import org.springframework.core.codec.ByteBufferEncoder; @@ -41,6 +41,7 @@ import org.springframework.core.codec.ByteBufferEncoder;
import org.springframework.core.codec.CharSequenceEncoder;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.codec.EncoderHttpMessageWriter;
import org.springframework.http.codec.HttpMessageWriter;
import org.springframework.http.codec.ResourceHttpMessageWriter;
@ -56,7 +57,6 @@ import static org.junit.Assert.assertEquals; @@ -56,7 +57,6 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.springframework.core.io.buffer.support.DataBufferTestUtils.dumpString;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
import static org.springframework.web.method.ResolvableMethod.on;
import static org.springframework.web.reactive.HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE;
@ -108,7 +108,7 @@ public class MessageWriterResultHandlerTests { @@ -108,7 +108,7 @@ public class MessageWriterResultHandlerTests {
MethodParameter type = on(TestController.class).resolveReturnType(String.class);
this.resultHandler.writeBody(body, type, this.exchange).block(Duration.ofSeconds(5));
assertEquals(APPLICATION_JSON_UTF8, this.exchange.getResponse().getHeaders().getContentType());
assertEquals(MediaType.parseMediaType("application/json;charset=UTF-8"), this.exchange.getResponse().getHeaders().getContentType());
}
@Test
@ -155,7 +155,7 @@ public class MessageWriterResultHandlerTests { @@ -155,7 +155,7 @@ public class MessageWriterResultHandlerTests {
List<ParentClass> body = Arrays.asList(new Foo("foo"), new Bar("bar"));
this.resultHandler.writeBody(body, returnType, this.exchange).block(Duration.ofSeconds(5));
assertEquals(APPLICATION_JSON_UTF8, this.exchange.getResponse().getHeaders().getContentType());
assertEquals(APPLICATION_JSON, this.exchange.getResponse().getHeaders().getContentType());
assertResponseBody("[{\"type\":\"foo\",\"parentProperty\":\"foo\"}," +
"{\"type\":\"bar\",\"parentProperty\":\"bar\"}]");
}
@ -166,7 +166,7 @@ public class MessageWriterResultHandlerTests { @@ -166,7 +166,7 @@ public class MessageWriterResultHandlerTests {
MethodParameter type = on(TestController.class).resolveReturnType(Identifiable.class);
this.resultHandler.writeBody(body, type, this.exchange).block(Duration.ofSeconds(5));
assertEquals(APPLICATION_JSON_UTF8, this.exchange.getResponse().getHeaders().getContentType());
assertEquals(APPLICATION_JSON, this.exchange.getResponse().getHeaders().getContentType());
assertResponseBody("{\"id\":123,\"name\":\"foo\"}");
}
@ -178,7 +178,7 @@ public class MessageWriterResultHandlerTests { @@ -178,7 +178,7 @@ public class MessageWriterResultHandlerTests {
List<SimpleBean> body = Arrays.asList(new SimpleBean(123L, "foo"), new SimpleBean(456L, "bar"));
this.resultHandler.writeBody(body, returnType, this.exchange).block(Duration.ofSeconds(5));
assertEquals(APPLICATION_JSON_UTF8, this.exchange.getResponse().getHeaders().getContentType());
assertEquals(APPLICATION_JSON, this.exchange.getResponse().getHeaders().getContentType());
assertResponseBody("[{\"id\":123,\"name\":\"foo\"},{\"id\":456,\"name\":\"bar\"}]");
}

4
spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingExceptionHandlingIntegrationTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -99,7 +99,7 @@ public class RequestMappingExceptionHandlingIntegrationTests extends AbstractReq @@ -99,7 +99,7 @@ public class RequestMappingExceptionHandlingIntegrationTests extends AbstractReq
}
catch (HttpStatusCodeException ex) {
assertEquals(500, ex.getRawStatusCode());
assertEquals("application/problem+json;charset=UTF-8", ex.getResponseHeaders().getContentType().toString());
assertEquals("application/problem+json", ex.getResponseHeaders().getContentType().toString());
assertEquals("{\"reason\":\"error\"}", ex.getResponseBodyAsString());
}
}

6
spring-webflux/src/test/java/org/springframework/web/reactive/result/view/HttpMessageWriterViewTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 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.
@ -59,8 +59,8 @@ public class HttpMessageWriterViewTests { @@ -59,8 +59,8 @@ public class HttpMessageWriterViewTests {
@Test
public void supportedMediaTypes() throws Exception {
assertEquals(Arrays.asList(
MediaType.parseMediaType("application/json;charset=UTF-8"),
MediaType.parseMediaType("application/*+json;charset=UTF-8")),
MediaType.APPLICATION_JSON,
MediaType.parseMediaType("application/*+json")),
this.view.getSupportedMediaTypes());
}

4
spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensionsTests.kt

@ -26,9 +26,7 @@ import org.junit.Assert.assertEquals @@ -26,9 +26,7 @@ import org.junit.Assert.assertEquals
import org.junit.Test
import org.reactivestreams.Publisher
import org.springframework.core.ParameterizedTypeReference
import org.springframework.http.MediaType
import org.springframework.http.MediaType.*
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
/**
@ -58,7 +56,7 @@ class ServerResponseExtensionsTests { @@ -58,7 +56,7 @@ class ServerResponseExtensionsTests {
@Test
fun `BodyBuilder#json`() {
bodyBuilder.json()
verify { bodyBuilder.contentType(APPLICATION_JSON_UTF8) }
verify { bodyBuilder.contentType(APPLICATION_JSON) }
}
@Test

2
spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java

@ -692,7 +692,7 @@ public class RequestResponseBodyMethodProcessorTests { @@ -692,7 +692,7 @@ public class RequestResponseBodyMethodProcessorTests {
@Test // SPR-14520
public void resolveArgumentTypeVariableWithGenericInterface() throws Exception {
this.servletRequest.setContent("\"foo\"".getBytes("UTF-8"));
this.servletRequest.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
this.servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
Method method = MyControllerImplementingInterface.class.getMethod("handle", Object.class);
HandlerMethod handlerMethod = new HandlerMethod(new MyControllerImplementingInterface(), method);

2
spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletAnnotationControllerHandlerMethodTests.java

@ -1205,7 +1205,7 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl @@ -1205,7 +1205,7 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
response = new MockHttpServletResponse();
getServlet().service(request, response);
assertEquals(500, response.getStatus());
assertEquals("application/problem+json;charset=UTF-8", response.getContentType());
assertEquals("application/problem+json", response.getContentType());
assertEquals("{\"reason\":\"error\"}", response.getContentAsString());
}

4
src/docs/asciidoc/languages/kotlin.adoc

@ -350,7 +350,7 @@ mockMvc.get("/person/{name}", "Lee") { @@ -350,7 +350,7 @@ mockMvc.get("/person/{name}", "Lee") {
principal = Principal { "foo" }
}.andExpect {
status { isOk }
content { contentType(APPLICATION_JSON_UTF8) }
content { contentType(APPLICATION_JSON) }
jsonPath("$.name") { value("Lee") }
content { json("""{"someBoolean": false}""", false) }
}.andDo {
@ -567,7 +567,7 @@ class UserHandler(builder: WebClient.Builder) { @@ -567,7 +567,7 @@ class UserHandler(builder: WebClient.Builder) {
client.get().uri("...").awaitExchange().awaitBody<User>()))
suspend fun listApi(request: ServerRequest): ServerResponse =
ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8).bodyAndAwait(
ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).bodyAndAwait(
client.get().uri("...").awaitExchange().awaitBody<User>())
}
----

4
src/docs/asciidoc/testing-webtestclient.adoc

@ -141,10 +141,10 @@ Typically, you start by asserting the response status and headers, as follows: @@ -141,10 +141,10 @@ Typically, you start by asserting the response status and headers, as follows:
[subs="verbatim,quotes"]
----
client.get().uri("/persons/1")
.accept(MediaType.APPLICATION_JSON_UTF8)
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
.expectHeader().contentType(MediaType.APPLICATION_JSON)
// ...
----

9
src/docs/asciidoc/web/webflux.adoc

@ -1342,7 +1342,7 @@ content types that a controller method produces, as the following example shows: @@ -1342,7 +1342,7 @@ content types that a controller method produces, as the following example shows:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@GetMapping(path = "/pets/{petId}", produces = "application/json;charset=UTF-8")
@GetMapping(path = "/pets/{petId}", produces = "application/json")
@ResponseBody
public Pet getPet(@PathVariable String petId) {
// ...
@ -1352,17 +1352,12 @@ content types that a controller method produces, as the following example shows: @@ -1352,17 +1352,12 @@ content types that a controller method produces, as the following example shows:
The media type can specify a character set. Negated expressions are supported -- for example,
`!text/plain` means any content type other than `text/plain`.
NOTE: For JSON content type, you should specify the UTF-8 `charset` even if
https://tools.ietf.org/html/rfc7159#section-11[RFC7159]
clearly states that "`no charset parameter is defined for this registration,`" because some
browsers require it to correctly interpret UTF-8 special characters.
You can declare a shared `produces` attribute at the class level. Unlike most other request
mapping attributes, however, when used at the class level, a method-level `produces` attribute
overrides rather than extend the class level declaration.
TIP: `MediaType` provides constants for commonly used media types -- e.g.
`APPLICATION_JSON_UTF8_VALUE`, `APPLICATION_XML_VALUE`.
`APPLICATION_JSON_VALUE`, `APPLICATION_XML_VALUE`.
[[webflux-ann-requestmapping-params-and-headers]]

9
src/docs/asciidoc/web/webmvc.adoc

@ -1504,7 +1504,7 @@ content types that a controller method produces, as the following example shows: @@ -1504,7 +1504,7 @@ content types that a controller method produces, as the following example shows:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@GetMapping(path = "/pets/{petId}", produces = "application/json;charset=UTF-8") <1>
@GetMapping(path = "/pets/{petId}", produces = "application/json") <1>
@ResponseBody
public Pet getPet(@PathVariable String petId) {
// ...
@ -1515,17 +1515,12 @@ content types that a controller method produces, as the following example shows: @@ -1515,17 +1515,12 @@ content types that a controller method produces, as the following example shows:
The media type can specify a character set. Negated expressions are supported -- for example,
`!text/plain` means any content type other than "text/plain".
NOTE: For the JSON content type, the UTF-8 charset should be specified even if
https://tools.ietf.org/html/rfc7159#section-11[RFC7159]
clearly states that "`no charset parameter is defined for this registration`", because some
browsers require it to correctly interpret UTF-8 special characters.
You can declare a shared `produces` attribute at the class level. Unlike most other
request-mapping attributes, however, when used at the class level, a method-level `produces` attribute
overrides rather than extends the class-level declaration.
TIP: `MediaType` provides constants for commonly used media types, such as
`APPLICATION_JSON_UTF8_VALUE` and `APPLICATION_XML_VALUE`.
`APPLICATION_JSON_VALUE` and `APPLICATION_XML_VALUE`.
[[mvc-ann-requestmapping-params-and-headers]]

Loading…
Cancel
Save