使用 Spring RestTemplate 发送 post 请求

阅读更多

注意点:
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 data) {
        log.info("--商品是否可销售入参: " + data.toString());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        MultiValueMap parameters = new LinkedMultiValueMap();
        parameters.add("params", JsonUtils.ToJsonString(data.get("item")).toLowerCase());
        HttpEntity> entity = new HttpEntity<>(parameters, headers);
        log.info("RequestEntity:{}", JsonUtils.ToJsonString(entity));

        ResponseEntity 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 params = new ArrayList<>();
}

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SkuAvailableForSaleOutputVO implements Serializable{
	private static final long serialVersionUID = 1L;
    private List 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 checkSkuAvailableForSale(@ApiParam("判断商品是否可销售入参") @RequestBody(required=true) RestTemplatePostRequestParam param) {
    	SkuAvailableForSaleInputVO vo = new SkuAvailableForSaleInputVO();
    	List list = JSON.parseArray(param.getParams().get(0), SkuAvailableForSaleInputVO.ITEMBean.class);
    	vo.setItems(list);
    	SkuAvailableForSaleOutputVO result = skuAvailableForSaleService.checkSkuAvailableForSale(vo);
    	MultiValueMap response = new LinkedMultiValueMap();
    	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 params;
}

@Data
@ApiModel("商品是否可销售入参")
@AllArgsConstructor
@NoArgsConstructor
public class SkuAvailableForSaleInputVO implements Serializable{
	private static final long serialVersionUID = 1L;
    private List 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 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


你可能感兴趣的:(spring,RestTemplate,json,post)