2014-09-29 39 views
2

是否有任何自定義JSON來通過某些配置將json屬性映射到Java對象屬性的java對象分析器。json to java對象自定義分析器

假設我有類

class Person { String id; String name; String loc;} 

我的JSON字符串是

{name:"xy",id:12, address: {location: "abc"}} 

我需要映射JSON的location.addressPersonloc財產。我們需要通過配置XML或prop文件來驅動這個映射。

EDITED ....

我想有語法或 如屬性文件中定義的規則:

address.location = loc 
id = id 
name = name 

這是我在想什麼。不知道如何映射覆雜的類型,比如列表,地圖等

所以我的代碼將調用一個方法

Person p = ObjectMapper.map(jsonData,Person.class,configuration) 

和實際映射所做的就是這樣

class ObjectMapper { 
public static <T> T map(String jsonData,Class<T> rootType, Map<String,String> rules) { 

    T object = rootType.newInstance(); 
    // TODO: code to parse json using the rules 
    //and finally return object 

    return (T) object; 
} 

這是我正打算做。任何幫助表示讚賞。 在此先感謝。

+1

https://code.google.com/p/google-gson/和更多的細節:http://pragmateek.com/javajson-mapping-with-gson/#A_simple_Java-JSON_mapping – Dan 2014-09-29 15:00:43

+0

我們展示的代碼你已經試過並描述你有什麼問題。 – 2014-09-29 15:01:02

+1

我們可以使用反射同樣的東西。 – 2014-09-30 06:42:50

回答

-1

導入這個庫項目code.google.com/p/google-gson

之後,就可以做到這一點: (「JSON」是要在解析任何JSON字符串這可能是你在你的問題中指定的一個。 )

Person personFromJson = new Gson().fromJson(json, Person.class); 
+1

我不認爲OP的例子可以很容易地處理,因爲沒有1對1的屬性映射。 – 5gon12eder 2014-09-29 15:30:41

+0

啊,當然是! – ChristopherMortensen 2014-09-29 16:09:14

2

使用下面的代碼。

import java.lang.reflect.Method; 
import java.lang.reflect.Type; 
import java.util.HashMap; 
import java.util.Map; 

import com.google.gson.Gson; 
import com.google.gson.reflect.TypeToken; 

public class Test { 

    public static void main(String... args) throws Exception{ 
     Map<String, String> rules = new HashMap<>(); 
     rules.put("address.location", "loc"); 
     rules.put("name", "name"); 
     rules.put("id", "id"); 

     String jsonData = "{name:'xy',id:'12', address: {location: 'abc'}, phones: ['a', 'b', 'c']}"; 

     Person person = (Person) map(jsonData, Person.class, rules); 
     System.out.println(new Gson().toJson(person)); 
    } 

    public static Object map(String jsonData, Class<?> rootType, Map<String, String> rules) throws Exception{ 
     Map<String, Object> genericMap = new HashMap<>(); 
     Type type = new TypeToken<Map<String, Object>>() {}.getType(); 
     genericMap = new Gson().fromJson(jsonData, type); 

     Object object = rootType.newInstance(); 

     for (Map.Entry<String, String> entry : rules.entrySet()){ 
      String mapKey = entry.getKey(); 
      String mapValue = entry.getValue(); 

      String keys[] = mapKey.split("\\."); 
      Map<String, Object> obj = null; 
      if(keys.length > 1){ 
       obj = (Map<String, Object>) genericMap.get(keys[0]); 
       for(int i=1;i<keys.length-1;i++){ 
        obj = (Map<String, Object>) obj.get(keys[i]); 
       } 
       // Method method = object.getClass().getDeclaredMethod("set" + capitalize(mapValue) , String.class); 
       // method.invoke(object, (String)obj.get(keys[keys.length-1])); 
       Field field = object.getClass().getDeclaredField(mapValue); 
       field.set(object, obj.get(keys[keys.length - 1])); 
      }else{ 
       // Method method = object.getClass().getDeclaredMethod("set" + capitalize(mapValue) , String.class); 
       // method.invoke(object, (String)genericMap.get(mapValue)); 

       Field field = object.getClass().getDeclaredField(mapValue); 
       field.set(object, genericMap.get(mapValue)); 
      } 
     } 
     return object; 
    } 

    public static String capitalize(String line){ 
     return Character.toUpperCase(line.charAt(0)) + line.substring(1); 
    } 
} 

class Person { 
    String id; 
    String name; 
    String loc; 

    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getLoc() { 
     return loc; 
    } 

    public void setLoc(String loc) { 
     this.loc = loc; 
    } 

} 

輸出

{"id":"12","name":"xy","loc":"abc","phones":["a","b","c"]} 

詳細

  • 使用Gson API。
  • 此代碼適用於n個被引用的對象(如a.b.c.item)。
  • 你的類應該包含每個字段的getter/setter。
  • 規則和POJO的字段名稱應匹配。
+0

感謝您分享代碼。這將工作甚至列表,地圖和複雜類型(如人有一些ProfessionDetails)。假設我有一個電話號碼對象phoneNumber的列表,其中包含字段交換代碼,用戶號碼和需要映射到Person Object的列表屬性。在這種情況下,我應該如何定義我的規則。我正在考慮定義像L-> phonenumbers.exchangecode = L-> phonenumbers.exchangecode。 L代表List。 C – CompuDynasty 2014-09-30 08:59:42

+0

目前我假設你的字符串類型的所有字段,請參閱(「設置」+大寫(mapValue),String.class)。但是你可以使用反射來給出一個數據類型。我也試過List。 – 2014-09-30 09:03:27

+0

更改了代碼以支持集合,現在您必須根據您的要求更改解析器。你可以根據你的需求創建你自己的解析器。 – 2014-09-30 09:09:48