【问题标题】:How to implement a PayPal IPN Controller in Java using Play 2.0如何使用 Play 2.0 在 Java 中实现 PayPal IPN 控制器
【发布时间】:2012-09-24 13:42:24
【问题描述】:

我正在使用 Play Framework 2.0 实现一个 PayPal IPN 控制器(目前使用 Java),它从 PayPal 服务器接收表单编码的 POST 请求。我正在调整来自 blog post by Guillame Leone 的 Play 1.x 控制器以使用 Play 2.0。由于“params”现在没有了,这个任务似乎有点棘手。

PayPal IPN 流程有两个步骤:

1) 将请求正文解析为文本,以便我可以向 PayPal 提交他们想要的确切响应。它必须是与他们提交给我的顺序相同的字符串。这目前有效:

 @BodyParser.Of(BodyParser.TolerantText.class)
 public static Result validation() throws Exception {
   Logger.info("Received IPN request");
    String str = "cmd=_notify-validate&" + request().body().asText();
    Logger.info("Validation string: " + str);

2) 向 PayPal 发送验证请求,当他们回复“已验证”响应时,我想解码表单编码的请求正文并将其作为地图访问。但是由于我已经使用注释将请求正文解析为文本,因此以下返回 null 而不是映射:

Map<String,String[]> data = request().body().asFormUrlEncoded() //returns null

两次解析此请求的最佳方式是什么,一次作为文本(忽略表单编码的 MIME 类型),第二次作为表单编码的数据?

(看来我可能想摆脱注释并直接调用 TolerantText 和 FormEncoded 解析器,但我不知道该怎么做!)

【问题讨论】:

  • 我也对 Scala 解决方案感兴趣,如果它更容易的话,因为我的大部分应用程序都是在 Scala 中构建的,一旦我更好地了解 Body Parsers,我计划将其移植到 Scala。跨度>
  • 如果您曾经迁移到 Scala API,您可以尝试将 toleranceText 与 play.core.parsers.FormUrlEncodedParser.parse(body) 一起获取请求映射。
  • 嘿,谢谢,我认为这会奏效。在将控制器迁移到 Scala 之前,我正在编写一个小的 Scala 实用函数来将请求正文作为字符串并将 parse(body) Map 转换为 Java 集合。可以说没有直接的方法可以使用纯 Java 做到这一点吗?

标签: scala playframework playframework-2.0 paypal-ipn


【解决方案1】:

由于 Java 和 Scala 集合之间的互操作性问题,使用 Play Java API 似乎没有直接的方法。

要使用 Java 集合访问表单数据,我必须编写一个 Scala 助手:

object BodyParserUtils {
  def parseTextAsFormUrlEncodedForJava(textBody: String) = {
    import collection.JavaConverters._
    val scalaMap = FormUrlEncodedParser.parse(textBody)
    scalaMap.mapValues(_.asJava).asJava
  }
}

然后我就可以设置数据变量了:

Map<String, List<String>> data = BodyParserUtils.
     parseTextAsFormUrlEncodedForJava(request().body().asText());

如果您想要一个裸机(尚未完成)Play 2.0 Java 控制器来开始接收 PayPal IPN 请求,这就是全部:

public class PaypalController extends Controller {

@BodyParser.Of(BodyParser.TolerantText.class)
public static Result validation() throws Exception {
    Logger.debug("Received IPN request");

    String str = "cmd=_notify-validate&" + request().body().asText();
    Logger.debug("Validation string: " + str);

    URL url = new URL("https://www.sandbox.paypal.com/cgi-bin/webscr");
    URLConnection connection = url.openConnection();
    connection.setDoOutput(true);
    connection.setRequestProperty("Content-Type",
            "application/x-www-form-urlencoded");

    PrintWriter out = new PrintWriter(connection.getOutputStream());
    out.println(str);
    out.close();

    BufferedReader in = new BufferedReader(new InputStreamReader(
            connection.getInputStream()));
    String result = in.readLine();
    in.close();

    Logger.debug("IPN result: " + result);

    Map<String, List<String>> data = BodyParserUtils
            .parseTextAsFormUrlEncodedForJava(request().body().asText());
    Logger.debug("Form data: " + data);

    if (StringUtils.equals(result, "VERIFIED")) {
        return ok();
    } else {
        return badRequest();
    }

}

}

【讨论】:

  • 我尝试为您的班级解决导入问题:import org.apache.commons.lang3.StringUtils; import play.Logger; import play.api.mvc.Result; import play.mvc.BodyParser; import play.mvc.Controller; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; import java.util.List; import java.util.Map; 但是 ok() 和 badRequest() 返回 Results.Status 而不是 Result
  • 以下是您的类的一组可编译的导入:import org.apache.commons.lang3.StringUtils; import play.Logger; import play.mvc.Result; import play.mvc.BodyParser; import play.mvc.Controller; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; import java.util.List; import java.util.Map;
猜你喜欢
  • 2016-11-02
  • 2016-07-19
  • 2016-09-28
  • 2011-11-29
  • 2019-04-06
  • 2021-03-05
  • 2018-06-12
  • 1970-01-01
  • 2014-01-26
相关资源
最近更新 更多