使用 Spring RestTemplate 发送 post 请求
程序员文章站
2022-05-26 23:17:53
...
注意点:
1)使用MultiValueMap设置入参,不要使用HashMap
2)构造HttpEntity发送请求
3)请求的参数使用LinkedMultiValueMap,每一个key里面存储的是个list,但是跟理解的有区别。不管入参是单个字符串、是一个对象的JSON字符串,还是一个对象List的JSON字符串,都是把整体的JSON作为第一个元素传递过去的,也就是请求接收方是类似下面的RestTemplatePostResponseParam 对象,但是值永远取第一个元素里的值,不管值代表的是单个字符串还是一个数组对象
4)返回的值同理也是要MultiValueMap,于是接受返回值的对象为RestTemplatePostRequestParam,也是值都只在第一个元素里面
调用方(客户端)代码
@Slf4j @RestController @RequestMapping("/sap") public class SapPullController { private final RestTemplate restTemplate; private final String SKU_AVALIABLE_FOR_SALE_URL = "http://mms-msm-hub/eccpullskuavailable/checkskuavailableforsale"; @Autowired public SapPullController(RestTemplate restTemplate) { this.restTemplate = restTemplate; } @ApiOperation(value = "判断商品是否可以销售", tags = {SwaggerConstant.SAP_PULL}) @RequestMapping(value = "/checkskuavailableforsale", method = RequestMethod.POST) public SkuAvailableForSaleOutputVO checkSkuAvailableForSale(@ApiParam(value = "请求参数", required = true) @RequestBody Map<String, Object> data) { log.info("--商品是否可销售入参: " + data.toString()); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON_UTF8); MultiValueMap<String,String> parameters = new LinkedMultiValueMap<String,String>(); parameters.add("params", JsonUtils.ToJsonString(data.get("item")).toLowerCase()); HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(parameters, headers); log.info("RequestEntity:{}", JsonUtils.ToJsonString(entity)); ResponseEntity<RestTemplatePostResponseParam> responseEntity = restTemplate.postForEntity(SKU_AVALIABLE_FOR_SALE_URL, entity, RestTemplatePostResponseParam.class); log.info("ResponseEntity:{}", JsonUtils.ToJsonString(responseEntity)); return JSON.parseObject(responseEntity.getBody().getParams().get(0), SkuAvailableForSaleOutputVO.class); } } @Data @AllArgsConstructor @NoArgsConstructor public class RestTemplatePostResponseParam implements Serializable{ private static final long serialVersionUID = 1L; private List<String> params = new ArrayList<>(); } @Data @AllArgsConstructor @NoArgsConstructor public class SkuAvailableForSaleOutputVO implements Serializable{ private static final long serialVersionUID = 1L; private List<ITEMBean> ITEM; @Data public static class ITEMBean { private String shopCode; private String skuCode; private String deliveryLocationCode; private String status; private String description; } }
服务提供方代码
/** * 商品是否可销售 * @author zhudaohui * @since 2018-07-20 * */ @RestController public class FHubEccPullSkuAvailableServiceImpl implements FHubEccPullSkuAvailableService { @Autowired private SkuAvailableForSaleService skuAvailableForSaleService; @Override @ApiOperation(value = "判断商品是否可销售", response = String.class, tags = {Swagger2Config.msm_Api_OutPut_Through_PI + Swagger2Config.web_Tag}) @OpenAPI(products = {ProductType.ALLIEDWEB}, authorities = {"mms:*"}) public MultiValueMap<String,String> checkSkuAvailableForSale(@ApiParam("判断商品是否可销售入参") @RequestBody(required=true) RestTemplatePostRequestParam param) { SkuAvailableForSaleInputVO vo = new SkuAvailableForSaleInputVO(); List<SkuAvailableForSaleInputVO.ITEMBean> list = JSON.parseArray(param.getParams().get(0), SkuAvailableForSaleInputVO.ITEMBean.class); vo.setItems(list); SkuAvailableForSaleOutputVO result = skuAvailableForSaleService.checkSkuAvailableForSale(vo); MultiValueMap<String, String> response = new LinkedMultiValueMap<String, String>(); response.add("params", JsonUtils.ToJsonString(result).toLowerCase()); return response; } } @Data @ApiModel("RestTemplate post请求参数接受") @AllArgsConstructor @NoArgsConstructor public class RestTemplatePostRequestParam implements Serializable{ private static final long serialVersionUID = 1L; private List<String> params; } @Data @ApiModel("商品是否可销售入参") @AllArgsConstructor @NoArgsConstructor public class SkuAvailableForSaleInputVO implements Serializable{ private static final long serialVersionUID = 1L; private List<ITEMBean> items; @Data public static class ITEMBean { private String shopCode; private String skuCode; private String deliveryLocationCode; } } @Data @ApiModel("商品是否可销售出参") @AllArgsConstructor @NoArgsConstructor public class SkuAvailableForSaleOutputVO implements Serializable{ private static final long serialVersionUID = 1L; private List<ITEMBean> ITEM = new ArrayList<>(); @Data @AllArgsConstructor @NoArgsConstructor public static class ITEMBean { private String shopCode; private String skuCode; private String deliveryLocationCode; private String status; private String description; } }
关于fasterxml-jackson发生Can not deserialize instance of异常原因验证
https://blog.csdn.net/li396864285/article/details/54287859
org.springframework.web.client.HttpClientErrorException: 400 null
百度了一下400代表无法解析请求。
说明请求是有问题的,如果发送的请求端没有问题。
那么就去控制器中查看是否有异常。
比如问题是控制器中的参数使用注解异常,
错误注解:@RequestParam
正确注解:@RequestBody