Akka Http how to add charset utf-8 to the content-type header

1,336 views
Skip to first unread message

Thibault Meyer

unread,
May 5, 2017, 3:40:30 AM5/5/17
to Akka User List
Hello,

I dont find how to set the content type to "application/json; charset=UTF-8" with the completeOKWithFuture and Jackson marshaller. Currently, Akka Http return the Content-Type "application/json" without specifying the charset. So in some browsers (like Opera or Chrome) the output text is not good.


get(() -> {
 
final MessageDispatcher dispatcher = akkaSystem.dispatchers().lookup("application.dispatcher");
 
return completeOKWithFuture(CompletableFuture.supplyAsync(() -> {
   
final Map<String, Object> result = new HashMap<>();
    result
.put("trackingNumber", trackingNumber);
   
ArrayList<Map<String, String>> status;
   
if (this.cache == null) {
      status
= TrackingCrawler.parseDocument(trackingNumber);
   
} else {
      status
= this.cache.readFromCache("tracking." + trackingNumber);
     
if (status == null) {
        status
= TrackingCrawler.parseDocument(trackingNumber);
       
this.cache.writeToCache(
         
"tracking." + trackingNumber,
          status
       
);
     
}
   
}
    result
.put("status", status);
   
return result;
 
}, dispatcher).exceptionally(ex -> {
    LOG
.error("Something goes wrong", ex);
   
return new HashMap<>();
 
}), Jackson.marshaller());
})



Sincerly.

Alex Cozzi

unread,
May 5, 2017, 1:42:40 PM5/5/17
to Akka User List
funny, I was looking into this yesterday!
I am by no means an expert, but I think that what it is happening is the following: 
application/json implies UTF-8: if you look at the MediaType class from akka http you se the declaration:

val `application/json` = awfc("json", HttpCharsets.`UTF-8`, "json")


second,  get the data from your service with curl/wget and have a look. When I did in my experiment the data in the file was correctly rendered as UTF-8. 

now, why non-ascii characters are messed up when you look at it in the browser? I think that the browser is trying to render json as HTML, and since the data is not html it defaults to HTML default encoding, which is ISO-8859-1 (https://www.w3schools.com/html/html_charset.asp), so it renders your data incorrectly.

In conclusion I believe that is not akka http at fault, but the default behavior of all web browser (I saw it on chrome and safari): your data is fine, it is just displayed wrongly when you look at it in a browser

Alex

Alan Burlison

unread,
May 5, 2017, 5:23:54 PM5/5/17
to akka...@googlegroups.com
On 05/05/17 18:42, Alex Cozzi wrote:

> funny, I was looking into this yesterday!
> I am by no means an expert, but I think that what it is happening is the
> following:
> application/json implies UTF-8: if you look at the MediaType class from
> akka http you se the declaration:

I believe you are correct, http://www.ietf.org/rfc/rfc4627.txt says:

3. Encoding
JSON text SHALL be encoded in Unicode. The default encoding is UTF-8.

so an explicit MIME type isn't required if the content is UTF-8 - but
other JSON frameworks do often seem to include the UTF-8 charset.

As far as I know there's no "proper" way of forcing the addition of the
charset to the application/json content type in Akka-HTTP but it is
possible to hack around it:

val ct = ContentType(MediaType.custom("application/json",
false).asInstanceOf[MediaType.WithOpenCharset], HttpCharset.custom("utf-8"))

--
Alan Burlison
--

Greg Methvin

unread,
May 5, 2017, 6:49:14 PM5/5/17
to akka...@googlegroups.com
There is no charset parameter defined for application/json. See https://www.iana.org/assignments/media-types/application/json

The encoding should not be determined by looking at the charset parameter, but rather by looking at the first four octets: https://tools.ietf.org/html/rfc4627#section-3

If you absolutely have to deal with non-conforming parsers, the custom media type is probably the right way to go.



--
     Read the docs: http://akka.io/docs/
     Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
     Search the archives: https://groups.google.com/group/akka-user
--- You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+unsubscribe@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.



--
Greg Methvin
Tech Lead - Play Framework

Thibault Meyer

unread,
May 6, 2017, 2:12:06 AM5/6/17
to Akka User List
Hi Greg,


how to do this ? I see no arguments in completeOKWithFuture or Jackson.marshaller() to do this. I'm using Java version of akka-http.

Thanks
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.

To post to this group, send email to akka...@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

johannes...@lightbend.com

unread,
May 15, 2017, 7:55:04 AM5/15/17
to Akka User List
Hi Thibault,

you are right, there's currently no built-in way to do this. To achieve it, you could e.g. copy the Jackson marshaller from the sources to use a custom media type. See here: https://github.com/akka/akka-http/blob/5932237a86a432d623fafb1e84eeeff56d7485fe/akka-http-marshallers-java/akka-http-jackson/src/main/java/akka/http/javadsl/marshallers/jackson/Jackson.java#L27-L27

Johannes

Thibault Meyer

unread,
May 15, 2017, 10:26:05 AM5/15/17
to Akka User List
Hi Johannes,

Thanks for the tips. It now working !


Sincerly
Reply all
Reply to author
Forward
0 new messages