如何从play应用程序中的play.mvc.Result对象中提取结果内容?

时间:2014-10-10 13:55:26

标签: json playframework playframework-2.0

实际上我正在从一个播放应用程序重定向到另一个播放应用程序,最后我收到响应作为Result对象。下面是两个应用程序中的操作。我从apllication1重定向到application2。应用程序2将返回我需要提取的JSON字符串。

如何从Result对象中检索JSON内容?

应用1:

public static Result redirectTest(){

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

应用2:

@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());
}

7 个答案:

答案 0 :(得分:4)

使用JavaResultExtractor,例如:

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

有一个字节数组,你可以从Content-Type头中提取字符集并创建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);

以上部分代码是从play.test.Helpers

复制而来的

答案 1 :(得分:2)

这个功能对我来说很好..感谢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;
}

}

答案 2 :(得分:1)

redirect返回错误代码为303的结果,这会导致调用者(浏览器)对给定的URL执行另一个请求。
你需要做的是实际代理。 Application1应向Application2发出请求,并处理响应 Play有非常好的Web Service API,可以轻松完成。

答案 3 :(得分:1)

您需要将 akka.stream.Materializer 的实例传递到 JavaResultExtractor getbody 方法。

使用Google Guice在构造函数级别或声明级别进行注入。

@Inject
Materializer materializer;

并且您可以根据需要将Result转换为String或任何其他类型:

    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.

答案 4 :(得分:0)

在控制器方法的上下文中,您可以尝试:

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();
}

此SO问题也可能有所帮助:JSON and Play

答案 5 :(得分:0)

这是一篇过时的文章,但我认为play.test.Helpers.contentAsString是您要寻找的内容

https://www.playframework.com/documentation/2.1.1/api/java/play/test/Helpers.html#contentAsString(play.mvc.Result)

答案 6 :(得分:-1)

首先我写这个scala方法将Enumerator [Array [Byte]]转换为Future [Array [Byte]]:

class EnumeratorHelper {

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

}

然后将返回的Future转换为Promise,最后得到promise值:

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")));

});