Description
The SseEmitter included in the spring framework does not seem to include a capable text/plain parser in the underlying converter set.
Whenever i try to send any form of event, the emitter automatically includes a "data:" prefix, which it adds with the text/plain mediatype.
After a bit of digging i noticed some of the underlying functions use a subset of spring's default MessageConverters, this subset does not include the default String converter.
So, whenever i try to send any type of event like so:
SseEmitter.SseEventBuilder event = SseEmitter.event()
.data("SSE MVC - " + LocalTime.now().toString())
.id(String.valueOf(i))
.name("sse event - mvc");
emitter.send(event);
it will inevitably result in a
java.lang.IllegalArgumentException: No suitable converter for class java.lang.String
The suggestion would be to either include the standard string converter, or let the SseEmitter use a different mediatype for pre- and suffixes that are supported in the Converter chain for the emitter.
I'm currently on spring boot version 2.1.12.RELEASE
Activity
rstoyanchev commentedon Feb 3, 2020
The handling for
SseEmitter
uses message converters fromResponseBodyEmitterReturnValueHandler
which is initialized inRequestMappingHandlerAdapter
from the same list of message converters as every other argument resolver.So it not clear at all what the root cause of your issue is. Please, provide more details or a sample.
[-]SseEmitter cannot parse text/plain[/-][+]SseEmitter cannot format text/plain[/+]rstoyanchev commentedon Feb 3, 2020
I corrected the title because SseEmitter does no parsing, but rather the opposite.
incapable commentedon Feb 3, 2020
Sorry, you're right.
But, you stated that it should be using all of the message converters, but it simply is not doing that.
Here you see the currently available converters for the ResponseBodyEmitterReturnValueHandler that the SseEmitter uses

which is added here, in the RequestMappingHandlerAdapter

And that list is set, in the adapter, over here

Which is called from the RepositoryRestMvcConfiguration, in the repositoryExporterHandlerAdapter method, from which it get's it's defaultMessageConverter list

https://github.com/spring-projects/spring-data-rest/blob/master/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java#L651
where only a subselection of the converters are added.
Please note: In my startup chain the repositoryExporterHandlerAdapter is called twice, only one of which comes from the RepositoryRestMvcConfiguration, the other initialization does include all the converters that would be needed. The SseEmitter uses the RepositoryRestMvc list of converters though, and because of that it cannot parse text/plain mediatypes
rstoyanchev commentedon Feb 3, 2020
Okay this makes is a bit more clear.
RepositoryRestMvcConfiguration
is in Spring Data REST and that doesn't seem to include a message converter for text when it configures therepositoryExporterHandlerAdapter
bean.Either Spring Data REST can add
StringHttpMessageConverter
to the config it uses, or perhaps there is a way that you can configured it into Spring Data REST. @gregturn or @odrotbohm any thoughts?If this isn't feasible we might be able to add special handling for SSE in case
StringHttpMessageConverter
isn't available.[-]SseEmitter cannot format text/plain[/-][+]SseEmitter cannot format text/plain if StringHttpMessageConverter is not configured[/+]odrotbohm commentedon Feb 5, 2020
Happy to investigate what we can do to help. Just wondering why your controller ends up in the Spring Data REST specific
HandlerAdapter
? Can you elaborate a bit more on your actual use case?15 remaining items