3

I've been working with Spring Boot 2.0.0.RC1 and use spring-boot-starter-webflux in order to build a REST Controller that returns a flux of text data.

@GetMapping(value = "/")
public Flux<String> getData(){
    return Flux.interval(Duration.ofSeconds(2))
        .map(l -> "Some text with umlauts (e.g. ä, ö, ü)...");
}

Since the text data contains some umlauts (e.g. ä, ö, ü), I would like to change the Content-Type header of the response from text/event-stream to text/event-stream;charset=UTF-8. Therefore, I tried wrapping to flux into a ResponseEntity. Like this:

@GetMapping(value = "/")
public ResponseEntity<Flux<String>> getData(){
    return ResponseEntity
            .ok()
            .contentType(MediaType.parseMediaType("text/event-stream;charset=UTF-8"))
            .body(Flux.interval(Duration.ofSeconds(2))
                    .map(l -> "Some text with umlauts (e.g. ä, ö, ü)..."));
}

Now, making a curl request to the endpoint shows that the Content-Type remains the same:

< HTTP/1.1 200 OK
< transfer-encoding: chunked
< Content-Type: text/event-stream
<
data:Some text with umlauts (e.g. ├ñ, ├Â, ├╝)...

I suspected the MediaType.parseMediaType() method to be the issue, but the media type is parsed correctly (as this screenshot shows):

this

However, the parameter charset seems to be ignored. How can I change the encoding to UTF-8 so that the browser interprets the umlaut characters correctly?

EDIT: Setting within the GetMapping annotation the produces field does not work either.

@GetMapping(value = "/", produces = "text/event-stream;charset=UTF-8")
public ResponseEntity<Flux<String>> getData(){
    return ResponseEntity
            .accepted()
            .contentType(MediaType.parseMediaType("text/event-stream;charset=UTF-8"))
            .body(Flux.interval(Duration.ofSeconds(2))
                    .map(l -> "Some text with umlauts (e.g. ä, ö, ü)..."));
}
JonathanDavidArndt
  • 2,518
  • 13
  • 37
  • 49
Michael Stadler
  • 441
  • 1
  • 4
  • 12
  • try this `@GetMapping(value = "/", produces = "text/event-stream;charset=UTF-8")` – pvpkiran Feb 19 '18 at 11:02
  • Thank you for your comment. I tried that before, but it does not help either. – Michael Stadler Feb 19 '18 at 11:28
  • I get the same behavior with Chrome. I think that the main problem is the missing `charset=UTF-8` part in the `Conent-Type` header of the response. Since that is missing, I guess ANSI encoding is assumed. – Michael Stadler Feb 19 '18 at 11:44
  • the problem is not in your code, in curl. You need to set Accept header . Try this `curl -v -H "Accept:text/event-stream;charset=UTF-8" --verbose http://localhost:8080/` – pvpkiran Feb 19 '18 at 12:10
  • Even with the Accept header set, the result is the same: `> GET / HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.58.0 > Accept:text/event-stream;charset=UTF-8 > < HTTP/1.1 202 Accepted < transfer-encoding: chunked < Content-Type: text/event-stream < data:Some text with umlauts (e.g. ├ñ, ├Â, ├╝)...` – Michael Stadler Feb 19 '18 at 12:19
  • This sounds like a reasonable change to ask - could you create a new issue on jira.spring.io for Spring Framework? – Brian Clozel Feb 19 '18 at 13:52
  • @BrianClozel Thanks for your input. I've just created a new [issue](https://jira.spring.io/browse/SPR-16516). – Michael Stadler Feb 19 '18 at 14:16
  • Are there any solutions? Tickets are closed, but I can not display Russian characters – LeshaRB Jul 09 '21 at 11:24

1 Answers1

0

You can create a Filter and process response before this return to browser

    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    import org.springframework.core.Ordered;
    
    // esse filtro foi criado pra converter para UTF-8 o response do Flux<ServerSentEvent<String>>
// this filter was created to convert all responses to UTF8, including Flux<ServerSentEvent<String>>
    @Component
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public class FluxPreProcessorFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            response.setCharacterEncoding("UTF-8");
            chain.doFilter(request, response);
        }
    
    }