Akka-Http Java: Implementing a Custom Unmarshaller

时间:2017-06-04 23:40:49

标签: java xml akka-http

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.

0 个答案:

没有答案