首页>>后端>>SpringBoot->实践出真知!Http接口联调实战

实践出真知!Http接口联调实战

时间:2023-11-30 本站 点击:1

场景

与供应商进行一次接口的对接,自己在postman中进行调试,发现可以正常调用,但是联调时对方却报请求方式错误,导致花费了较多时间。

请求类型

POST

请求的url https://xxxxx/vehicleOperate/openapi/gateMachine/inRecord/518021_0054/parkcarin

请求参数

{"carinlist":"[{"id":"197","entrance":"入口","cardId":"BDF2413131313131","cardNo":"津A11111","carNo":"津A11111","ownerName":"临时用户","cardTypeId":"31","cardTypeName":"临时卡A","entranceTime":"2017-06-1408:38:29","entranceUserName":"系统管理员","entranceWayId":"0","entranceWayName":"正常入场","small":"0","entryPic":"","MachNo":"1"}]","signature":"SJDKLSJKLDJSKLSHJKSHDJKHJKHJK","t":"1520416876"}

接口代码

```@PostMapping("/inRecord/{parkId}/parkcarin")publicDoorRecordResultcreateInRecord(@RequestBodyDoorGateMachineRecordInfoInVOdoorGateMachineRecordInfoVO,@PathVariable("parkId")StringparkId){DoorRecordResultdoorRecordResult=newDoorRecordResult();SSOUserssoUser=getCurrentUser();log.info("parkId:{},入场消息消费:{}",parkId,JSONObject.toJSONString(doorGateMachineRecordInfoVO));List<DoorGateMachineRecordInVO>carinlist=doorGateMachineRecordInfoVO.getCarinlist();carinlist.stream().forEach(g->{g.setCreatorId(ssoUser.getId());g.setCreatorName(ssoUser.getUsername()+"/"+ssoUser.getRealname());g.setCreateTime(newDate());});doorRecordResult=gateMachineService.handleInRecord(carinlist,parkId);log.info("入场消息消费处理结束parkId:{},处理结果:{}",parkId,JSONObject.toJSONString(doorRecordResult));returndoorRecordResult;}```

通过postman调用接口可以调通返回数据,但是通过对方应用调用就是不行,其中试了几种方式都是不行,最终发现遗漏了一项,就是content-type,对方应用调用我们接口推送数据的content-type是application/x-www-form-urlencoded,而我这边接口支持的content-type实际上是application/json,导致接口无法调用,接口文档中content-type类型一定要标明,否则会严重影响接口的开发。

application/x-www-form-urlencoded和application/json有什么区别呢?首先要了解下一共有几种content-type

application/x-www-form-urlencoded application/x-www-form-urlencoded是最常见的 POST 提交数据的方式了。浏览器的原生

@PostMapping(value="/inRecord/{parkId}/parkcarin",consumes="application/x-www-form-urlencoded")publicDoorRecordResultcreateInRecord(@RequestParam(value="carinlist")StringcarinlistStr,@PathVariable("parkId")StringparkId){-----carinlistStr=parameterMap.get("carinlist")[0];}

也可以不用springMVC的注解,直接从HttpServerlet中取值,如

@PostMapping(value="/inRecord/{parkId}/parkcarin",consumes="application/x-www-form-urlencoded")publicDoorRecordResultcreateInRecord(HttpServletRequestrequest,@PathVariable("parkId")StringparkId){List<DoorGateMachineRecordInVO>carinlist=null;Map<String,String[]>parameterMap=request.getParameterMap();try{StringcarinlistStr=parameterMap.get("carinlist")[0];log.info("入场消息消费处理开始parkId:{},收到数据:{}",parkId,carinlistStr);carinlist=JacksonUtil.toList(carinlistStr,DoorGateMachineRecordInVO.class);

之前对方系统报请求方式错误,就是因为代码中使用@RequestBody来接收参数,那什么时候要用@RequestBody来接收参数呢,这就要说第二种content-type

application/json

这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。 这种类型是现在很常见的响应头,而接收她的参数就是@RequestBody,之前接口不通的原因也是我这边使用的响应头其实是application/json方式

multipart/form-data

这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让

text/xml

它是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范。典型的 XML-RPC 请求是这样的:

POST http://www.example.com HTTP/1.1 Content-Type: text/xml <?xml version="1.0"?>examples.getStateName41

除了content-type类型外,还要注意的就是如何在postman上测试application/x-www-form-urlencoded请求。由于入参是复杂的数组,所以要考虑postman如何传递数组。

起初以为是这样传递

一直调不通,后来才发现是这样的

由此可见postman默认是一行对应一个key-value,当时联调时由于对postman的这种调用不熟悉,所以使用通过java代码的调用形式,这两种也是异曲同工的。了解这些后我也对http的请求头进行了一些了解

Accept:客户端能接受的内容类型 text/plain, text/html

User-Agent :发起请求方的信息

结语

Http接口算是诸多接口中最简单的接口,但是如果不熟悉他的请求头,请求体,及相应框架的接收处理,也会产生一系列的问题,只有再实践中发掘其中问题,才能再下次处理接口时更好的处理功能的开发,更快的处理相关问题,提升开发的效率。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/SpringBoot/4402.html