Comments (6)
Using the postProcess
hooks points offers more precise control over the end result. Perhaps not needed here, but it's the recommended approach and this sort of situation is why those methods were introduced.
from spring-boot.
Until we find time to look at this in detail, as an alternative workaround, you may want to consider defining your own HttpMessageConverters
bean that overrides postProcessConverters
and postProcessPartConverters
to filter out the unwanted converter.
from spring-boot.
@wilkinsona Thanks for the alternative workaround. Can you maybe explain what the advantage of that approach is over the workaround I shared above?
from spring-boot.
@wilkinsona Thanks! By the way, when I have overridden postProcessConverters()
, I don't also have to override postProcessPartConverters()
, correct? The latter only applies in a subset of cases, do I interpret that correctly from the code?
Based on the example you linked to, I ended up with this (in Kotlin), which indeed works as well, at least in our case:
import org.springframework.boot.autoconfigure.http.HttpMessageConverters
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.converter.AbstractKotlinSerializationHttpMessageConverter
import org.springframework.http.converter.HttpMessageConverter
@Configuration
class MessageConvertersConfig {
/**
* Bean provider that filters out standard [HttpMessageConverter]s that we don't want Spring to use, even when the
* serde frameworks for them are detected by Spring in the classpath.
*
* With thanks to https://github.com/spring-projects/spring-boot/issues/39853#issuecomment-1984360351 and
* https://github.com/spring-projects/spring-boot/issues/1482#issuecomment-61862787
*
* Should override [org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration.messageConverters]
*/
@Bean
fun filteredMessageConverters(): HttpMessageConverters =
object : HttpMessageConverters() {
override fun postProcessConverters(converters: MutableList<HttpMessageConverter<*>>): MutableList<HttpMessageConverter<*>> {
converters.removeIf {
it is AbstractKotlinSerializationHttpMessageConverter<*>
}
return converters
}
}
}
from spring-boot.
By the way, when I have overridden
postProcessConverters()
, I don't also have to overridepostProcessPartConverters()
, correct? The latter only applies in a subset of cases, do I interpret that correctly from the code?
Yes, that's right. postProcessPartConverters()
only applies to the converters that are used by AllEncompassingFormHttpMessageConverter
. If your app isn't receiving multi-part requests, the converters used by this converter converter won't need to be customized.
Just to make sure I have understood your situation correctly, am I right in understanding that:
- Your application has Jackson on the classpath
- Your application has kotlinx.serialization on the classpath
- You are (de)serializing a type that kotlinx.serialization supports (
kotlinx.serialization.SerializersKt.serializerOrNull
returns aKSerializer
for the type) but you want Jackson to be used instead
Assuming that the above is correct, is kotlinx.serialization on the classpath for some other reason or is it there accidentally? Just trying to understand the scope of the problem and gauge how likely others are to be affected by it – this is the first time it's been raised in Boot's issues as far as I can remember.
from spring-boot.
@wilkinsona You summarized the points correctly, but just to add some extra context to point 2: we are including a library dependency in our project, which uses kotlinx.serialization
and pulls it into the project as a transitive dependency. That's why it's showing up in our classpath alongside Jackson.
The application as a whole, however, is still set up to use Jackson for (de)serialization (apart from the library that we're including for one specific purpose). We may decide to migrate the entire project from Jackson to kotlinx.serialization
at some point, but that wouldn't be a trivial, so we prefer to maintain the same behavior throughout the application for now.
By the way, thinking about it more, I'm not entirely sure about point 3. It's plausible, but I simply experienced certain integration tests in the application starting to fail, because it switched from Jackson to kotlinx.serialization
, just because it found both serde frameworks in the classpath. And I know it did so, because I could see in the stacktraces that kotlinx.serialization was being invoked. So that seems to imply that point 3 is true.
But even if it's not common to have multiple (Spring-supported) serde frameworks in the classspath, wouldn't it be reasonable to expect that the one explicitly selected in spring.mvc.converters.preferred-json-mapper
would be used anyway?
Anyway, I hope this answers your question. Just let me know in this thread if more information or clarification is needed. Thanks!
from spring-boot.
Related Issues (20)
- spring-boot-dependencies cannot be used with repositories that ban com.oracle.database.jdbc:ojdbc-bom
- spring-boot-dependencies cannot be used with repositories that ban com.oracle.database.jdbc:ojdbc-bom
- Upgrade to Asciidoctor Gradle Plugin 4.0.2
- Avoid calling getProject() during execution of StarterMetadata task
- Avoid calling getProject() during execution of StarterMetadata task
- Avoid calling getProject() during execution of StarterMetadata task
- Avoid calling getProject() during execution of AutoConfigurationMetadata task
- Avoid calling getProject() during execution of AutoConfigurationMetadata task
- Avoid calling getProject() during execution of AutoConfigurationMetadata task
- Avoid calling getProject() during execution of publishMavenPublicationToProjectRepository
- Avoid calling getProject() during execution of publishMavenPublicationToProjectRepository
- Avoid calling getProject() during execution of publishMavenPublicationToProjectRepository
- Avoid calling getProject() when checking configuration metadata
- Avoid calling getProject() when checking configuration metadata
- Avoid calling getProject() when checking configuration metadata
- IllegalArgumentException can be thrown when running an uber jar on a shared drive HOT 3
- Avoid calling getProject() during execution of extractVersionConstraints
- Avoid calling getProject() during execution of extractVersionConstraints
- Using prometheus 0.x with distribution percentiles lead to "Counts in ClassicHistogramBuckets cannot be negative."
- LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spring-boot.