我有两个使用YML子集的JSON格式的文件,其中一个是设备列表,另一个是列出特定类型设备属性的文件。
将设备实例列表分为一个文件,将属性分为另一个文件的选择是为了使设备制造商可以更改属性,而不必返回并重新编写/重新编译硬编码属性。
无论如何,我可以对JSONParser使用两个不同的调用,然后最后将属性列表添加到Device对象,但是这种解决方案似乎浪费了代码,因为while循环的内部除外,设置了值,它们做的完全相同。
我以为像Ruby-ish Yield之类的方法可能会在内部循环中解决问题,但不确定Java中是否存在这种方法。
因此,事不宜迟,这里是代码:
// Import the json simple parser, used to read configuration files import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.JSONValue; import org.json.simple.parser.*; public class LoadJson { private String path = ""; private String fileType = ""; //public LoadJson(String path, String fileType){ //this.path = path; //this.fileType = fileType; //} public static Device openJSON(String fileType, String deviceName) { JSONParser parser = new JSONParser(); Device myDevice = new Device(); ContainerFactory containerFactory = new ContainerFactory(){ public List creatArrayContainer() { return new LinkedList(); } public Map createObjectContainer() { return new LinkedHashMap(); } }; try { File appBase = new File("."); //current directory String path = appBase.getAbsolutePath(); System.out.println(path); Map obj = (Map)parser.parse(new FileReader(path+fileType),containerFactory); Iterator iter = obj.entrySet().iterator(); //Iterator iterInner = new Iterator(); while(iter.hasNext()){ //LinkedList entry = (LinkedList)iter.next(); LinkedList myList = new LinkedList(); Map.Entry entry = (Map.Entry)iter.next(); myList = (LinkedList) (entry.getValue()); Iterator iterate = myList.iterator(); while (iterate.hasNext()) { LinkedHashMap entry2 = (LinkedHashMap)iterate.next(); if(fileType=="mav2opc") { String deviceName1 = entry2.get("DeviceName").toString(); String userName = entry2.get("UserName").toString(); String password = entry2.get("Password").toString(); String deviceType = entry2.get("DeviceType").toString(); String ipAddress = entry2.get("IPAddress").toString(); myDevice = new Device(deviceName1, userName, password, deviceType,ipAddress); openJSON(deviceType,deviceName1); System.out.println(myDevice); } else { //Add a tag String tagName = entry2.get("tagName").toString(); String tagType = entry2.get("tagType").toString(); String tagXPath = entry2.get("tagXPath").toString(); String tagWritable = entry2.get("tagWritable").toString(); } } } //System.out.println("==toJSONString()=="); //System.out.println(JSONValue.toJSONString(json)); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch(ParseException pe){ System.out.println(pe); } return myDevice; }
}
好的,所以您有两个文件,一个包含设备列表,另一个包含每个设备的文件,每个文件都具有设备属性。这两个文件的结构完全相同,我猜是这样的
设备文件:
{{"DeviceName:"d1","UserName":"u1","Password":"p1","DeviceType":"t1","IPAddress":"i1"}, {"DeviceName:"d2","UserName":"u2","Password":"p2","DeviceType":"t2","IPAddress":"ir"}}
和每个设备的文件
{{"tagName:"n1","tagType":"t1","tagXPath":"X1","tagWritable":true}}
每个设备文件中只有一个映射,尽管它在列表中。处理逻辑是打开文件,创建解析器,读取json并为列表中的每个条目处理地图。
处理地图的逻辑是两者之间的唯一区别。请注意,现在您正在丢弃从每个设备文件中读取的内容,您必须将其存储在myDevice
myDevice
一种实现方法是使用回调:创建一个MapHandler具有method 的接口process。openJSON接受此类型的参数并process为每个方法调用它。
MapHandler
process
openJSON
可以使用myDevice正在处理的设备级处理程序来构造并设置字段。