服务端 Webhook
JAVA Webhook
对于使用 java 的 Opencard 应用, 开发者可以参考以下 java 示例代码,来实现 Webhook 服务。
- 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
- <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)