一、前端给的JSON数据格式:
{
"positionConstruct": [{
"positionCode": "2",
"positionName": "小张",
"productLine": "生产线",
"customer": "饭店",
"customerLevel": "特级",
"customerRegion": "线上",
"customerClassify": "餐饮",
"outSysKey": "1q",
"productLineId": "1231445",
"customerCode": "1231244"
},{
"positionCode": "2",
"positionName": "小里",
"productLine": "生产线",
"customer": "饭店",
"customerLevel": "特级",
"customerRegion": "线上",
"customerClassify": "餐饮",
"outSysKey": "2w",
"productLineId": "1231445",
"customerCode": "1231244"
},
{
"positionCode": "2",
"positionName": "小章",
"productLine": "生产线",
"customer": "饭店",
"customerLevel": "特级",
"customerRegion": "线上",
"customerClassify": "餐饮",
"outSysKey": "3e",
"productLineId": "1231445",
"customerCode": "1231244"
}
]
}
注意,上面的JSON是一个JSON数组包着3个JSON对象!
二、Controller层完成转换
事先声明!前端传来的JSON,虽然是一串json,但是controller接收的String类型(形参str),不被认为是一段JSON。必须先使用阿里巴巴的JSON工具转换成JSON格式!
@RequestMapping(value = "/save", method = RequestMethod.POST)
public void save(@RequestBody String str) throws Exception{ //要加上@RequestBody
JSONObject json=JSON.parseObject(str); //先将传入的字符串转换成JSONObject
JSONArray arr=(JSONArray)json.get("positionConstruct"); //然后将3个JSON对象组成一个JSON数组
//JSONObject jo = new JSONObject(new String(str));
for(Object pc:arr){
String s = JsonUtils.objectToJson(pc); //遍历JSON数组,使用工具类将每个JSON对象转换成标准的字符串JSON
PositionContrast pos=JsonUtils.jsonToPojo(s,PositionContrast.class); //使用工具类将JSON字符串转换成POJO实体类(注意,这里要传入实体类.class)
pcs.save(pos); //将得到的POJO传入service层
}
}
简单解释下,核心就是利用阿里巴巴提供的fastjson工具:
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
第一步:先将传入的字符串转换成JSONObject
第二步:然后将3个JSON对象组成一个JSON数组
第三步:遍历JSON数组,使用工具类将每个JSON对象转换成标准的字符串JSON
这一步对应之前所说的:
前端传来的JSON,虽然是一串json,但是controller接收的String类型(形参str),不被认为是一段JSON。必须先使用阿里巴巴的JSON工具转换成JSON格式!我打印了一下转换前转换后的两串字符串(其实就是s和str这两个变量,发现这两个字符串的确不一样)
第四步:使用工具类将JSON字符串转换成POJO实体类
第五步:将得到的POJO传入service层,处理结束
三、处理json的工具类:
其实就是对fasterxml.jackson进行二次封装,代码如下:
package cn.xxwlh.api.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
public class JsonUtils {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 将对象转换成json字符串。
* @param data
* @return
*/
public static String objectToJson(Object data) {
try {
String string = MAPPER.writeValueAsString(data);
return string;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
/**
* 将json结果集转化为对象
*
* @param jsonData json数据
* @param
* @return
*/
public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
try {
T t = MAPPER.readValue(jsonData, beanType);
return t;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将json数据转换成pojo对象list
* <p>Title: jsonToList</p>
* <p>Description: </p>
* @param jsonData
* @param beanType
* @return
*/
public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
try {
List<T> list = MAPPER.readValue(jsonData, javaType);
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
四、json转pojo反序列化错误(摘自网络):
问题出现原因:
前端传入JSON字符串,如果有pojo类没有的字段,在转换成pojo时,就会出问题。
解决方案:
https://cloud.tencent.com/developer/article/1648032
我使用的方法是在pojo上加注解。注解名字是@JsonIgnoreProperties(ignoreUnknown = true)
,ignoreUnknown的意思是忽视未知。顾名思义,前端传入JSON字符串,如果有pojo类没有的字段,在转换成pojo时就会被忽略。
五、补充:如果前端传来的JSON格式是对象包对象
第一节里面,是一个JSON数组包着多个JSON对象。那如果是一个JSON对象包着多个JSON对象呢?像这样:
{
{"resdata":"
{
"_entityName":"null",
"_keyName":"null",
"job_name":"测试职位01",
"customer_name":"崂山鸡鸭店",
"customerType_name":"成都前置仓客户",
"custtype_name":"冻产",
"salearea_name":"烟台",
"product_name":"生鸡-鸡鲜品",
"enable":1,
"tenant_id":"rkvvw7qj",
"job":"2183575469363456",
"customer":2184783722123776,
"customerType":2182055851315712,
"custtype":2179465457931008,
"salearea":2183637457853440,
"product":2183636308219136,
"_status":null,
"id":"2196111745585408",
"creator":"34022",
"createTime":1617240023546,
"enablets":1617240023000,
"pubts":1617240024000
}
"}
不知道为啥,上面的JSON代码放到解析里面会报错。可能是因为转义问题。下面加上转义之后就不报错了:
反正意思就是对象包对象。
处理方式(假设上文入参的JSON字符串是str):
JSONObject json= JSON.parseObject(str); //先将传入的字符串转换成JSONObject
String resdata = json.getString("resdata"); //取得包在里面的resdata层
JSONObject resdataObject = JSON.parseObject(resdata); //重新解析字符串为JSONObject
String s = JsonUtils.objectToJson(resdataObject);//将JSONObject转成JSON字符串
SaleOrder order = JsonUtils.jsonToPojo(s, SaleOrder.class);//将JSON字符串转换成pojo
关键就是这一行代码:
String resdata = json.getString("resdata"); //取得包在里面的resdata层
相当于剥开了resdata这一个外层,拿到里面的内层JSON对象
总结
工作中对JSON的处理还有很多,先记录一部分,后续补充