How to extract result content from play.mvc.Result

2019-04-12 20:26发布

actually I am doing redirect from one play application to another play application, finally I receive response as Result object.. Below is the action in two applications. I am redirecting from apllication1 to application2. Application 2 will return JSON string, that I need to extract.

How can I retrieve JSON content from Result object?

Application1:

public static Result redirectTest(){

    Result result =  redirect("http://ipaddress:9000/authenticate");
    /*** here I would like to extract JSON string from result***/
    return result;
}

Application2:

@SecuredAction
public static Result index() {
     Map<String, String> response = new HashMap<String, String>();
     DemoUser user = (DemoUser) ctx().args.get(SecureSocial.USER_KEY);

       for(BasicProfile basicProfile: user.identities){
           response.put("name", basicProfile.firstName().get());
           response.put("emailId", basicProfile.email().get());
           response.put("providerId", basicProfile.providerId());
           response.put("avatarurl", basicProfile.avatarUrl().get());
       }

    return ok(new JSONObject(response).toString());
}

6条回答
我想做一个坏孩纸
2楼-- · 2019-04-12 21:10

This functions works fine for me.. Thanks to Mon Calamari

public static JsonNode resultToJsonNode(Result result) {

    byte[] body = JavaResultExtractor.getBody(result, 0L);

    ObjectMapper om = new ObjectMapper();
    final ObjectReader reader = om.reader();
    JsonNode newNode = null;
    try {
        newNode = reader.readTree(new ByteArrayInputStream(body));
        Logger.info("Result Body in JsonNode:" + newNode.toString());
    } catch (JsonProcessingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return newNode;
}

}

查看更多
爷的心禁止访问
3楼-- · 2019-04-12 21:15

redirect return results with error code 303, which cause the caller (browser) to do another request to the given url.
What you need to do is actually proxying. Application1 should make a request to Application2, and handle the response.
Play have very nice Web Service API which allow doing this easily.

查看更多
霸刀☆藐视天下
4楼-- · 2019-04-12 21:17

First i write this scala method to convert Enumerator[Array[Byte]] to Future[Array[Byte]]:

class EnumeratorHelper {

  def getEnumeratorFuture(body: Enumerator[Array[Byte]]) ={
    Iteratee.flatten(body |>> Iteratee.consume[Array[Byte]]()).run
  }

}

Then convert returned Future to Promise and finally get promise value:

final F.Promise<Result> finalResultPromise = delegate.call(ctx);
finalResultPromise.onRedeem(result -> {
    F.Promise<byte[]> requestBodyPromise = F.Promise.wrap(new EnumeratorHelper().getEnumeratorFuture(result.toScala().body()));

    requestBodyPromise.onRedeem(bodyByte -> handleBody(new String(bodyByte, "UTF-8")));

});
查看更多
Juvenile、少年°
5楼-- · 2019-04-12 21:18

You'll need to pass an instance of akka.stream.Materializer into JavaResultExtractor's getbody method.

Use Google Guice for Injecting at constructor level or declaration level.

@Inject
Materializer materializer;

and Further you can convert Result into String or any other type as required:

    Result result = getResult(); // calling some method returning result
    ByteString body = JavaResultExtractor.getBody(result, 1, materializer);
    String stringBody = body.utf8String(); // get body as String.
    JsonNode jsonNodeBody = play.libs.Json.parse(stringBody); // get body as JsonNode.
查看更多
forever°为你锁心
6楼-- · 2019-04-12 21:23

In the context of a controller method you could try:

import play.libs.Json;
import play.mvc.Result;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.node.ObjectNode;
...
public static Result redirectTest(){
     ObjectNode body = (ObjectNode) request().body().asJson();
     String providerId = body.get("providerId").asText();
}

This SO question may also help: JSON and Play

查看更多
放我归山
7楼-- · 2019-04-12 21:24

Use JavaResultExtractor, example:

Result result = ...;
byte[] body = JavaResultExtractor.getBody(result, 0L);

Having a byte array, you can extract charset from Content-Type header and create java.lang.String:

String header = JavaResultExtractor.getHeaders(result).get("Content-Type");
String charset = "utf-8";
if(header != null && header.contains("; charset=")){
    charset = header.substring(header.indexOf("; charset=") + 10, header.length()).trim();
}
String bodyStr = new String(body, charset);
JsonNode bodyJson = Json.parse(bodyStr);

Some of above code was copied from play.test.Helpers

查看更多
登录 后发表回答