使用ObjectMapper().writeValueAsString(data)时谨慎在data类中使用get开头的函数!

在项目开发中,遇到JSON文档生成包含notNull的问题,经排查发现是由于`getNotNull`函数名与Java默认getter方法冲突。解决办法是修改函数名,避免使用以`get`开头,确保`ObjectMapper.writeValueAsString`正确调用。

问题出现

在最近写的一个项目中,需要把一个实体对象以json文档的形式储存。
其中包含这样的一个类:
在这里插入图片描述
一开始使用**ObjectMapper().writeValueAsString(data)**时可以非常正常地生成以下json:
在这里插入图片描述

后面一直在正常进行开发,直到有一天打开了一下生成的json文档,发现里面出现了奇怪的东西:

在这里插入图片描述
是的就是放在第一个的notNull

问题定位

其实整个生成json文档的逻辑非常简单,就是读数据,生成相应的json格式字符串,最后写入文档。
问题只可能出现在生成json格式的位置!通过debug也可以很容易的验证这个结论。
全局搜索notnull发现只有一个函数包括了这两个单词:
在这里插入图片描述

问题解决

当时第一反应是getNotNull这个函数名是不是和其他函数名冲突了,于是我把函数名改为了getOneList,结果输出的json文档变成了这样:

在这里插入图片描述
这样的话问题就很显然了,应该是**ObjectMapper().writeValueAsString(data)**在生成json格式的字符时会调用data类中全部的getter方法。

所以解决方法就是把函数名改掉,不使用get开头

public boolean syncDeviceInfo(Integer deviceId) { // 获取Omada设备信息 OmadaDeviceInfoPO deviceInfo = omadaDeviceInfoRepository.findById(deviceId) .orElseThrow(() -> new RuntimeException("Omada device info does not exist")); // 合法性校验 if (deviceInfo.getStatus().equals(OmadaDeviceInfoPO.STATUS_ONLINE) && !deviceInfo.getStatus().equals(OmadaDeviceInfoPO.STATUS_OFFLINE)) { throw new RuntimeException("The equipment must be in an offline state before it can be brought online"); } try { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 处理 imageInfo 并替换 image_bucket_path 中的路径为预签名 URL String processedImageInfo = processAndReplaceImageUrls(deviceInfo.getImageInfo()); deviceInfo.setImageInfo(processedImageInfo); // 构造请求数据 HashMap<String, String> formData = new HashMap<>(); String omadaDeviceInfo = objectMapper.writeValueAsString(deviceInfo); formData.put("omadaDeviceInfo", omadaDeviceInfo); String formDataJson = objectMapper.writeValueAsString(formData); // ===== Step 3: 发送 HTTP 请求 ===== HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> entity = new HttpEntity<>(formDataJson, headers); RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:9090/actuator/omadaDeviceInfo"; ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class); if (!response.getStatusCode().is2xxSuccessful()) { throw new RuntimeException( "syn to common data error:,HTTP status: " + response.getStatusCode() + ", response: " + response.getBody()); } return true; } catch (Exception e) { log.error("omada device info syn error: " + e.getMessage(), e); return false; } } 修改这个函数的入参为String dataDetails,这个就是deviceInfo的JSON字符串
10-22
我用springboot写的代码是 @Override public CompletableFuture<String> getPayMentData(PayMentIsReqVO jsonStr, SftpConfig config, String url,String id) { ThreadPoolExecutor executor = ThreadPoolConfig.getInstance(); CompletableFuture<String> future = new CompletableFuture<>(); executor.execute(() -> { PayMentEsResVO payMentEsResVO = new PayMentEsResVO(); String str = ""; ObjectMapper objectMapper = new ObjectMapper(); try { Map<String, Object> resultMap = Utils.convertObjectToJson(jsonStr, null, true, Arrays.asList("amount")); // 指定转换为List log.info("resultMap: " + resultMap); List<Map<String, Object>> list = new ArrayList<>(); list.add(resultMap); String jsonString = objectMapper.writeValueAsString(list); String responseData = sendIsPOST(jsonString, config, url); payMentEsResVO = ConverObj.paymentObjIsRes(responseData); log.info("payMentEsResVO: " + payMentEsResVO); HeaderVO headerVO = new HeaderVO(); headerVO.setIfId(id); ResponeVO responeVO = new ResponeVO(); responeVO.setPayload(payMentEsResVO); responeVO.setHeader(headerVO); ResponeResVO responeResVO = new ResponeResVO(); responeResVO.setResponse(responeVO); // str = objectMapper.writeValueAsString(payMentEsResVO); byte[] utf8JsonBytes = objectMapper.writeValueAsString(responeResVO).getBytes(StandardCharsets.UTF_8); str = new String(utf8JsonBytes, StandardCharsets.UTF_8); future.complete(str); } catch (Exception e) { payMentEsResVO.setMSGTY("E"); payMentEsResVO.setMESSG(e.toString()); try { str = objectMapper.writeValueAsString(payMentEsResVO); } catch (JsonProcessingException ex) { ex.printStackTrace(); } future.complete(str); // 将异常传递给CompletableFuture } }); return future; } public class ThreadPoolConfig { private static final int CORE_POOL_SIZE = 3; // 核心线程数 private static final int MAX_POOL_SIZE = 5; // 最大线程数 private static final long KEEP_ALIVE_TIME = 1L; // 非核心线程闲置1s private static final int QUEUE_CAPACITY = 5; // 工作队列的容量 private static volatile ThreadPoolExecutor executor = null; public static ThreadPoolExecutor getInstance() { if (executor == null) { synchronized (ThreadPoolConfig.class) { if (executor == null) { executor = new ThreadPoolExecutor( CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new ArrayBlockingQueue<>(QUEUE_CAPACITY), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy() ); } } } return executor; } 帮我改成Django代码
10-11
第一部分: WOMProduceTask outPutTask = produceTaskDao.get(Long.valueOf(vo.getBindTaskId())); CustomOutputMaterialDTO customOutputMaterialDTO = new CustomOutputMaterialDTO(); customOutputMaterialDTO.setProcessFlag(false); customOutputMaterialDTO.setIsSave(false); customOutputMaterialDTO.setDeleteIdList(new ArrayList<>()); customOutputMaterialDTO.setTaskId(Long.valueOf(vo.getBindTaskId())); List<WOMOutputDetail> outputDetailList = new ArrayList<>(); //单投料仅一个物料不需要列表 WOMOutputDetail outputDetail = new WOMOutputDetail(); outputDetail.setArtificialNum(new BigDecimal(vo.getPreFeedNum())); outputDetail.setContain(null); BaseSetMaterial product = new BaseSetMaterial(); product.setId(outPutTask.getProductId().getId()); product.setCode(outPutTask.getProductId().getCode()); product.setName(outPutTask.getProductId().getName()); outputDetail.setProduct(product); outputDetail.setReportNum(new BigDecimal(vo.getPreFeedNum())); outputDetailList.add(outputDetail); customOutputMaterialDTO.setOutputDetailList(outputDetailList); String outputData = ""; try{ //outputData = objectMapper.writeValueAsString(customOutputMaterialDTO); outputData = JSONObject.toJSONString(customOutputMaterialDTO); }catch (Exception e){ throw new BAPException("生成跨级工单产出报工单失败"); } log.error("生成跨级工单产出报工单:{}", outputData); Map<String, Object> stringObjectMap = taskActiveService.conformOutput(outputData);第二部分: public Map<String, Object> conformOutput(String data) { Map<String, Object> resultMap = new HashMap<>(); Date operateTime = new Date(); Staff staff = (Staff) getCurrentStaff(); ObjectMapper objectMapper = new ObjectMapper(); log.error("PDA确认产出data:" + data); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); CustomOutputMaterialDTO outputData = null; try { outputData = objectMapper.readValue(data, new TypeReference<CustomOutputMaterialDTO>() { }); } catch (IOException e) { throw new BAPException(e); } //产出明细 List<WOMOutputDetail> outputDetailList = outputData.getOutputDetailList(); log.error("产出明细:{}", outputDetailList);现已知第一部分代码的日志记录:生成跨级工单产出报工单:{"deleteIdList":[],"isSave":false,"outputDetailList":[{"artificialNum":0.200,"product":{"code":"40013947","effectiveState":0,"extraColMap":{},"id":5545720264681840,"isPrintBarcode":false,"matState":{"attribute":false,"children":[],"children2":[],"code":"valid","id":"BaseSet_matState/valid","isParent":true,"layNo":0,"leaf":false,"leaf2":false,"root":true,"uniqueCode":"null/valid","valid":true,"version":0},"name":"C37溶液","valid":true,"version":0},"reportNum":0.200,"valid":true,"version":0}],"processFlag":false,"taskId":5717687965183968}为什么第二部分的产出明细日志记录outputDetailList列表为Null
08-20
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值