需求
前后端分离项目,前端通过post请求封装成application/json数据请求后端。后端通过签名模仿form表单用RestTemplate调用第三方平台格式为application/x-www-form-urlencoded。
通过反射需要将对象转成MultiValueMap
因为RestTemplate调用form表单提交只能用MultiValueMap,我用的Fastjson不能直接将实例对象转换成key-value的MultiValueMap。反射对象转MultiValueMap如下:
/***
* @Description:传入参数为实例对象一般是XXXDTO就是请求对象
* @Param: [obj]
* @return: java.util.Map<java.lang.String, java.lang.reflect.Field>
* @Author:
* @Date: 2021-03-12
*/
public static MultiValueMap<String, Object> getMultiValueMap(Object obj) {
MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
Class<?> clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
try {
for (Field field : fields) {
if (needFilterField(field)) {
continue;
}
//意思就是该方式是用来设置获取权限的。
//如果 accessible 标志被设置为true,那么反射对象在使用的时候,不会去检查Java语言权限控制(private之类的);
//如果设置为false,反射对象在使用的时候,会检查Java语言权限控制。
//需要注意的是,设置为true会引起安全隐患。
field.setAccessible(true);
multiValueMap.add(field.getName(), field.get(obj));
}
getParentMap(clazz, multiValueMap, obj);
} catch (Exception e) {
e.printStackTrace();
}
return multiValueMap;
}
/**
* 过滤不需要属性
*
* @param field
* @return
*/
private static Boolean needFilterField(Field field) {
// 过滤静态属性
if (Modifier.isStatic(field.getModifiers())) {
return true;
}
// 过滤transient 关键字修饰的属性
if (Modifier.isTransient(field.getModifiers())) {
return true;
}
return false;
}
如果是需要父类的属性需要通过反射递归调用父类
/**
* 递归所有父类属性
*
* @param clazz
* @param multiValueMap
*/
private static void getParentMap(Class<?> clazz, MultiValueMap<String, Object> multiValueMap, Object obj) {
Class<?> superClazz = clazz.getSuperclass();
if (superClazz != null) {
Field[] superFields = superClazz.getDeclaredFields();
try {
for (Field field : superFields) {
if (needFilterField(field)) {
continue;
}
field.setAccessible(true);
multiValueMap.add(field.getName(), field.get(obj));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
getParentMap(clazz, multiValueMap, obj);
}
}
这样传入的对象就会转成key-value模式传入的对象
转完之后的MultiValueMap对象
RestTemplate调用
代码如下:
@Autowired
private RestTemplate restTemplate;
/***
* @Description:RetResponse为自己封装的统一返回对象
* @Param: [returnStr]
* @return: cn.thinkjoy.springboot.logicunified.dto.response.RetResponse
* @Author: leichunhong
* @Date: 2021-02-23
*/
@Override
public RetResponse getRetResponse(String url, MultiValueMap<String, Object> multiValueMap) {
RetResponse retResponse=new RetResponse();
try{
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(multiValueMap, httpHeaders);
ResponseEntity<String> response = restTemplate.postForEntity(getPath(url), requestEntity, String.class);
retResponse = JSONObject.parseObject(response, RetResponse.class);
return retResponse;
}catch (Exception e){
logger.error(e.getMessage(), e);
retResponse.setRet(-1);
retResponse.setMsg("http请求错误");
return retResponse;
}
}