shardingsphere icon indicating copy to clipboard operation
shardingsphere copied to clipboard

shardingsphere-jdbc-5.5.0 causes spring boot to return JSON data as XML

Open Comven opened this issue 1 year ago • 7 comments

spring-boot: 2.7.18、3.2.4 shardingsphere-jdbc:5.5.0

The introduction of the 'jackson-dataformat-xml' component dependency in version 5.5 resulted in the JSON returned by the spring boot program being changed to XML format.

shardingsphere-jdbc-core-5.4.1 Return format is

[
    {
        "id": 1,
        "name": "ZhangSan",
        "address": "BeiJing",
        "addTime": "2024-05-11 10:05:10"
    }
]

shardingsphere-jdbc-5.5.0 Return format is

<List>
<item>
<id>1</id>
<name>ZhangSan</name>
<address>BeiJing</address>
<addTime>2024-05-11 09:48:56</addTime>
</item>
</List>

Comven avatar May 11 '24 02:05 Comven

  • Neither you nor #31067 provide unit tests, and the issue is clearly a spring boot configuration issue. The deeper question subject to a third party spring boot starter automatically configure class. I would encourage you to write unit tests first and send them to spring boot.

  • For https://github.com/spring-projects/spring-boot/issues/32494 and https://github.com/spring-projects/spring-boot/issues/32647 .

linghengqian avatar May 11 '24 04:05 linghengqian

Can shardingsphere-jdbc be made to not rely on the jackson-dataformat-xml component package, otherwise using the shardingsphere-jdbc-.5.5.0, the spring boot program will not be able to return JSON properly? Originally, our business program did not introduce this problematic jackson-dataformat-xml component package because shardingsphere jdbc automatically introduced this package, which caused this problem. @linghengqian

Comven avatar May 11 '24 06:05 Comven

  • @Comven Shardingsphere always needs a library for parsing xml files. In the past it was JAXB API, now it is jackson-dataformat-xml, and it can also be xstream in the future. The reason has been explained clearly in #29384 . Using jackson-dataformat-xml will allow shardingsphere to better protect against breaking changes in Spring Boot 3.x and GraalVM Native Image.
  • You must provide unit tests to prove why just introducing jackson-dataformat-xml will cause WebMVC or Webflux in Spring Boot to actually change the return value of the Controller. There have been 4 issues so far, and no one has provided a minimal unit test.
  • Prove it. I believe this is 100% a problem with Spring Boot or a third-party Spring Boot Stater, because there is no reason to change the configuration of Spring Boot by just introducing jackson-dataformat-xml, which is just an xml parsing library.

linghengqian avatar May 11 '24 06:05 linghengqian

I ran into the same problem and found others who ran into the same problem as follows: https://stackoverflow.com/questions/41036377/spring-mvc-changing-default-response-format-from-xml-to-json https://stackoverflow.com/questions/66752245/spring-5-jackson-dataformat-xml-forces-responsebody-with-xml https://stackoverflow.com/questions/57706610/how-to-set-default-messageconverter-to-json-with-jackson-dataformat-xml-added And a Chinese developer analyzed the reason: https://hafuhafu.com/archives/springboot-jackson-xml-result-json/

lazeyliu avatar May 11 '24 09:05 lazeyliu

@lazeyliu @Comven

  • I'm pretty sure this issue still lacks real unit testing. Although we can see many similar issues so far, including but not limited to,
    • https://stackoverflow.com/questions/66752245
    • https://stackoverflow.com/questions/57706610
    • https://stackoverflow.com/questions/41036377
    • https://hafuhafu.com/archives/springboot-jackson-xml-result-json/
    • https://github.com/spring-projects/spring-boot/issues/32494
    • https://github.com/spring-projects/spring-boot/issues/32647
    • #31067
  • So far, no issue has actually provided git with unit tests. The results I've seen from reasonable unit tests and https://github.com/spring-projects/spring-boot/issues/32494#issuecomment-1268851718 should be consistent.
With the expected xml dependency

	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml'

the following controller:

@RestController
public class JsonXmlController {
	@GetMapping("/book")
	public Book book() {
		return new Book("Intro to Spring Boot", "Spring team");
	}
	public record Book(String title, String author) {
	}
}

I'm getting the following behavior:

http localhost:8080/book -v
GET /book HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: localhost:8080
User-Agent: HTTPie/3.2.1



HTTP/1.1 200
Connection: keep-alive
Content-Type: application/json
Date: Wed, 05 Oct 2022 19:14:27 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked

{
    "author": "Spring team",
    "title": "Intro to Spring Boot"
}
  • I have every reason to believe that you should provide unit tests first, and unit tests are probably completely unrelated to shardingsphere.

linghengqian avatar May 11 '24 09:05 linghengqian

@lazeyliu @Comven

With the expected xml dependency

	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml'

the following controller:

@RestController
public class JsonXmlController {
	@GetMapping("/book")
	public Book book() {
		return new Book("Intro to Spring Boot", "Spring team");
	}
	public record Book(String title, String author) {
	}
}

I'm getting the following behavior:

http localhost:8080/book -v
GET /book HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: localhost:8080
User-Agent: HTTPie/3.2.1



HTTP/1.1 200
Connection: keep-alive
Content-Type: application/json
Date: Wed, 05 Oct 2022 19:14:27 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked

{
    "author": "Spring team",
    "title": "Intro to Spring Boot"
}
  • I have every reason to believe that you should provide unit tests first, and unit tests are probably completely unrelated to shardingsphere.

I have said earlier that this bug is due to jackson-dataformat-xml, but shardingsphere-5.5.0 uses the functionality of this component to cause such problems in programs that introduce shardingsphere-jdbc, which is relevant. That's why I said can you switch back to jaxb parsing xml instead of jackson-dataformat-xml, otherwise jackson-dataformat-xml has always had this problem without changing, Our projects using shardingsphere-jdbc-5.5.0 need to deal specifically with the issue of the response data being returned in xml。

The problem of replicating jackson-dataformat-xml is relatively easy。 spring-boot-2.7.18 or later,Introduce the following since coordinates

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <scope>provided</scope>
</dependency>

Write a piece of logic that returns JSON content, as shown in the following code image

Accessing this interface address directly in a browser yields the following results image

Comven avatar May 24 '24 01:05 Comven

  • @Comven So, this is actually an issue with Spring Framework's WebMVC. Even if jackson-dataformat-xml is not used and instead, xstream or another XML parsing library is utilized, the problem would still arise if one were to implement an AbstractGenericHttpMessageConverter akin to MappingJackson2XmlHttpMessageConverter. I lean towards this being an issue that should be raised at https://github.com/spring-projects/spring-framework/issues , specifically that merely introducing jackson-dataformat-xml should not activate the MappingJackson2XmlHttpMessageConverter.

linghengqian avatar May 24 '24 07:05 linghengqian

  • If no one is willing to investigate on the Spring Framework side, I will revisit this issue in two months and try to introduce a draft into the Spring Framework OSS 6.3.0-M1.

linghengqian avatar Jun 07 '24 03:06 linghengqian

From my point of view, this is actually a problem with Google Chrome, because your http request gives too high a priority to XML. I suggest you file an issue against Spring Boot on the Chromium side. Refer to https://www.chromium.org/for-testers/bug-reporting-guidelines/ .

linghengqian avatar Jul 12 '24 11:07 linghengqian

  • I've done some more interesting tracking on this issue, and I reasonably believe that this is one of Mozilla's shit-hills of code, and Chrome is just perfectly inheriting Mozilla's conventions.
  • This is actually https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation/List_of_default_Accept_values ​​which is a constraint for all browsers.

User Agent: Firefox 128 and later [1] Value: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8

  • This is documented at https://github.com/spring-projects/spring-boot/blob/v3.3.2/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc#write-an-xml-rest-service and https://github.com/spring-projects/spring-boot/blob/v3.3.2/spring-boot-project/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc#write-a-json-rest-service .

  • Be responsible. Choose Custom @ResponseBody rendering or Custom Jackson ObjectMapper as required by Spring Boot.

linghengqian avatar Aug 17 '24 04:08 linghengqian