How to get a value from a generic Object - java

I have the following request with these fields:
Payment (Type Payment) -> Parameters (Type Object).
I know this Parameters class has these fields:
token (String)
type (String)
cvv (String)
I´m trying to have access to the field token through request.getPayment().getParameters() but I don't really know how to make it work. I found something related to Reflection but I don´t really know how it can work.
I've tried something like but I still don't know howo to fetch this String "token":
Field field = org.springframework.util.ReflectionUtils.findField(String.class, "token");
org.springframework.util.ReflectionUtils.makeAccessible(field);
String token = field.get(request.getPayment().getParameters().????) ????

If you sure that you will always have these fields in this generic object, you can just use casting:
class PaymentParameter {
String token;
String type;
String cvv;
... // getters & setters or Lombok stuff
}
...
var paymentParameters = (PaymentParameters) request.getPayment().getParameters();
You can read more about casting here and here.
Please be aware that casting can throw ClassCastException. So you have to cover this case in your code.
The second option is that your request is a JSON string, then you can use Jackson to convert it to the map or object. This topic is covered also on Baeldung.

Related

Get value from object by key in java

I am getting object in the response of entityManager.find method.
and i want to get values from that object by passing key. but i din't get any success.
For example :-
my entity :-
#entity
class Test (){
public Long id;
public String name ;
public String descr;
}
and i am getting object in the response of below code.
`Object obj=`entitymanager.find(classname,id);
Note :- Instead of object i can't use entity's object directly because input class name can be dynamically pass that's why i am taking response in Object.
Now i want to get value from object by passing key
something like that obj.getvalue("id");
I tried below things to make it done :-
Map<String, Object> user = (Map<String, Object>)obj;
Used json simple parser to parse it.
JSONParser parser = new JSONParser();
JSONObject jsonObject =parser.parse(obj.toString());
But din't get any success.
Please help me out.
I'm a little unsure of what you're asking... but as long as "name" is a primary key you can call
Test obj = entitymanager.find(Test.class, name);
Object obj=entitymanager.find(classname,id);
In the above line what is the type of "classname".
Since your question does not mention the type. I assume its of type Object.
You should do something like
Object obj=entitymanager.find(classname.getClass(),id);

Get Thrift Field Type from ID

Is there a way to get the type of a parameter using the thrift ID? I have data coming in that needs to go to one of 6 different Thrift objects so I'm using reflection to instantiate the appropriate object and set data fields.
Class<?> cls = Class.forName(package + table.name);
Object o = cls.newInstance();
Method getField = cls.getMethod("fieldForId", int.class);
Object field = getField.invoke(o, thriftId);
Method setField = cls.getMethod("setFieldValue", field.getClass(), Object.class);
setField.invoke(o, field, data);
The variable data is a String. This code works great until it comes across a field with a type other than String where I can get ClassCastException. I tried doing this:
Method getFieldValue = cls.getMethod("getFieldValue", field.getClass());
System.out.println(getFieldValue.invoke(o, field).getClass.getName());
But for String, getFieldValue returns null if they are blank and you can't get the class. I could assume that all null values are Strings, but that seems dangerous considering Lists, Maps, etc are probably returned as null as well.
I also tried getting the Class of the field but it just comes back as the Enum (_Fields) which is expected.
I managed to find a solution. Grab the name of the field then get that field.
Method getFieldName = field.getClass().getMethod("getFieldName");
String fieldName = (String) getFieldName.invoke(field);
Class<?> fieldType = cls.getField(fieldName).getType());

Gson serialization depending on field value

I have a POJO that is similar to:
public class MyGsonPojo {
#Expose
#SerializedName("value1")
private String valueOne;
#Expose
#SerializedName("value2")
private boolean valueTwo;
#Expose
#SerializedName("value3")
private int valueThree;
// Getters and other stuff here
}
The issue is that this object has to be serialized into a json body for a call
to the server. Some fields are optional for the request and if I even send it with default and null values, the API responds differently (Unfortunately changing the api is not an option).
So basically I need to exclude fields from serialization if any of them is set to a default value. For example if the field valueOne is null the resulting json should be:
{
"value2" : true,
"value3" : 2
}
Any idea how to make this a painless effort? I wouldn't want to build the json body manually.
Any help would be great. Thank you in advice.
Steps to follow:
Convert the JSON String into Map<String,Object> using Gson#fromJson()
Iterate the map and remove the entry from the map which are null
Form the JSON String back from the final map using Gson#toJson().
I have already posted the sample code in the same context here:
Remove empty collections from a JSON with Gson
Option 1) Use a TypeAdapter, see accepted answer here:
Option 2) If using Jackson instead of gson is a possibility, you can annotate/serialize on getters instead of on fields, and put your logic for returning
whatever you need for "default values" in your getters.
//won't get serialized because it's private
private String valueOne;
...
#JsonSerialize
String getValueOne(){
if (valueOne == null) return "true"
else...
}
You could also use a single #JsonInclude(Include.NON_NULL) or #JsonInclude(Include.NON_EMPTY) annotation at the top of your class to prevent any null or empty fields from being serialized.

Getter (accessor) based serialization (json or xml)

I need to serialize a couple of objects in my Android app and send them to web service.
The model classes for objects have various int fields which need to be converted into meaningful string representations from various arrays before sending to web service.
So, I am assuming that easiest way will be to use gson or xstream (JSON or XML - anything is fine) but with following method:
- I'll mark all existing int fields as transient and exclude them from serialization
- I'll create new get method per field. The get method will read value of corresponding integer and return its string representation.
But in either of 2 libraries - gson or xstream, I am unable to find way to serialize based on getters instead of fields. Please suggest.
And yes, I DO NOT need to deserialize the data back.
I think you need a wrapper class.
Consider this:
public class Blammy
{
private int gender;
... imagine the rest of the class.
}
public class BlammyWrapper
{
private String gender;
public BlammyWrapper(final Blammy blammy)
{
if (blammy.gender == 1)
{
gender = "Its a Boy";
}
else if (blammy.gender == 2)
{
gender = "girl";
}
else // always check your boundary conditions.
{
throw new InvalidArgumentException("Naughty blammy; unrecognized gender value");
}
public String gender()
{
return gender;
}
}
Ok, finally, I followed this approach:
1. Removed all resource arrays from my app code
2. Added enums with toString for each current array
3. Changed all int properties to be of corresponding enum type
4. Used XStream
5. Added a custom convertor for XStream for generic enum types where if it finds any property of type enum, then it will marshal it using toString method.
Thanks for all support btw. All your answers and comments atleast made me clear that my current code architecture needed drastic improvement.

how to cast string to integer at runtime

I am using reflection in java.
I am getting to know the type of method parameter I am passing at run time. So I am fetching the parameter value from file into a string variable.
SO now if i get to know that the parameter type as integer and if i pass an object containting the string value I am getting
argument type mismatch
java.lang.IllegalArgumentException: argument type mismatch
Class classDefinition = Class.forName("webservices."+objectName);
String methodName = set"+fieldNameAttay[i].substring(0,1)).toUpperCase()+fieldNameAttay[i].substring(1); Field f = classDefinition.getDeclaredField(fieldNameAttay[i]);
try
{
//argType = f.getType();
Method meth = classDefinition.getMethod(methodName,f.getType());
Object arg = new Object[]{fieldValueArray[i]}; //fieldValueArray[i] is always string array
meth.invoke(object, arg); //If f.getType is Integer this //throws ex
}
catch (Exception e)
{
System.err.println(e.getMessage());
e.printStackTrace();
}
You can't cast a string to an integer - you can parse it though. For example:
if (parameterType == int.class && argumentType == String.class)
{
int integerArgument = Integer.parseInt((String) argumentValue);
// Now call the method appropriately
}
Of course, you also need to consider Integer as well as int.
How about
Integer.parseInt((String) stringObj)
Note that casting can happen only if the two objects belong in the same hierarchy. So this is not casting.
If the only types you are using are String and Integer, checking the type and then using Integer.parseInt might be the simplest thing to do.
However if you have more different types, I would suggest checking out the good old JavaBeans framwork: http://download.oracle.com/javase/tutorial/javabeans/index.html
And especially the PropertyEditors
http://download.oracle.com/javase/7/docs/api/java/beans/PropertyEditor.html
http://download.oracle.com/javase/7/docs/api/java/beans/PropertyEditorManager.html
The PropertyEditors allow you to set the value as text, and then retrieve the value as correct type. Assuming you have implemented and registered the property editors, the steps to get the correct type are similer to this:
Find out the type of the parameter
Retrieve a PropertyEditor for that type
Use setAsText and getValue in the property editor to convert the value to correct type
...or You can just adapt the same mechanism to your simple needs by implementing your own conversion framework with similar but simpler interfaces.
System.out.println(Integer.parseInt(obj.toString()))
There's another way to do it:
Integer number = Integer.valueOf("1");

Categories