jersey处理支付宝异步回调通知的问题:java.lang.IllegalArgumentException: Error parsing media type 'application/x-www

tcpflow以流为单位分析请求内容,非常适合服务器端接口类服务查问题

这次遇到的问题跟支付宝支付后的回调post结果有关

淘宝的代码例子:

    public void doPost(HttpServletRequest request, HttpServletResponse response)throws UnsupportedEncodingException {
        //»ñµÃ´ýÇ©ÃûÊý¾ÝºÍÇ©ÃûÖµ
        String sign = URLDecoder.decode(request.getParameter("sign"),"utf-8");
        String content = URLDecoder.decode(request.getParameter("content"),"utf-8");
        

服务器用jersey,直接使用 @FormParam 类型参数,收到post请求,但无法处理内容,log显示错误:

java.lang.IllegalArgumentException: Error parsing media type 'application/x-www-form-urlencoded; text/html; charset=UTF-8'

使用curl测试application/x-www-form-urlencoded 是可以解析的

curl -d 'sign=1&notify_data=yest' "https://passport.ishuangshuang.com/credits/order/notify"

我以为是我代码写法不支持,按照例子更改服务器端代码为:

code2:
  public String verify(@Context HttpServletRequest request) {
        Map map = request.getParameterMap();
        log.info("[alipay] callback,map="+map);
        String sign = (String) ((Object[]) map.get("sign"))[0];
        String verifyData =  (String) ((Object[]) map.get("notify_data"))[0];

仍是同样错误

使用tshark抓包,结果发现在命令行不能使用follow stream  直接查看流内容,于是安装tcpflow,yum  install  -y  tcpflow

使用命令 tcpflow -p dst port 8280,生成8280收到的请求流日志:

X-Host: xxx.com
X-Forwarded-Proto: https
Content-Type: application/x-www-form-urlencoded; text/html; charset=UTF-8
User-Agent: Mozilla/4.0
Host: xxx.com
Content-Length: 1135
LOGID: 5762503519760285696
CLIENTIP: 110.75.141.3
X-FORWARDED-FOR: 110.75.141.3

sign=mYJtdB2XmD57ReoLQkhMhUpIxmMLQltfs0opq%2Bl3prGzkA9xckxpqKMBy7vAHfCZe3ryJq1VoJxBpAv6KsaAarCn2tfcLt2EClfrZDoL967xPzLcz%2BmddlEe7ST4CHvOYg4jNaJBpxEYoDnDTmK3Rk7x%2FbfmJZwulA8OOjqGHac%3D&sign_type=RSA&notify_data=%3Cnotify%3E%3Cpartner%3E2088901361787590%3C%2Fpartner%3E%3Cdiscount%3E0.00%3C%2Fdiscount%3E%3Cpayment_type%3E1%3C%2Fpayment_type%3E%3Csubject%3E%E7%A7%AF%E5%88%86%E8%B4%AD%E4%B9%B0%3C%2Fsubject%3E%3Ctrade_no%3E2013071530259116%3C%2Ftrade_no%3E%3Cbuyer_email%3E13811437730%3C%2Fbuyer_email%3E%3Cgmt_create%3E2013-07-15+19%3A30%3A59%3C%2Fgmt_create%3E%3Cquantity%3E1%3C%2Fquantity%3E%3Cout_trade_no%3E100027%3C%2Fout_trade_no%3E%3Cseller_id%3E2088901361787590%3C%2Fseller_id%3E%3Ctrade_status%3ETRADE_FINISHED%3C%2Ftrade_status%3E%3Cis_total_fee_adjust%3EN%3C%2Fis_total_fee_adjust%3E%3Ctotal_fee%3E0.01%3C%2Ftotal_fee%3E%3Cgmt_payment%3E2013-07-15+19%3A31%3A01%3C%2Fgmt_payment%3E%3Cseller_email%3Ezhifubao%40fanxer.com%3C%2Fseller_email%3E%3Cgmt_close%3E2013-07-15+19%3A31%3A01%3C%2Fgmt_close%3E%3Cprice%3E0.01%3C%2Fprice%3E%3Cbuyer_id%3E2088502632932163%3C%2Fbuyer_id%3E%3Cuse_coupon%3EN%3C%2Fuse_coupon%3E%3C%2Fnotify%3E

两个问题:

1 Content-Type 确实有问题,这么写会导致jersey无法识别,无法解析。"Content-Type: application/x-www-form-urlencoded; text/html; charset=UTF-8"  jersey解析type为application,然后读到分隔符"/",x-www-form-urlencoded为 subtype,往后的数值为parameterMap  "text/html"因为分隔符不是"=" 无法识别,HttpHeaderReader.nextSeparator报错。不能让我为了alipay去修改jersey源码吧?

2 对于单独的jersey post注解方法,无法按照淘宝的java例子处理参数,只能以get方式添加在url后,才能以 code2 方式处理。

搜索支付宝 notify  ,google不出有效信息,

搜索 支付宝 ws_secure_pay,是客户端外包同事给的包名,才找到教程,原来还得上支付宝论坛 :http://club.alipay.com/thread-htm-fid-703.html

发现jersey 方法里不写consume也还是不行,默认是*/* 还是识别不了多重类型,servlet不会处理content-type,到最后还是按淘宝例子用servlet实现了这个支付流程。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

Web-第十天 Cookie&Session学习

当用户访问某些Web应用时,经常会显示出该用户上一次的访问时间。例如,QQ登录成功后,会显示用户上次的登录时间。通过本任务,读者将学会如何使用Cookie技术实...

1513
来自专栏比原链

Derek解读Bytom源码-启动与停止

Gitee地址:https://gitee.com/BytomBlockchain/bytom

1233
来自专栏c#开发者

Asp.net Webform 使用Repository模式实现CRUD操作代码生成工具

Asp.net Webform 使用Repository模式实现CRUD操作代码生成工具 介绍 该工具是通过一个github上的开源项目修改的原始作者https...

4408
来自专栏木木玲

Netty 那些事儿 ——— 心跳机制

6979
来自专栏Android 研究

OKHttp源码解析(三)--中阶之线程池和消息队列

android的异步任务一般都是用Thread+Handler或者AsyncTask来实现,其中笔者当初经历过各种各样坑,特别是内存泄漏,当初笔者可是相当的欲死...

2103
来自专栏Hellovass 的博客

社交化分享组件踩坑

问题是这样的,项目里的社交化分享是基于 UMShare 封装成的一个 ShareLib module,为了让这个 module 对调用者说更透明,我将 WXEn...

2785
来自专栏大内老A

[WCF REST] 通过ASP.NET Output Caching实现声明式缓存

ASP.NET的输出缓存(Output Caching)机制允许我们针对整个Web页面或者页面的某个部分(主要针对用户控件)最终呈现的HTML进行缓存。对于后续...

1987
来自专栏Java3y

Servlet第五篇【介绍会话技术、Cookie的API、详解、应用】

什么是会话技术 基本概念: 指用户开一个浏览器,访问一个网站,只要不关闭该浏览器,不管该用户点击多少个超链接,访问多少资源,直到用户关闭浏览器,整个这个过程我们...

3275
来自专栏Android 研究

OKHttp源码解析(九):OKHTTP连接中三个"核心"RealConnection、ConnectionPool、StreamAllocation

RealConnection是Connection的实现类,代表着链接socket的链路,如果拥有了一个RealConnection就代表了我们已经跟服务器有了...

3775
来自专栏实战docker

修改,编译,GDB调试openjdk8源码(docker环境下)

在上一章《在docker上编译openjdk8》里,我们在docker容器内成功编译了openjdk8的源码,有没有读者朋友产生过这个念头:“能不能修改open...

5129

扫码关注云+社区

领取腾讯云代金券