带有参数的Spring RestTemplate GET

使用 RestTemplate 发送 get 请求携带参数,发现有问题,对面收不到我的请求参数,

一种方式是使用占位符将请求的 url 转换一下,类似于这样 String url = "http://api.xxx.xxx?name={name}&age={age}"; 将请求参数拼接在链接后面,这种方式比较麻烦,后面有修改的话改动较多。

还有一种方式, 使用 UriComponentsBuilder 拼接请求参数

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url).queryParams(params);
builder.queryParam(key,value)

一个工具类的 get 请求代码

// 拼接字符串
private String buildUrl(String subUrl) {
	return String.format("%s%s", volcanoUrl, subUrl);
}


// 发送 get 请求
public static <T> T getForEntity(String url, Class<T> responseType, MultiValueMap<String, String> headers,
		MultiValueMap<String, String> params, Object requestObj) {
	log.info("开始请求远程数据,url:{},paramMap:{},headers:{},requestObj:{}", url, params, headers,requestObj);
	HttpEntity<?> requestEntity = new HttpEntity<>(headers);
	if (params == null) {
		params = new LinkedMultiValueMap<>();
	}
	UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url).queryParams(params);
	if (requestObj != null) {
		for (Entry<String, String> entry : objectToMap(requestObj).entrySet()) {
			builder.queryParam(entry.getKey(), Lists.newArrayList(entry.getValue()));
		}
	}
	ResponseEntity<CommonResponse<T>> responseEntity = restTemplate.exchange(builder.build().toUri(),
			HttpMethod.GET, requestEntity, getCommonResponseReference(responseType));
	if (responseEntity != null && responseEntity.getStatusCode() == HttpStatus.OK) {
		CommonResponse<T> resp = responseEntity.getBody();
		if (resp.isSuccess()) {
			return resp.getData();
		} else {
			throw new BizException("数据请求失败,对方返回失败," + resp.getError());
		}
	}
	throw new BizException("数据请求失败,网络异常," + JSON.toJSONString(responseEntity));
}



// obj 转 map
public static Map<String, String> objectToMap(Object obj) {
	if (obj == null) {
		return null;
	}
	Map<String, String> map = new HashMap<String, String>();

	List<Field> allFields = new ArrayList<>();
	Class currentClass = obj.getClass();

	while (currentClass != null) {
		allFields.addAll(Arrays.asList(currentClass.getDeclaredFields()));
		currentClass = currentClass.getSuperclass();
	}

	for (Field field : allFields) {
		field.setAccessible(true);
		if (Objects.isNull(field.get(obj))) {
			continue;
		}
		if (field.isSynthetic()) {
			continue;
		}
		Object object = field.get(obj);
		if (object instanceof Map) {
			map.put(field.getName(), JSON.toJSONString(object));
		} else {
			map.put(field.getName(), String.valueOf(field.get(obj)));
		}
	}
	return map;
}



private static <T> ParameterizedTypeReference<CommonResponse<T>> getCommonResponseReference(Class<T> clazz) {
	JavaType javaType = objectMapper.getTypeFactory().constructParametricType(CommonResponse.class, clazz);
	return ParameterizedTypeReference.forType(javaType);
}


2021/12/14 posted in  Spring