Let's suppose that I have the next class:
public class MyClass {
private String name;
private String surName;
private String phone;
private String address;
private String gender;
}
I want to parametrize obsidian job to do something similar like this:
#Parameter(name="sample", type= Type.STRING, required=false)
But instead of String type, I want MyClass.java type
Any idea how to do it?
Related
I try to parse reponse from Api to my custom object.
Most fields are parsed correctly, except fields named like: eMail, iKindName, bNumber, uTypeName, iStartDT, iKindCd, uTypeCd (first small, second capital letter)
In fields like that I have null values if I use my custom object ResponseV2.
If I use Object type instead of ResponseV2 - fields eMail, iKindName, bNumber, uTypeName, iStartDT, iKindCd, uTypeCd are not null
Whats wrong with that fields (with pattern: first small and second capital letter) in my ReponseV2? Should I use some annotations, like #JsonProperty here?
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
#Data
public class ResultV2 implements Serializable {
private String country;
private String federationNumber;
private String city;
private String regon;
private String managerSurname;
private String countryCd;
private String pib;
private String institutionUuid;
private String lNumber;
private String siTypeName;
private String managerName;
private String ministryNumber;
private String eMail;
private String supervisingInstitutionID;
private String nip;
private String street;
private String www;
private String espAddress;
private String voivodeship;
private String id;
private String iKindName;
private String federationComposition;
private String lastRefresh;
private String postalCd;
private String bNumber;
private String panNumber;
private List<BranchesV2> branches;
private String krs;
private String supervisingInstitutionName;
private String iLiqStartDT;
private String eunNumber;
private String uTypeName;
private String institutionUid;
private String phone;
private String iStartDT;
private String iLiqDT;
private String name;
private String iKindCd;
private String siTypeCd;
private String yearPib;
private String uTypeCd;
private String dataSource;
private String voivodeshipCode;
private String status;
private String statusCode;
}
I have solution: it works if I have
#JsonProperty ("eMail") private String eMail;
instead of
private String eMail;
But why?
Lombok #Data annotation is generating setter method as
public void setEMail(final String eMail) {
this.eMail = eMail;
}
However json mapper expects the setter method to be with lower case letter e like in example below, so it could not find the method.
public void seteMail(final String eMail) {
this.eMail = eMail;
}
Just use JsonProperty like #JsonProperty("eMail") on those fields. It would work fine.
Here is a detailed explanation on why it work like this: Why does Jackson 2 not recognize the first capital letter if the leading camel case word is only a single letter long?
In my Android project I have two types of response where both response are identical except two keys.
Response 1
{"fullName":"William Sherlock Scott Holmes","address":"221B Baker Street, London, England, UK","downloads":642,"rating":3,"repos":["https://link1","https://link2","https://link3"]}
Response 2
{"name":"Sherlock","city":"London","downloads":642,"rating":3,"repos":["https://link1","https://link2","https://link3"]}
If you see the responses only two key names are changing fullName/name and address/city
I don't want to create one more pojo for other response. My question is: is it possible to use only one Pojo to read both responses?
public class AccountInfo {
private String name;
private String city;
//other objects
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
//other setters and getters
}
Any help will be appreciated...
You can annotate the members to accept values from two different json names using the #SerializedName annotation:
#SerializedName(value = "name", alternate = {"fullName"})
private String name;
#SerializedName(value = "city", alternate = {"address"})
private String city;
Either named element can then be placed into the members that are annotated like this.
UPDATED :
#SerializedName alternate names when deserializing is added in Version 2.4
Yes, you can totally use one POJO class for deserializing both responses. Your POJO class will contain keys from both responses.
public class Response {
private String name;
private String city;
private String fullName;
private String address;
private Integer downloads;
private Integer rating;
private List<String> repos ;
}
But when using the Response class, be careful that for first response, the name and city will be null, and for the second one, the address and fullname.
Yeah you can do that in a single POJO. Try this:
public class POJO {
#SerializedName("name")
public String name;
#SerializedName("city")
public String city;
#SerializedName("fullName")
public String fullName;
#SerializedName("address")
public String address;
#SerializedName("downloads")
public Integer downloads;
#SerializedName("rating")
public Integer rating;
#SerializedName("repos")
public List<String> repos = new ArrayList<String>();
}
While parsing you have to check values for null. For eg -
While Parsing Response 1: name and city variables will be null
While Parsing Response 2: fullname and address will be null
Note : Try checking values for null before using else you'll get nullpointerexception
Define all possible fields in your POJO Class like
public class AccountInfo {
private String name;
private String city;
private String fullname;
private String address;
}
While performing operation check for null in those feilds
I'm trying to learn about serialization and encountered the following problem:
I have an implementation of a customer that looks somewhat like this.
private static customerCount = 0;
private String customerID;
private String name;
private String street;
private String city;
private String postcode;
private String type;
I'm trying to serialize / deserialize an Arraylist
In the constructor, the ID will be created like this:
private Customer(...){
this.customerID = "ID" + customerCount;
customerCount++;
}
The serialization process works, however, all the IDs are set to ID0 when I deserialize.
Can anyone help resolve this problem?
Update: Alright, I just found out that static fields wont be serialized. How can I "model" the ID of a customer so I can serialize it? I need to have a unique value to create IDs for customers.
Here's a solution that combines the factory with the list that keeps track of customer count.
The customer class has a protected constructor, forcing you to build them through another means within the same package.
public class Customer implements Serializable {
private String customerID;
private String name;
private String street;
private String city;
private String postcode;
private String type;
protected Customer(String customerID,
String name,
String street,
String city,
String postcode,
String type) {
this.customerID = customerID;
this.name = name;
this.street = street;
this.city = city;
this.postcode = postcode;
this.type = type;
}
}
Now within the package, create a list wrapper like this:
public class CustomerList {
private int customerCount = 0;
private List<Customer> customers = new ArrayList<>();
public boolean addCustomer(String name,
String street,
String city,
String postcode,
String type) {
Customer customer = new Customer("ID" + customerCount++,
name,
street,
city,
postcode,
type);
return customers.add(customer);
}
}
This class then takes care of constructing the new customer, and provides a unique ID.
Edit: Just noticed that you now also have the upside of making the CustomerList class serializable as well. Then you can load it and still have an accurate customer count for adding additional uniquely ID-ed customers.
Usually, you would like to serialize only attributes and their values, not the logic from the class. Logic should happen before serialization or after deserialization.
I have the following xml
<MyPojo>
<name>Jason</name>
<age>25</age>
<meta>
<occupation>Engineer</occupation>
</meta>
</MyPojo>
I need to deserialize it to the following POJO:
public class MyPojo {
private String name;
private int age;
private String occupation;
}
The problem here is that occupation is wrapped within meta element
You need one more object:
public class MyPojo {
private String name;
private int age;
private Meta meta;
}
public class Meta{
private String occupation;
}
My idea is to replace occupation with an own class. Something like myMeta or whatever you want to call it(be aware in your case like the xml says: meta). This class should cotain the field occupation:
public class Meta
{
private String occupation;
}
After that you only have to add a new field of your new class e.g. myMeta to myPojo. Something like this:
public class MyPojo
{
private String name;
private int age;
private Meta meta;
}
this should avoid
that occupation is wrapped within meta element
Hope that helps!
Hi i want to know if exist a way to avoid duplicate code in this code. Now i have an action class named CustomerAction this class handle the behaviour of the request (it's like a controller) and i have a CustomerPOJO with attributes like id, name, last_name etc. Now i have to add attributes to CustomerAction to handle the data submited from the form. Is there any way to bypass the action with my CustomerPOJO ?
public class CustomerAction {
private String nombre;
private String apellido;
private String dni;
private String fechaNac;
private String obraSocial;
private String nroAsociado;
private String plan;
private String password;
private String email;
private String telParticular;
private String telCelular;
private static final Log log = LogFactory
.getLog(CustomerAction.class);
public String execute() throws Exception {
if ("cancelar".equals(this.getAccion())) {
log.debug("Executing 'cancelar' action");
return "login";
}
if ("registro".equals(accion)) {
log.debug("Executing 'registro' action");
IReferenceDataBusinessDelegate ud = new ReferenceDataBusinessDelegate();
ud.signCustomer(this.getNombre(), this.getApellido(),
this.getDni(), this.getCorreo(), this.getContrasena());
return "login";
}
}
public class Customers implements java.io.Serializable {
private long id;
private String dni;
private String name;
private String lastName;
private String email;
private String password;
private String phone;
private String cellphone;
private Date birthDate;
private Date creationDate;
private Date lastAccessDate;
private byte active;
private Set<Profesionales> profesionaleses = new HashSet<Profesionales>(0);
private Set<Pacientes> pacienteses = new HashSet<Pacientes>(0);
public Customers() {
}
}
Yes, use ModelDriven, and use a Customers as the model.
http://struts.apache.org/2.x/docs/model-driven.html
You'll need to make sure the "modelDriven" interceptor is in your stack.
How/where to initialize the model depends on your particular usage scenario; you can do it in a getter as shown in the docs, in a prepare() method if you need to reload it from the DB, etc.
I'm not sure what you mean by "bypass the action."
Please note that the ad-hoc dispatch mechanism implemented here with the accion parameter duplicates functionality provided by Struts 2 using the method attribute of the action configuration. I don't recommend using ad-hoc dispatch mechanisms as it makes understand program flow more difficult than necessary.