I'm trying to implement my own Unmarshaller
for akka-http
that converts an HttpEntity object into an object representing the incoming XML. It's not very obvious how you do it. The documentation for akka-http unmarshallers is still incomplete. The documentation references that akka-http
comes with its own Jackson marshaller and unmarshaller but from looking at the jars, I don't see those classes anywhere.
I see an example of how to implement your own Unmarshaller
from looking at the akka.http.javadsl.unmarshalling.Unmashaller
object.
val requestToEntity: Unmarshaller[HttpRequest, RequestEntity] =
unmarshalling.Unmarshaller.strict[HttpRequest, RequestEntity](_.entity)
Here, it's using the scaladsl's Unmarshaller object's strict
function to create a synchronous Unmarshaller according to the scaladocs of strict
.
I took this approach and what I got isn't very pretty.
private static final ObjectMapper mapper = new XmlMapper();
private <T> Unmarshaller<HttpEntity, T> unmashaller(Class<T> clazz) {
Function1<HttpEntity, T> scalaConverter = new AbstractFunction1<HttpEntity, T>() {
public T apply(HttpEntity entity) {
T s = null;
// TODO: performing async operation in sync matter. figure out how to do this better
try {
String body = Unmarshaller.entityToString()
.unmarshal(entity, materializer)
.toCompletableFuture()
.get();
s = mapper.readValue(body, clazz);
} catch (Exception e) {
e.printStackTrace();
}
return s;
}
};
return (Unmarshaller<HttpEntity, T>) Unmarshaller$.MODULE$.strict(scalaConverter);
}
The strict
function takes a scala Function1 object. I first convert the HttpEntity to a String. Once I get the string, I convert it to the object using an external Jackson library.
Is there a better way to do this? I'm more or less doing this as a POC.