json中date类型数据为空造成转JAVA对象失败

本文介绍了一种解决Java中JSON转换时遇到的日期格式错误或为空导致的JSONException问题的方法。通过对ezmorph-1.0.6.jar中的DateMorpher类进行修改,使程序能够正确处理日期为空的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在学习java对象和json互相转换,发现当java对象里date类型属性值为null时,

会报如下异常:

net.sf.json.JSONException: Error while setting property=date type class java.lang.String

看了下json-lib的源码,才发现Json转Java的时候,调用ezmorph-1.0.6.jar中的DateMorpher类有问题:

如果date的格式错误或者为空(总之就是转换错误)的时候,没有对错误处理。

就在net.sf.ezmorph.object.DateMorpher的这一段

Java代码  收藏代码
  1. try{   
  2.        return dateParser.parse( strValue.toLowerCase() );  
  3.  } catch( ParseException pe ){   
  4.      // ignore exception, try the next format   
  5. }   

 所以我改成如下样子

Java代码  收藏代码
  1. try{  
  2.    return dateParser.parse( strValue.toLowerCase() );  
  3. }  
  4. catch( ParseException pe ){  
  5.    return null;  
  6. }  

 

 这样就行了。

测试结果如下:



 

附件是修改后的ezmorph-1.0.6.jar,下载即可用。

 

<think>我们讨论了如何在JavaScript中安全地将JSON数据换为Map对象。用户提供的引用内容中提到了一些方法,但主要是在Java环境下的换,而我们需要的是JavaScript的解决方案。引用[1]和[引用2]提供了JavaScript中Map与JSON互相换的方法,我们可以重点参考。问题:如何在JavaScript中安全地将JSON数据换为Map对象?步骤:1.首先,我们需要解析JSON字符串(如果输入是字符串)为JavaScript对象。2.然后,我们将这个对象换为Map。注意:JSON数据可能是对象或数组,我们这里主要考虑对象,因为Map的键值对结构对应对象。安全考虑:-解析JSON时使用try-catch来避免无效的JSON字符串。-检查解析后的数据类型,确保它是一个对象(非数组)才进行换。如果JSON表示的是数组,我们也可以将其换为Map,但需要决定如何设置键(例如使用索引?还是数组中的某个属性?)。这里我们主要讨论对象形式的JSON。方法:参考引用[2]中的反向操作:将Map换为JSON时使用了Object.fromEntries(map),那么反过来,将对象换为Map可以使用newMap(Object.entries(object))。具体步骤:1.使用JSON.parse()将JSON字符串解析为JavaScript对象(如果输入是字符串的话)。2.使用Object.entries()将对象换为键值对数组。3.使用newMap()将这个键值对数组换为Map。注意:如果JSON字符串表示的是数组,那么Object.entries()也可以处理数组(数组会被视为键为下标的对象),但这样得到的Map键是字符串形式的数字(数组下标)。但通常,如果原始数据是数组,我们可能更希望保持为数组而不是Map。因此,我们需要根据输入数据的结构来决定换方式。如果用户明确知道输入是一个对象(键值对),那么我们可以按照上述方法换。如果输入可能是数组,我们则需要额外的逻辑来处理。为了安全,我们可以:-首先解析JSON字符串。-判断解析后的数据类型:如果是对象(且不是数组),则换为Map。如果是数组,则可以根据需要选择是否换(例如,如果数组元素是对象,并且我们想用某个属性作为键,那么可以遍历数组构造Map,但这不是标准的换)。因此,我们这里提供一个通用的方法:将对象形式的JSON换为Map。对于数组,我们不做换(或者抛出一个错误,或者返回一个以索引为键的Map,根据需求决定)。下面我们提供两个函数:1.一个安全的JSON解析函数,可以处理字符串并返回解析后的数据。2.一个将对象(非数组)换为Map的函数。但是,为了更通用,我们也可以提供一个选项,允许用户传入一个回调函数来决定如何换数组。然而,根据问题,我们只关注将对象换为Map,所以我们可以这样实现:代码实现:```javascript/***将JSON字符串安全地换为Map对象*@param{string}jsonStr-JSON字符串*@returns{Map}换后的Map对象,如果JSON解析失败数据不是对象(比如是数组,我们这里不换数组,而是将其作为一个值,但为了安全,我们只对象)则返回Map或抛出错误(根据设计)*注意:我们这里设计为只对象。如果解析结果是数组,我们会抛出一个错误,或者返回一个Map,或者也可以将其视为一个键为索引的对象换,但这样不符合常规。因此,我们只对象。*/functionjsonToMap(jsonStr){try{constobj=JSON.parse(jsonStr);//检查解析后的obj是否是对象,并且不是数组(因为数组也是对象,但我们不希望用数组构建Map)if(typeofobj==='object'&&obj!==null&&!Array.isArray(obj)){returnnewMap(Object.entries(obj));}else{//这里可以处理数组情况,但我们按照约定不换数组,我们可以返回一个Map,或者抛出错误,或者根据情况换数组//我们选择返回一个Map,并打印警告console.warn('InputJSONisanarrayornotanobject.ExpectedanobjecttoconverttoMap.');returnnewMap();//返回Map}}catch(e){console.error('InvalidJSONstring',e);returnnewMap();//返回Map}}```但是,如果我们想处理数组并换为Map(用数组下标作为键),可以这样修改:```javascriptfunctionjsonToMap(jsonStr){try{constdata=JSON.parse(jsonStr);if(typeofdata==='object'&&data!==null){//如果是数组,我们也要换吗?如果需要,我们可以换,但要注意数组换为Map时,键是索引(字符串形式的数字)//使用Object.entries可以处理数组,数组会返回[索引,元素]的数组returnnewMap(Object.entries(data));}else{console.warn('InputJSONisnotanobjectorarray.');returnnewMap();}}catch(e){console.error('InvalidJSONstring',e);returnnewMap();}}```第二种实现对于数组和对象都可以换,但数组换后的Map的键是索引(字符串),值是对应的元素。另外,还有一种情况:如果JSON字符串表示的是一个字符串、数字等基本类型,那么解析后的数据就不是对象,我们就无法换为Map,所以返回Map。用户的安全换需求包括:-无效JSON字符串的处理(返回Map并打印错误)-非对象类型处理(根据设计决定是否换)考虑到用户问题,通常我们期望的JSON数据是一个对象。所以,我们可以提供两种方法,一种只对象,另一种可以对象和数组。我们也可以提供一个更灵活的方法,让用户自己决定如何换:```javascriptfunctionjsonToMap(jsonStr,arrayConversion=false){try{constdata=JSON.parse(jsonStr);if(typeofdata==='object'&&data!==null){if(Array.isArray(data)){if(arrayConversion){//如果允许数组换,将数组换为Map,键为索引returnnewMap(Object.entries(data));}else{thrownewError('JSONdataisanarray,butarrayConversionflagisnotsettotrue.');}}else{returnnewMap(Object.entries(data));}}else{thrownewError('JSONdataisnotanobjectorarray.');}}catch(e){console.error('ErrorconvertingJSONtoMap:',e);returnnewMap();}}```但是,由于用户要求“安全”,我们应尽可能减少意外。因此,我们默认不换数组(因为数组通常应该用数组的方式处理),所以使用第一种方法(只对象)可能更符合预期。综上,我们推荐第一种方法(只对象,非对象则返回Map并警告)。此外,注意:JSON字符串中可能包含嵌套对象,但我们的换只会换最外层的对象,内部的嵌套对象并不会换为Map(仍然是对象)。如果用户希望将所有嵌套对象换为Map,则需要递归处理。但是,递归换可能会导致性能问题,而且设计起来更复杂。因此,我们这里只换最外层。所以,我们最终给出只换最外层对象(非数组)的函数,内部嵌套对象保持不变。测试:```javascriptconstjsonStr='{"name":"Alice","age":25,"address":{"city":"NewYork"}}';constmap=jsonToMap(jsonStr);console.log(map.get('name'));//Aliceconsole.log(map.get('address'));//{city:"NewYork"},注意这里是一个普通对象,而不是Map```如果用户希望将嵌套的对象换为Map,我们需要递归函数:```javascriptfunctiondeepJsonToMap(jsonStr){functionconvert(obj){if(typeofobj==='object'&&obj!==null){//如果是数组,则递归处理每个元素if(Array.isArray(obj)){returnobj.map(item=>convert(item));}//如果是对象,则创建一个新Map,并递归处理每个值constmap=newMap();Object.entries(obj).forEach(([key,value])=>{map.set(key,convert(value));});returnmap;}returnobj;}try{constdata=JSON.parse(jsonStr);returnconvert(data);}catch(e){console.error('InvalidJSONstring',e);returnnewMap();}}```这个深度换函数会将对象以及嵌套对象换为Map,如果是数组,则递归换数组中的每个元素(如果元素是对象,也会被换为Map)。但注意,这样换后,原数组会变成Map吗?不会,数组会被换成新数组,数组中的元素如果是对象换为Map。而对于原对象,则直接换为Map。测试深度换:```javascriptconstjsonStr='{"name":"Alice","address":{"city":"NewYork"},"friends":[{"name":"Bob"},{"name":"Charlie"}]}';constmap=deepJsonToMap(jsonStr);console.log(map.get('address')instanceofMap);//trueconsole.log(map.get('friends'));//[Map,Map],数组,其中每个元素是Mapconsole.log(map.get('friends')[0].get('name'));//"Bob"```根据用户需求,我们可以提供浅换(仅最外层)或深换(递归全部对象)两种方式。总结回答:在JavaScript中安全地将JSON数据换为Map对象,我们可以:1.安全解析JSON字符串(使用try-catch)。2.检查解析后的数据类型。3.对于非嵌套需求,使用`newMap(Object.entries(object))`对象。4.根据需求选择是否递归换嵌套对象。我们提供了两个函数:`jsonToMap`(浅换)和`deepJsonToMap`(深换)。建议:如果JSON数据结构简单(没有嵌套对象)或者我们只需要操作顶层属性,使用浅换即可。如果需要操作嵌套属性且希望它们也是Map,则使用深换。注意:深换可能会消耗更多资源(特别是嵌套很深的大对象),并且丢失原对象的一些特性(例如原型链),但它提供了更一致的Map结构。因此,回答中应包含这两种方法。接下来按照用户的要求组织回答:-分步骤说明-提供代码示例-注意LaTeX格式(但这个问题没有数学公式)-生成相关问题</think> ### 如何在 JavaScript 中安全地将 JSON 数据换为 Map 对象JavaScript 中安全地将 JSON 数据换为 Map 对象需要处理数据完整性、错误防护和类型安全。以下是详细的实现方法: #### **基础换方法** 1. **解析 JSON换为对象** ```javascript try { const jsonStr = '{"name":"Alice","age":30}'; const jsonObj = JSON.parse(jsonStr); // 安全解析 } catch (e) { console.error("无效的JSON格式", e); } ``` 2. **对象 Map 的核心方法** ```javascript // 方法1:使用 Object.entries() const mapFromObject = (obj) => new Map(Object.entries(obj)); // 方法2:遍历属性(更可控) const safeMapFromObject = (obj) => { const map = new Map(); Object.keys(obj).forEach(key => { map.set(key, obj[key]); }); return map; }; ``` #### **安全增强措施** 1. **类型校验** ```javascript const jsonToSafeMap = (jsonStr) => { try { const data = JSON.parse(jsonStr); if (!data || typeof data !== 'object') { throw new Error("非对象类型"); } return new Map(Object.entries(data)); } catch (e) { console.error(`失败: ${e.message}`); return new Map(); // 返回Map而非null } }; ``` 2. **嵌套对象处理** ```javascript const deepJsonToMap = (obj) => { if (typeof obj !== 'object' || obj === null) return obj; const map = new Map(); Object.entries(obj).forEach(([key, value]) => { // 递归处理嵌套对象 map.set(key, typeof value === 'object' ? deepJsonToMap(value) : value); }); return map; }; ``` #### **使用示例** ```javascript const jsonData = '{"user":{"name":"Bob","prefs":{"theme":"dark"}}'; const userMap = jsonToSafeMap(jsonData); console.log(userMap.get('user')); // 输出: Map {'name' => 'Bob', 'prefs' => Map{...}} ``` #### **安全注意事项** 1. **输入验证** - 使用 `JSON.parse()` 前检查字符串有效性 - 正则验证:`/^[\],:{}\s]*$/.test(str.replace(/\\["\\\/bfnrtu]/g, '@'))` 2. **循环引用处理** ```javascript const safeMap = (obj, seen = new WeakSet()) => { if (seen.has(obj)) return '[Circular]'; seen.add(obj); // ...换逻辑 }; ``` 3. **特殊类型支持** - 日期对象:`value instanceof Date ? new Date(value) : value` - BigInt:需自定义序列化方案 #### **反向换(Map JSON)** ```javascript const mapToJson = (map) => { return JSON.stringify(Object.fromEntries(map)); }; ``` ### **最佳实践总结** 1. 始终使用 `try/catch` 包裹 `JSON.parse()` 2. 校验输入数据类型 (`typeof`, `instanceof`) 3. 对嵌套对象使用递归换 4. 处理循环引用等边界情况 5. 提供默认值或 Map 而非 `null` [^1] [^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值