我如何为这个 json 输入定义 Gson java class
How do i define Gson java class for this json input
如何为 Json 定义轨道以反序列化此 json
"user": {
"authority": "user",
"title": "Renata Tebaldi Serenata Tebaldi [Disc 2]",
"artist": "Renata Tebaldi",
"tracks": {
"1": "Track 01 - BELLINI: Vaga luna che inargenti",
"2": "Track 02 - BELLINI: Per pieta bel ‘idol mio",
"3": "Track 03 - MASCAGNI: M’ama ... Non m’ama",
"4": "Track 04 - RESPIGHI: Notte",
"5": "Track 05 - TOSTI: ‘A vuchella",
"6": "Track 06 - DAVICO: O luna che fa lume",
"7": "Track 07 - DONIZETTI: Me voglio fa ‘na casa",
"8": "Track 08 - MASCAGNI: La tua Stella",
"9": "Track 09 - TOSTI: Sogno",
"10": "Track 10 -ROSSINI: L’invito",
"11": "Track 11 - ZANDONAI: L’assiulo",
"12": "Track 12 - CIMARA: Stormello",
"13": "Track 13 - PONCHIELLI: Noi leggevamo insieme",
"14": "Track 14 - MASCAGNI: Serenato",
"15": "Track 15 - PARISOTTI: Se tu m’ami",
"16": "Track 16 - PARADISI: M’ha presa alla sua ragna",
"17": "Track 17 - SCARLATTI: O cessati di piagarmi",
"18": "Track 18 - GLUCK: O dell mio dolce ardor",
"19": "Track 19 - RICCI: Il carrettiere del Vomero",
"20": "Track 20 - MERCADANTE: La sposa del marinaro",
"21": "Track 21 - BELLINI: Malliconia, ninfa gemtile",
"22": "Track 22 - PUCCINI: E l’luccelino"
}
},
我对User的定义如下
public class UnitiCoreUser
{
private String authority;
private String artist;
private String title;
public String getAuthority()
{
return authority;
}
public void setAuthority(String authority)
{
this.authority = authority;
}
public String getArtist()
{
return artist;
}
public void setArtist(String artist)
{
this.artist = artist;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
}
我的问题是轨道,因为其中的元素不是按名称固定的,即它们都是相同的,但标记为 1,2,3,4,... 所以不能只有一个轨道数组。
例如曲目[]曲目;
尝试使用 Map
:
Map<Integer, String> tracks;
这是一个例子(你展示的 class 和你展示的 JSON 也不完全匹配):
import com.google.gson.Gson;
import java.util.Map;
public class TestApp {
public TestApp() {
String test = "{\"user\":{\"authority\":\"user\",\"title\":\"Renata Tebaldi Serenata Tebaldi [Disc 2]\",\"artist\":\"Renata Tebaldi\",\"tracks\":{\"1\":\"Track 01 - BELLINI: Vaga luna che inargenti\",\"2\":\"Track 02 - BELLINI: Per pieta bel \u2018idol mio\",\"3\":\"Track 03 - MASCAGNI: M\u2019ama ... Non m\u2019ama\",\"4\":\"Track 04 - RESPIGHI: Notte\",\"5\":\"Track 05 - TOSTI: \u2018A vuchella\",\"6\":\"Track 06 - DAVICO: O luna che fa lume\",\"7\":\"Track 07 - DONIZETTI: Me voglio fa \u2018na casa\",\"8\":\"Track 08 - MASCAGNI: La tua Stella\",\"9\":\"Track 09 - TOSTI: Sogno\",\"10\":\"Track 10 -ROSSINI: L\u2019invito\",\"11\":\"Track 11 - ZANDONAI: L\u2019assiulo\",\"12\":\"Track 12 - CIMARA: Stormello\",\"13\":\"Track 13 - PONCHIELLI: Noi leggevamo insieme\",\"14\":\"Track 14 - MASCAGNI: Serenato\",\"15\":\"Track 15 - PARISOTTI: Se tu m\u2019ami\",\"16\":\"Track 16 - PARADISI: M\u2019ha presa alla sua ragna\",\"17\":\"Track 17 - SCARLATTI: O cessati di piagarmi\",\"18\":\"Track 18 - GLUCK: O dell mio dolce ardor\",\"19\":\"Track 19 - RICCI: Il carrettiere del Vomero\",\"20\":\"Track 20 - MERCADANTE: La sposa del marinaro\",\"21\":\"Track 21 - BELLINI: Malliconia, ninfa gemtile\",\"22\":\"Track 22 - PUCCINI: E l\u2019luccelino\"}}}";
UnitiCoreUser user = new Gson().fromJson(test, UnitiCoreUser.class);
}
public static void main(String[] args) {
new TestApp();
}
public class UnitiCoreUser {
private User user;
public User getUser() {
return user;
}
}
class User {
public String authority;
private String artist;
private String title;
Map<Integer, String> tracks;
public String getAuthority() {
return authority;
}
public void setAuthority(String authority) {
this.authority = authority;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Map<Integer, String> getTracks() {
return tracks;
}
}
}
你必须使用
Map<String,String> tracks
会自动反序列化为map。
Gson 有类型适配器可以处理一些奇怪的事情。这些类型适配器可以 read/write JSON 元素映射它们 to/from 类,并进行一些额外的检查(例如,类似数组的映射验证)。
public final class SequentiveMapTypeAdapterFactory
implements TypeAdapterFactory {
private static final ConstructorConstructor constructorConstructor = new ConstructorConstructor(ImmutableMap.of(
List.class, type -> new ArrayList<>()
));
private SequentiveMapTypeAdapterFactory() {
}
@Override
@Nullable
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
final Class<? super T> rawType = typeToken.getRawType();
if ( !List.class.isAssignableFrom(rawType) ) {
return null;
}
final Type type = typeToken.getType();
final Type elementType = $Gson$Types.getCollectionElementType(type, rawType);
@SuppressWarnings("unchecked")
final TypeAdapter<T> typeAdapter = (TypeAdapter<T>) new SequentiveMapTypeAdapter<>(
(ObjectConstructor<? extends List<Object>>) constructorConstructor.get(typeToken),
(TypeAdapter<Object>) gson.getAdapter(TypeToken.get(elementType))
);
return typeAdapter.nullSafe();
}
private static final class SequentiveMapTypeAdapter<E>
extends TypeAdapter<List<E>> {
private final ObjectConstructor<? extends List<E>> objectConstructor;
private final TypeAdapter<E> elementTypeAdapter;
private SequentiveMapTypeAdapter(final ObjectConstructor<? extends List<E>> objectConstructor, final TypeAdapter<E> elementTypeAdapter) {
this.objectConstructor = objectConstructor;
this.elementTypeAdapter = elementTypeAdapter;
}
@Override
public void write(final JsonWriter out, final List<E> list) {
throw new UnsupportedOperationException();
}
@Override
public List<E> read(final JsonReader in)
throws IOException {
in.beginObject();
final List<E> list = objectConstructor.construct();
for ( int i = 1; in.hasNext(); i++ ) {
final String name = in.nextName();
if ( !name.equals(String.valueOf(i)) ) {
throw new JsonParseException("Expected " + i + " but was name " + name);
}
final E element = elementTypeAdapter.read(in);
list.add(element);
}
in.endObject();
return list;
}
}
}
那么您的映射对象应该知道如何通过注释相应的字段将 JSON 对象转换为列表或数组:
final class UnitiCoreUser {
String authority;
String artist;
String title;
@JsonAdapter(SequentiveMapTypeAdapterFactory.class)
List<String> tracks;
}
然后它将起作用:
final UnitiCoreUser unitiCoreUser = gson.fromJson(jsonReader, UnitiCoreUser.class);
for ( final String track : unitiCoreUser.tracks ) {
System.out.println(track);
}
输出:
Track 01 - BELLINI: Vaga luna che inargenti
Track 02 - BELLINI: Per pieta bel ‘idol mio
Track 03 - MASCAGNI: M’ama ... Non m’ama
Track 04 - RESPIGHI: Notte
Track 05 - TOSTI: ‘A vuchella
Track 06 - DAVICO: O luna che fa lume
Track 07 - DONIZETTI: Me voglio fa ‘na casa
Track 08 - MASCAGNI: La tua Stella
Track 09 - TOSTI: Sogno
Track 10 -ROSSINI: L’invito
Track 11 - ZANDONAI: L’assiulo
Track 12 - CIMARA: Stormello
Track 13 - PONCHIELLI: Noi leggevamo insieme
Track 14 - MASCAGNI: Serenato
Track 15 - PARISOTTI: Se tu m’ami
Track 16 - PARADISI: M’ha presa alla sua ragna
Track 17 - SCARLATTI: O cessati di piagarmi
Track 18 - GLUCK: O dell mio dolce ardor
Track 19 - RICCI: Il carrettiere del Vomero
Track 20 - MERCADANTE: La sposa del marinaro
Track 21 - BELLINI: Malliconia, ninfa gemtile
Track 22 - PUCCINI: E l’luccelino
尝试使用 属性 Map tracks
如何为 Json 定义轨道以反序列化此 json
"user": {
"authority": "user",
"title": "Renata Tebaldi Serenata Tebaldi [Disc 2]",
"artist": "Renata Tebaldi",
"tracks": {
"1": "Track 01 - BELLINI: Vaga luna che inargenti",
"2": "Track 02 - BELLINI: Per pieta bel ‘idol mio",
"3": "Track 03 - MASCAGNI: M’ama ... Non m’ama",
"4": "Track 04 - RESPIGHI: Notte",
"5": "Track 05 - TOSTI: ‘A vuchella",
"6": "Track 06 - DAVICO: O luna che fa lume",
"7": "Track 07 - DONIZETTI: Me voglio fa ‘na casa",
"8": "Track 08 - MASCAGNI: La tua Stella",
"9": "Track 09 - TOSTI: Sogno",
"10": "Track 10 -ROSSINI: L’invito",
"11": "Track 11 - ZANDONAI: L’assiulo",
"12": "Track 12 - CIMARA: Stormello",
"13": "Track 13 - PONCHIELLI: Noi leggevamo insieme",
"14": "Track 14 - MASCAGNI: Serenato",
"15": "Track 15 - PARISOTTI: Se tu m’ami",
"16": "Track 16 - PARADISI: M’ha presa alla sua ragna",
"17": "Track 17 - SCARLATTI: O cessati di piagarmi",
"18": "Track 18 - GLUCK: O dell mio dolce ardor",
"19": "Track 19 - RICCI: Il carrettiere del Vomero",
"20": "Track 20 - MERCADANTE: La sposa del marinaro",
"21": "Track 21 - BELLINI: Malliconia, ninfa gemtile",
"22": "Track 22 - PUCCINI: E l’luccelino"
}
},
我对User的定义如下
public class UnitiCoreUser
{
private String authority;
private String artist;
private String title;
public String getAuthority()
{
return authority;
}
public void setAuthority(String authority)
{
this.authority = authority;
}
public String getArtist()
{
return artist;
}
public void setArtist(String artist)
{
this.artist = artist;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
}
我的问题是轨道,因为其中的元素不是按名称固定的,即它们都是相同的,但标记为 1,2,3,4,... 所以不能只有一个轨道数组。
例如曲目[]曲目;
尝试使用 Map
:
Map<Integer, String> tracks;
这是一个例子(你展示的 class 和你展示的 JSON 也不完全匹配):
import com.google.gson.Gson;
import java.util.Map;
public class TestApp {
public TestApp() {
String test = "{\"user\":{\"authority\":\"user\",\"title\":\"Renata Tebaldi Serenata Tebaldi [Disc 2]\",\"artist\":\"Renata Tebaldi\",\"tracks\":{\"1\":\"Track 01 - BELLINI: Vaga luna che inargenti\",\"2\":\"Track 02 - BELLINI: Per pieta bel \u2018idol mio\",\"3\":\"Track 03 - MASCAGNI: M\u2019ama ... Non m\u2019ama\",\"4\":\"Track 04 - RESPIGHI: Notte\",\"5\":\"Track 05 - TOSTI: \u2018A vuchella\",\"6\":\"Track 06 - DAVICO: O luna che fa lume\",\"7\":\"Track 07 - DONIZETTI: Me voglio fa \u2018na casa\",\"8\":\"Track 08 - MASCAGNI: La tua Stella\",\"9\":\"Track 09 - TOSTI: Sogno\",\"10\":\"Track 10 -ROSSINI: L\u2019invito\",\"11\":\"Track 11 - ZANDONAI: L\u2019assiulo\",\"12\":\"Track 12 - CIMARA: Stormello\",\"13\":\"Track 13 - PONCHIELLI: Noi leggevamo insieme\",\"14\":\"Track 14 - MASCAGNI: Serenato\",\"15\":\"Track 15 - PARISOTTI: Se tu m\u2019ami\",\"16\":\"Track 16 - PARADISI: M\u2019ha presa alla sua ragna\",\"17\":\"Track 17 - SCARLATTI: O cessati di piagarmi\",\"18\":\"Track 18 - GLUCK: O dell mio dolce ardor\",\"19\":\"Track 19 - RICCI: Il carrettiere del Vomero\",\"20\":\"Track 20 - MERCADANTE: La sposa del marinaro\",\"21\":\"Track 21 - BELLINI: Malliconia, ninfa gemtile\",\"22\":\"Track 22 - PUCCINI: E l\u2019luccelino\"}}}";
UnitiCoreUser user = new Gson().fromJson(test, UnitiCoreUser.class);
}
public static void main(String[] args) {
new TestApp();
}
public class UnitiCoreUser {
private User user;
public User getUser() {
return user;
}
}
class User {
public String authority;
private String artist;
private String title;
Map<Integer, String> tracks;
public String getAuthority() {
return authority;
}
public void setAuthority(String authority) {
this.authority = authority;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Map<Integer, String> getTracks() {
return tracks;
}
}
}
你必须使用
Map<String,String> tracks
会自动反序列化为map。
Gson 有类型适配器可以处理一些奇怪的事情。这些类型适配器可以 read/write JSON 元素映射它们 to/from 类,并进行一些额外的检查(例如,类似数组的映射验证)。
public final class SequentiveMapTypeAdapterFactory
implements TypeAdapterFactory {
private static final ConstructorConstructor constructorConstructor = new ConstructorConstructor(ImmutableMap.of(
List.class, type -> new ArrayList<>()
));
private SequentiveMapTypeAdapterFactory() {
}
@Override
@Nullable
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
final Class<? super T> rawType = typeToken.getRawType();
if ( !List.class.isAssignableFrom(rawType) ) {
return null;
}
final Type type = typeToken.getType();
final Type elementType = $Gson$Types.getCollectionElementType(type, rawType);
@SuppressWarnings("unchecked")
final TypeAdapter<T> typeAdapter = (TypeAdapter<T>) new SequentiveMapTypeAdapter<>(
(ObjectConstructor<? extends List<Object>>) constructorConstructor.get(typeToken),
(TypeAdapter<Object>) gson.getAdapter(TypeToken.get(elementType))
);
return typeAdapter.nullSafe();
}
private static final class SequentiveMapTypeAdapter<E>
extends TypeAdapter<List<E>> {
private final ObjectConstructor<? extends List<E>> objectConstructor;
private final TypeAdapter<E> elementTypeAdapter;
private SequentiveMapTypeAdapter(final ObjectConstructor<? extends List<E>> objectConstructor, final TypeAdapter<E> elementTypeAdapter) {
this.objectConstructor = objectConstructor;
this.elementTypeAdapter = elementTypeAdapter;
}
@Override
public void write(final JsonWriter out, final List<E> list) {
throw new UnsupportedOperationException();
}
@Override
public List<E> read(final JsonReader in)
throws IOException {
in.beginObject();
final List<E> list = objectConstructor.construct();
for ( int i = 1; in.hasNext(); i++ ) {
final String name = in.nextName();
if ( !name.equals(String.valueOf(i)) ) {
throw new JsonParseException("Expected " + i + " but was name " + name);
}
final E element = elementTypeAdapter.read(in);
list.add(element);
}
in.endObject();
return list;
}
}
}
那么您的映射对象应该知道如何通过注释相应的字段将 JSON 对象转换为列表或数组:
final class UnitiCoreUser {
String authority;
String artist;
String title;
@JsonAdapter(SequentiveMapTypeAdapterFactory.class)
List<String> tracks;
}
然后它将起作用:
final UnitiCoreUser unitiCoreUser = gson.fromJson(jsonReader, UnitiCoreUser.class);
for ( final String track : unitiCoreUser.tracks ) {
System.out.println(track);
}
输出:
Track 01 - BELLINI: Vaga luna che inargenti
Track 02 - BELLINI: Per pieta bel ‘idol mio
Track 03 - MASCAGNI: M’ama ... Non m’ama
Track 04 - RESPIGHI: Notte
Track 05 - TOSTI: ‘A vuchella
Track 06 - DAVICO: O luna che fa lume
Track 07 - DONIZETTI: Me voglio fa ‘na casa
Track 08 - MASCAGNI: La tua Stella
Track 09 - TOSTI: Sogno
Track 10 -ROSSINI: L’invito
Track 11 - ZANDONAI: L’assiulo
Track 12 - CIMARA: Stormello
Track 13 - PONCHIELLI: Noi leggevamo insieme
Track 14 - MASCAGNI: Serenato
Track 15 - PARISOTTI: Se tu m’ami
Track 16 - PARADISI: M’ha presa alla sua ragna
Track 17 - SCARLATTI: O cessati di piagarmi
Track 18 - GLUCK: O dell mio dolce ardor
Track 19 - RICCI: Il carrettiere del Vomero
Track 20 - MERCADANTE: La sposa del marinaro
Track 21 - BELLINI: Malliconia, ninfa gemtile
Track 22 - PUCCINI: E l’luccelino
尝试使用 属性 Map