问题描述:
前端请求JOSN数据中包含对象和数组对象,后端接口如果直接接受,将会抛“400”的错误,解决办法。
示例请求数据:
{
"base": {
"name": "参数123",
"code": "",
"status": "",
"purchaseNo": "CFXZ20190308001",
"purchaseId": "1001",
"purchaseTypeName": "写死了的采购计划名称用于参数",
"totalPrice": 99999,
"matters": "",
"addedType": "0",
"addedContractName": "",
"renewType": "0",
"renewContractName": "",
"renew_contract": "",
"frameworkType": "0",
"frameworkContractName": "",
"normalType": "0",
"contractAdministratorName": "",
"otherType": "0",
"otherContractName": "",
"financialRemarks": "3",
"type": ""
},
"info": {
"otherContractSubjectName": "江南皮革厂",
"otherContractSubjectIds": "30",
"otherContractSubjecSupplierNos": "",
"ourContractSubjectName": "神州优车武汉分公司",
"ourContractSubjectId": "89",
"statusOurContractSubjectName": "",
"preEffectiveDateStr": "",
"endDateType": "0",
"endDateStr": "",
"contractEffectiveDateStr": "",
"contractSignatoryName": "",
"contractSignatoryId": "",
"departmentName": "",
"departmentId": "",
"plateName": "",
"plateId": "",
"cityName": "",
"constractTermsRemarks": ""
},
"pay": {
"taxUnitPrice": 100.32,
"untaxUnitPrice": 0,
"num": 200,
"taxAllPrice": 90000,
"sumPayPrice": "",
"unPayPrice": "",
"invoiceType": "1",
"invoiceTime": "0",
"foregift": 50000,
"foregiftDates": "2019-10-05",
"freeStartDates": "2019-03-08",
"freeEndDates": "2019-03-30",
"installPayType": "1",
"warrantyMoneyType": "",
"preLastPrice": 0,
"taxRate": 0,
"bankAccount": "",
"bankIds": "",
"beforePayPrice": 0,
"leaseTotalMoney": 0,
"propertyTotalMoney": 0,
"amountRemarks": ""
},
"other": {
"createUser": "",
"createTime": "",
"updateTime": "",
"companyPlane": "",
"mobile": "",
"nodeType": "",
"updateUserId": ""
},
"information": [{
"term": 1,
"money": 111,
"pricePrezent": 1,
"prePayTime": 11,
"days": 0
}, {
"term": 2,
"money": 222,
"pricePrezent": 2,
"prePayTime": 22,
"days": 0
}, {
"term": 3,
"money": 333,
"pricePrezent": 3,
"prePayTime": 33,
"days": 0
}]
}复制代码
解决办法:
1、前端请求采用JSON格式的字符串
JSON.stringify(this.form)复制代码
2、后台接收前端提交的JSON格式字符串数据
@RequestMapping(value = "/todo", method = RequestMethod.POST)
@ResponseBody
public Result todo(@RequestBody String param) { try {
ContractDetailVO vo = resolverObjectIncludeArrayByJSON(param, ContractDetailVO.class);
log.info("{}", vo);
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}复制代码
具体实现方法:
/**
* 解析JSON对象中包含数组
* @param JOSNStr
* @param t
* @param
* @return
* @throws NoSuchFieldException
* @throws IOException
* @throws IllegalAccessException
* @throws InstantiationException
*/
private static T resolverObjectIncludeArrayByJSON(String JOSNStr, Class t) throws NoSuchFieldException, IOException, IllegalAccessException, InstantiationException {
ObjectMapper mapper = new ObjectMapper();
// 将JSON字符串转换成JsonNode格式
JsonNode jsonNode = mapper.readTree(JOSNStr);
Iterator> elements = jsonNode.fields();
// 实例化返回对象
T clazz = t.newInstance();
// 遍历JSONNode节点数据
while(elements.hasNext()) {
Map.Entry node = elements.next();
// 获取当前节点的key值
String key = node.getKey();
// 反射传入转换对象的key值对应的属性
Field field = clazz.getClass().getDeclaredField(key);
field.setAccessible(true);
// 获取当前key值对应的类
Class cls = t.getDeclaredField(key).getType();
// 判断是否为集合对象
if(StringUtils.equals(cls.getName(), "java.util.List")) {
ParameterizedType p = (ParameterizedType)t.getDeclaredField(key).getGenericType();
Class c = (Class)p.getActualTypeArguments()[0];
// 集合对象只用Array进行实例化
Object array = mapper.readValue(node.getValue().toString(), Array.newInstance(c, 1).getClass());
// 遍历Array,并且set到返回对象对应的属性中
if(array != null && Array.getLength(array) > 0) {
List list = new ArrayList();
for(int i = 0; i < Array.getLength(array); i++){
list.add(Array.get(array, i));
}
field.set(clazz, list);
}
} else {
// 转换的对象set到返回对象的属性中
Object obj = mapper.readValue(node.getValue().toString(), cls);
field.set(clazz, obj);
}
}
return clazz;
}复制代码