欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

你以为你以为的就是你以为的吗?记一次服务器点对点通知的联调过程

程序员文章站 2023-10-29 08:04:16
公司两个系统。 我们的A系统要给B系统上送业务签约单申请。B系统接收数据后,异步处理,签约完成会主动发送通知给我们的A系统。 接口文档里说明了,通过http协议的post请求来发送异步通知,报文是json格式字符串。But,But,But, ......

你以为你以为的就是你以为的吗?记一次服务器点对点通知的联调过程

公司两个系统。

我们的a系统要给b系统上送业务签约单申请。b系统接收数据后,异步处理,签约完成会主动发送通知给我们的a系统。

接口文档里说明了,通过http协议的post请求来发送异步通知,报文是json格式字符串。

 

你以为你以为的就是你以为的吗?记一次服务器点对点通知的联调过程

我们a系统定义restful的http接口。

【题外话】@requestbody注解:@requestbody接收的参数是来自requestbody中,即请求体。适用于http post请求。请求端通过httpentity传递参数,并在请求头中声明数据的类型content-type,springmvc通过使用 handleradapter 配置的httpmessageconverters来解析httpentity中的数据,然后绑定到相应的bean上。

@restcontroller
@slf4j
public class taxnotifycontroller {

    @reference
    private taxnotifyservice taxnotifyservice;

    /**
     *
     * @param notifyvo
     * @return
     */
    @postmapping("/ayncnotify")
    @unauthtoken
    public string ayncnotify(@requestbody notifyvo notifyvo){
        log.info("收到回调----异步回调----异步通知----回调通知:{}", json.tojsonstring(notifyvo));
        string resptext = taxnotifyservice.ayncnotify(notifyvo);
        log.info("回调----异步回调----异步通知----回调通知 回写内容:{}",resptext);
        return resptext;
    }
}

 

你以为你以为的就是你以为的吗?记一次服务器点对点通知的联调过程

qa在测试过程中,发现我方一直收不到对方的回调。有对方日志截图为证。

你以为你以为的就是你以为的吗?记一次服务器点对点通知的联调过程

 

你以为你以为的就是你以为的吗?记一次服务器点对点通知的联调过程

查看我们a系统的log。并没有发现“收到回调----异步回调----异步通知----回调通知”这样的log。

 

难道是b系统到我们a系统的网络不通?双方都是测试环境呀!还是去找运维确认吧。

[root@localhost logs]# curl http://192.168.40.84:8802/ent-boot/ayncnotify
{"code":"error","message":"request method 'get' not supported"}

 

因为需要post,所以curl接收到这个错误。但至少证明这2个系统间的网络是没问题的。

 

再次确认我方log。发现蛛丝马迹:

2019-12-13 11:07:01.894 [http-nio-8802-exec-9] info  com.emaxcard.car.filter.crosxssfilter:40 - 
crosxssfilter.......orignal url:/ent-boot/ayncnotify,parametermap:{} 2019-12-13 11:07:01.895 [http-nio-8802-exec-9] warn o.s.w.s.m.support.defaulthandlerexceptionresolver:197 -
resolved [org.springframework.web.httpmediatypenotsupportedexception: content type 'text/xml;charset=utf-8' not supported] 2019-12-13 11:07:01.895 [http-nio-8802-exec-9] info com.emaxcard.car.filter.crosxssfilter:44 -
crosxssfilter..........dofilter url:/ent-boot/ayncnotify,parametermap:{}

 

莫非,对方给的content-type是text/xml??

 

找b系统的开发同学,经查代码里httputil,果然,指定的content-type是text/xml。 如下图。我们知道,springmvc默认接收数据的格式是json方式序列化的。你指定成xml格式,显然springmvc在反序列化成notifyvo对象时会抛出异常。自然,就不会执行这个action方法了,所以,我们没看到那条“收到回调----异步回调----异步通知----回调通知”log。

你以为你以为的就是你以为的吗?记一次服务器点对点通知的联调过程

【题外话】关于springmvc的messageconverter设置,可以查看spirng-web.jar里的resttemplate.java源码。

line122:jsonbpresent = classutils.ispresent("javax.json.bind.jsonb", classloader);

你以为你以为的就是你以为的吗?记一次服务器点对点通知的联调过程

 

接着说,我们让这位开发同学改成 application/json 后,问题得以解决。

你以为你以为的就是你以为的吗?记一次服务器点对点通知的联调过程

 

 

butbutbut,下午,qa在测试付款单的回调的时候,同样的问题又出现了,我们接收不到请求报文。一看log,又是text/xml搞的鬼。b系统的这个付款回调是另一个同学开发的。考虑到目前已经有外部商户接入b系统,他们不准备改了。

不改就不改吧,b系统他们不改,只好我们a系统改了。话说回来,即便他们现在不改,日后有其他商户对接联调时,也难免会出现类似的问题。那,就是以后的事儿了。

我们怎么改呢?那就不直接从requestbody里接收notfiyvo对象了,改成接收string字符串。然后,在方法里来做判断和反序列化。改后的代码为:

    @postmapping("/ayncnotify")
    @unauthtoken
    public string ayncnotify(@requestbody string notifystr){
        log.info("收到回调----异步回调----异步通知----回调通知:{}", notifystr);
        if(stringutils.isblank(notifystr)){
            log.info("回调通知为空");
            return "error-回调通知请求参数为空";
        }
        notifyvo notifyvo = json.parseobject(notifystr,notifyvo.class);
        log.info("回调转换notifyvo:{}",notifyvo);
        string resptext = taxnotifyservice.ayncnotify(notifyvo);
        log.info("回调----异步回调----异步通知----回调通知 回写内容:{}",resptext);
        return resptext;
    }

 

 

你以为你以为的就是你以为的吗?记一次服务器点对点通知的联调过程

the end.

下午得知,一同学在对接付款接口时,当付款接口返回受理失败时,他把付款单的付款结果改成了失败。这可要不得呀!付款结果一定要通过付款查询接口来查。查询返回付款成功,则付款成功;查询返回付款失败,则付款失败;对于查询到的其他结果,保守起见,都视为付款中即可,然后由人工来干预。技术人员千万别自作主张,把某些不明确的结果定为付款失败。万一出现重复付款,那就尴尬了。我在2016年那时刚开始做聚合支付时,是有这样的惨痛经历的。

 

 ☞ stay hungry,stay foolish.