getting variable name change in android using gson - java

I am making an android application using google Gson to parse to and from json classes that I have in other project.
I have a class Person which contains attributes like:
public class Person {
private String firstName;
private String lastName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String name) {
this.firstName = name;
}
}
But when I'm debugging in the MainActivity.java I see a or b as attribute names instead of firstName and lastName, and that's make the json text be:
{a:"someName", b:"someLastName"}
does anyone know's why is this and how can I fix it?
class Person.java is located in a separated project. I think that my project can't see the source code and that would be the reason.
I'm kind of lost here.
Thank you

Related

How does jackson #JsonGetter and #JsonSetter work

I am using jackson 2.10.0 (https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core/2.10.0), following is a simple test case
The Person class is defined as follows, for the setters, I have used the #JsonSetter annotation, and didn't use #JsonGetter for the getters,
import com.fasterxml.jackson.annotation.JsonProperty;
public class Person {
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
#JsonSetter("first_name")
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
#JsonSetter("last_name")
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Then, I create a Person object ,and serialize it as string,
import com.fasterxml.jackson.databind.ObjectMapper;
public class Person3Test2 {
public static void main(String[] args) throws Exception {
Person p = new Person();
p.setFirstName("abc");
p.setLastName("def");
String str = new ObjectMapper().writeValueAsString(p);
System.out.println(str);
}
}
It will call Person's getters, since it doesn't use #JsonGetter, so I think the output should be
{"firstName":"abc","lastName":"def"}
But, I am surprised to find that it is :
{"first_name":"abc","last_name":"def"}
It looks that the #JsonSetter has affected the getter output, I would ask what's the behavior here.
#JsonSetter will effect during serialization also here is the github issue, if you want different name just use another annotation #JsonGetter on get method
Documentation may be wrong; #JsonSetter does not only affect deserialization. While it can indeed be used for asymmetric naming (similar to #JsonProperty itself with "split" annotation), its scope is not limited.
It may have been at some point, but after unification of property handling (in 1.8 or so), there is less separation between various property accessors.
I can review Javadocs to make it clear that none of annotations is strictly limited in scope -- some may only be relevant to one or the other, but none is intentionally separated.

Spring boot relaxed binding not working

I am new to spring boot. I want to achieve relaxed binding in spring boot. As per this documentation https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-relaxed-binding.
It says, even though if we have name with dashes(like first-name) in .properties file, it can be mapped to variable without dashes(like firstName). But it didn't seems to be working.
I have application.properties file like below:
person.first-name=orcl
person.address=xyz
And my Properties util java file looks like:
#ConfigurationProperties(prefix="person")
#Component
#PropertySource("file: application.properties")
public class ApplicationPropertiesUtil
{
private String firstName;
private String address;
public String getfirstName()
{
return firstName;
}
public void setfirstName(String firstName)
{
this.firstName = firstName;
}
public String getaddress()
{
return address;
}
public void setaddress(String address)
{
this.address = address;
}
}
address property is getting bind properly, but for firstname it is null.
The problem is your setter methods which don't align with java bean standard.
It should be named "setFirstName" with an upper case F.

Generate Different types of XMl with same class using JAXB

I have one class:
#XmlRootElement(name="pickup")
public class PickUp
{
#XmlAttribute(name="contactName")
public String contactName;
#XmlAttribute(name="phoneNumber")
public String phoneNumber;
#XmlAttribute(name="pickupDate")
public String pickupDate;
#XmlAttribute(name="pickupTime")
public String pickupTime;
#XmlAttribute(name="closingTime")
public String closingTime;
#XmlAttribute(name="location")
public String location;
}
This will generate XMl like this:
<Pickup contactName="Test Name" phoneNumber="888-888-8888" pickupDate="2009-08-03" pickupTime="16:30" closingTime="17:45" location="Front Door"/>
This is working perfect, but with same code i also want to generate Xml like below:
<Pickup>
<contactName>Test Name</contactName>
<phoneNumber>888-888-8888</phoneNumber>
<pickupDate>2009-08-03</pickupDate>
<pickupTime>16:30</pickupTime>
<closingTime>17:45</closingTime>
<location>Front Door</location>
</Pickup>
I can do this by creating another class with #xmlElement but i want to use same class for this.
Please help me.
I found this https://stackoverflow.com/a/33096124/1976843 answer that can help you.
If you want to keep using jaxb you will need to write your own AnnotationReader
Your are using tags for XML attributes. Use #XmlElement tags to generate the XML in your required format you should give the tags as
#XmlElement
public String getContactName() {
return contactName;
}
public void setcontactName(String name) {
this.contactName= name;
}
#XmlElement
public String getphoneNumber() {
return phoneNumber;
}
public void setphoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
No need to create a new class. You can do changes in your original class for xml element.

Spring java custom get-method in domain model class

Using Spring data I would like to be able to define a custom get-method inside a domain model class without affecting the model itself. For example, using this model:
#Document
public class Person
{
private String firstName;
private String lastName;
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName = lastName;
}
}
Eveything is working fine so far: the model Person has the fields 'firstName' and 'lastName' and I can successfully save a 'person'. The resulting JSON has the fields 'firstName' and 'lastName'. Now I would like to add some additional data in the JSON without affecting the model and its save-operations, something like this:
#Document
public class Person
{
private String firstName;
private String lastName;
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName = lastName;
}
// custom method
public String getFullName()
{
return firstName+" "+lastName;
}
}
The JSON should contain the same data as before, but this time also an additional 'fullName'-field. However, at the same time the data model assumes an additional field 'fullName' is added and filled with null-values when saving into the database.
I have already tried annotations like #Transient, but this does not work. The documentation states "by default all private fields are mapped to the document, this annotation excludes the field where it is applied from being stored in the database", so it only can be applied to private fields in the class, not to get-methods.
What is the correct way to do this in Spring? Of course I can extend the class Person and include the getFullName-method there, but I was wondering if it is possible to include everything in one class.
Edit:
I use Elasticsearch as DB engine using spring-data-elasticsearch 1.2.0.RELEASE. I have just tested MongoDB as alternative and then it is working fine, even without the #Transient annotation. I think the index-method of the ElasticsearchRepository is serializing the provided class instance when saving it to the database. In that way the JSON-output and the saved data are always identical. Any suggestions?

Why to override toString Method inside DTO

I see that Most of the times in the DTO object ,
the toString Method is actaully overridden .
For example :
public class Person implements Serializable {
private String firstName;
private String lastName;
private int age;
/**
* Creates a new instance of Person
*/
public Person() {
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//Overriding toString to be able to print out the object in a readable way
//when it is later read from the file.
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(firstName);
buffer.append("\n");
buffer.append(lastName);
buffer.append("\n");
buffer.append(age);
buffer.append("\n");
return buffer.toString();
}
}
Could anybody please tell me what is the use of doing so ??
The answer is in your code comment. When debugging, you want to be able to print a human readable representation of your object. If you don't override toString you will most likely have a representation like:
Person#129cfbb
It makes the debugger easier to use. In Eclipse (and I believe in nearly every IDE), the debugger shows the output of toString() on an object by default.
Edit: As other's have pointed out, there are plenty of other uses: logging, display in a GUI element, or anywhere else you need to convert the object to text for display.
This is to have some proper output (as returned by toString() implementation) instead of the standard implementation of java.lang.Object (will be something like your.package.Person#...) when printing the object or when you append it to another string.
There are numerous uses. Among others : to display this object in a combobox in a GUI, to debug, for some unit testing assertions...
Overriding toString to be able to print out the object in a readable way when it is later read from the file.
Sorry, couldn't resist. In all seriousness, toStrings are valuable to be overridden for any Java class. However, I would wager a DTO in particular is good to have a toString, because the object is meant to transfer data. Often, this means printing out the data into readable format.

Categories