服务端 Webhook

JAVA Webhook

对于使用 java 的 Opencard 应用, 开发者可以参考以下 java 示例代码,来实现 Webhook 服务。

  1. import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.HashMap;
    import java.util.Map;
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.jose4j.jwe.JsonWebEncryption;
    import org.jose4j.jwk.JsonWebKey;

    //Webhook 基本协议实现
    //以下代码为示例,未妥善处理业务字段或异常等因素
    public class WebServ extends HttpServlet{

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //配置项,测试时请修改以下配置
    String jwkJson = "{\"kty\":\"oct\",\"k\":\"MDEyMzQ1Njc4OWFiY2RlZg\"}";

    //组建自己的 PSK_TABLE, 可根据自己的需求修改
    Map<String, JsonWebKey> psk_table = new HashMap<String, JsonWebKey>();
    psk_table.put("0", JsonWebKey.Factory.newJwk(jwkJson));

    response.setCharacterEncoding("UTF-8");
    response.setHeader("content-type", "application/jwt;charset=UTF-8");

    //获取请求头
    PrintWriter res = response.getWriter();
    BufferedReader br = request.getReader();
    String req_body = null;
    req_body = br.readLine();
    br.close();

    //构建解密jwe
    JsonWebEncryption jwetoken = new JsonWebEncryption();
    jwetoken.setCompactSerialization(req_body);

    //从 protected 字段中解出来 kid
    String kid = jwetoken.getKeyIdHeaderValue();

    //通过 kid 确定要用哪个解密 key
    JsonWebKey psk = psk_table.get(kid);

    //用 key 解密取得解密后的内容
    jwetoken.setKey(psk.getKey());
    String plaintext = jwetoken.getPlaintextString();

    //解码
    Map<String, Object> jsonText = JSON.parseObject(plaintext);

    //获取资源号id
    String srcid = (String) jsonText.get("srcid");
    JSONObject payload = new JSONObject();

    //如果资源方有多张卡片,从 req 中解析出来 srcid,处理相应的业务逻辑
    if (srcid.equals("123")) {
    //do something
    payload.put("msg", "scueess");
    payload.put("status", 0);

    JSONObject data = new JSONObject();
    data.put("jump_url","/path/to/page3");
    payload.fluentPut("data", data);
    } else {
    payload.put("msg", "Invalid srcid");
    payload.put("status", 2);
    }
    //处理业务响应结果
    String res_plaintext = JSON.toJSONString(payload);

    //用请求的 header 和 key 生成加密结果,保持加密算法和头内容(kid/rid)与请求一致
    JsonWebEncryption senderJwe = new JsonWebEncryption();
    senderJwe.setPlaintext(res_plaintext);
    senderJwe.setAlgorithmHeaderValue(jwetoken.getAlgorithmHeaderValue());
    senderJwe.setEncryptionMethodHeaderParameter(jwetoken.getEncryptionMethodHeaderParameter());
    senderJwe.setKey(psk.getKey());

    String res_body = senderJwe.getCompactSerialization();
    res.write(res_body);
    }
    }

其中jose4j获取方式: 在pom中的dependencies部分添加如下dependency

  1. <dependency>
    <groupId>org.bitbucket.b_c</groupId>
    <artifactId>jose4j</artifactId>
    <version>0.7.0</version>
    </dependency>

本示例代码涉及到的开发工具和开发环境,如下所示:IDE:eclipse;开发工具:jdk 1.8 、 maven 3.6.1;开发环境:tomcat 2.2 、 servlet 3.1.0 (本次使用的是maven仓库中的tomcat 和servlet)