How would GSON handle that? How would it be possible for me to make a
class to read this file into? Obviously I can't have spaces in my
variable names.
public class Name {
private final String firstName;
private final String lastName;
// Used for deserialization
private Name() {
this("", "");
}
public Name(String firstName, String lastName) {
this.firstName = Preconditions.checkNotNull(firstName);
this.lastName = Preconditions.checkNotNull(lastName);
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getFullName() {
return getFirstName() + " " + getLastName();
}
}
-----------------------------------------
For this case, I can see two different options:
Option #1 - You can modify the "Name" class. Now your implementation
would look as follows:
public class Name {
@SerializedName("First Name") private final String firstName;
@SerializedName("Last Name") private final String lastName;
// Everything else stays the same
}
Option #2 - Create your own FieldNamingStrategy implementation. This
approach is preferred if in general you want to convert all Java
fields from the common pattern "someFieldName" to "Some Field Name".
This general naming strategy would be implemented as follows (NOTE:
this is for Gson 1.4):
public MyNamingStrategy implements FieldNamingStrategy2 {
@Override
public String translateName(FieldAttributes f) {
String fieldName = capitalizedFirstLetter(f.getName());
return insertWordSplitterToken(fieldName, " ");
}
private static String capitalizeFirstLetter(String target) {
char firstCharacter = target.charAt(index);
if (!Character.isUpperCase(firstCharacter)) {
return Character.toUpperCase(firstCharacter) +
target.substring(1);
} else {
return target;
}
}
private static String insertWordSplitterToken(String target, String
separatorToken) {
StringBuilder translation = new StringBuilder();
for (int i = 0; i < target.length(); i++) {
char character = target.charAt(i);
if (Character.isUpperCase(character) && translation.length() !=
0) {
translation.append(separatorToken);
}
translation.append(character);
}
return translation.toString();
}
}
Now you would create your Gson instance as follows:
Gson gson = new GsonBuilder()
.setFieldNamingStrategy(new MyNamingStrategy())
.create();
Not sure how common this is, but if multiple clients use this
"spacing" naming policy then maybe it would be wise to implement is as
a supported "FieldNamingPolicy".
Hope this helps,
Joel
I changed it to:
class Person
{
@SerializedName("First Name")
String firstName;
@SerializedName("Last Name")
String lastName;
}
but got this error:
Exception in thread "main" java.lang.IllegalArgumentException: First
Name is not a valid JSON field name.
at
com.google.gson.JsonFieldNameValidator.validate(JsonFieldNameValidator.java:
63)
at
com.google.gson.SerializedNameAnnotationInterceptingNamingPolicy.translateName(SerializedNameAnnotationInterceptingNamingPolicy.java:
48)
at
com.google.gson.JsonObjectDeserializationVisitor.getFieldName(JsonObjectDeserializationVisitor.java:
93)
at
com.google.gson.JsonObjectDeserializationVisitor.visitFieldUsingCustomHandler(JsonObjectDeserializationVisitor.java:
98)
at
com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java:
141)
at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:122)
at
com.google.gson.JsonDeserializationContextDefault.fromJsonObject(JsonDeserializationContextDefault.java:
73)
at
com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:
49)
at com.google.gson.Gson.fromJson(Gson.java:379)
at com.google.gson.Gson.fromJson(Gson.java:352)
at Tester.main(Tester.java:15)
and this is my json file:
{
"First Name": "John",
"Last Name": "Smith"
}
class MyNamingStrategy implements FieldNamingStrategy
{
@Override
public String translateName(Field f)
{
System.out.println("Field: "+f.getName());
String name = f.getName().replace(" ","");
String toReturn = (name.charAt(0)+"").toLowerCase() +
name.substring(1);
System.out.println(toReturn);
return toReturn;
}
}
When it prints the f.getName() it prints the name of the variable in
the Person class, rather than the name of the field in the JSON file.
My problem is that the names of my fields in the JSON file have spaces
in them and I want to put them into a class without spaces in variable
names.
This is fixed in r546 which will be included in the full 1.4 Gson
release.
As an FYI, the Field Naming Strategies map for Java to the JSON
representation. This is because we take the Java Class object as the
source of truth and map it to its JSON representation.
Hope this helps,
Joel
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE_WITH_SPACES)
.create();
Let me know,
Joel