2013-09-26 22 views
2

我有一個類似的JSON結構:反序列化傑克遜通過使用密鑰值

"teams": { 
    "team1Id": "team1Name", 
    "team2Id": "team2Name" 
} 

,我想將其反序列化到這些Java類:

class Teams { 
Team team1; 
Team team2; 
} 

class Team { 
String id; 
String name; 
} 

正如你所看到的應該將作爲JSON密鑰的team1Id和team2Id轉換爲Java字段的值。此外,第一個teamId/teamName對應該歸入存儲在team1中的對象,而第二個對存儲在team2字段中。

是否有任何本機JACKSON映射器來做到這一點,或者我需要爲此創建自己的定製解串器?

+0

即JSON,雖然有效的不匹配類的語義。您將需要編寫您的自定義解串器。你擁有的是一種獨立的格式。 –

+0

你是完全正確的。儘管這是從第三方檢索到的JSON。我不控制它的模式。 – andresp

+0

這真的很奇怪。你能否展示結果團隊對象在反序列化之後應該是什麼樣子?我的意思是,如果我在團隊對象上調用toString()方法,它應該打印什麼? => [Team team1 = [Team id = team1Name,name = null],team2 = [Team id = team2Name,name = null]? –

回答

3

您可以爲這個類實現自定義的反序列化器,但是,我認爲,更簡單的解決方案將使用@JsonAnySetter註釋。

class Teams { 

    Team team1 = new Team(); 
    Team team2 = new Team(); 

    @JsonAnySetter 
    public void anySetter(String key, String value) { 
     if (key.startsWith("team1")) { 
      team1.setId(key); 
      team1.setName(value); 
     } else if (key.startsWith("team2")) { 
      team2.setId(key); 
      team2.setName(value); 
     } 
    } 

    //getters, setterr, toString() 
} 

實例:

import java.io.File; 
import java.io.IOException; 

import com.fasterxml.jackson.annotation.JsonAnySetter; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonProgram { 

    public static void main(String[] args) throws IOException { 
     ObjectMapper mapper = new ObjectMapper(); 
     Wrapper wrapper = mapper.readValue(new File("X:/json"), Wrapper.class); 
     System.out.println(wrapper.getTeams()); 
    } 
} 

class Wrapper { 

    private Teams teams; 

    public Teams getTeams() { 
     return teams; 
    } 

    public void setTeams(Teams teams) { 
     this.teams = teams; 
    } 
} 

以上程序打印:

Teams [team1=Team [id=team1Id, name=team1Name], team2=Team [id=team2Id, name=team2Name]] 

此JSON:

{ 
    "teams": { 
     "team1Id": "team1Name", 
     "team2Id": "team2Name" 
    } 
} 

### EDIT 1 ###

如果你的JSON看起來像這樣:

{ 
    "teams": { 
     "12345": "Chelsea", 
     "67890": "Tottenham" 
    } 
} 

我建議把它反序列化到LinkedHashMap<String, String>,之後將其轉換爲Teams對象。示例程序:

import java.io.File; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.LinkedHashMap; 
import java.util.List; 
import java.util.Map.Entry; 

import com.fasterxml.jackson.databind.ObjectMapper; 

public class JacksonProgram { 

    public static void main(String[] args) throws IOException { 
     ObjectMapper mapper = new ObjectMapper(); 
     Wrapper wrapper = mapper.readValue(new File("X:/json"), Wrapper.class); 
     System.out.println(wrapper.toTeams()); 
    } 
} 

class Wrapper { 

    private LinkedHashMap<String, String> teams; 

    public LinkedHashMap<String, String> getTeams() { 
     return teams; 
    } 

    public void setTeams(LinkedHashMap<String, String> teams) { 
     this.teams = teams; 
    } 

    public Teams toTeams() { 
     List<Team> teamList = toTeamList(); 

     Teams result = new Teams(); 
     result.setTeam1(teamList.get(0)); 
     result.setTeam2(teamList.get(1)); 
     return result; 
    } 

    private List<Team> toTeamList() { 
     List<Team> teamList = new ArrayList<Team>(teams.size()); 
     for (Entry<String, String> entry : teams.entrySet()) { 
      Team team = new Team(); 
      team.setId(entry.getKey()); 
      team.setName(entry.getValue()); 
      teamList.add(team); 
     } 

     return teamList; 
    } 
} 

上面的程序打印:

Teams [team1=Team [id=12345, name=Chelsea], team2=Team [id=67890, name=Tottenham]] 
+0

謝謝。我不能使用「team1」和「team2」前綴來標識屬性。 team1和team2是變量,就像team1Name和team2Name一樣。我只是介紹它們來推斷解析背後的語義。 混凝土JSON的一個實例是這樣的: \t 「團隊」:{ \t \t 「12345」: 「切爾西」, \t \t 「67890」: 「熱刺」 \t} 儘管如此,使用AnySetter看起來像一個有趣的方法,只要我可以推斷鍵值對出現在JSON中的順序(第一個團隊應存儲在team1字段中,第二個團隊存儲在team2字段中)。可能嗎? – andresp