Is there a way to create POJO from Java class? - java

I have the bunch of Java classes. I need to create simple POJOs of just the fields from Java classes. There is a way to create POJOs from JSON but I need directly from Java classes.
Java class may have logical methods and constructed based upon different things. My goal is just to hold the state in POJOs and send it over the network and deserialize in same set of POJOs.

You can serialize Java classes just fine, no need to strip them down to their fields (which is what it sounds like you want).
class MyClass implements Serializable {
private int myInt;
private String myString;
public MyClass(int mi, String ms) {
myInt = mi; myString = ms;
}
public String doStuff() { return String.format("%s %d", myString, myInt); }
}
Code for serialization:
MyClass toSerialize = new MyClass(5, "Test");
try (ObjectOutputStream out = new ObjectOutputStream(getNetworkOutstream())) {
out.writeObject(toSerialize);
}
Code to deserialize:
try (ObjectInputStream in = new ObjectInputStream(getNetworkInStream())) {
MyClass received = (MyClass) in.readObject();
}
The doStuff method is not in the way if that's what you're thinking.
Caveat is that all fields need to also be Serializable (or primitives).

If you are looking for a way to programmatically parse all those classes and generate POJOs for them, then you can use libraries like Antlr, JavaCC or JavaParser to analyse sources and then generate and save the new POJOs.

Use some JSON library.
For ex. GSON
You could choose what fields to serialize or not using transient identifier.
Apart from that these libraries offer much more and definitely all the requirements you specified.

Related

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.

Have Jackson parse Json object as primitive String

Simple question/problem for anybody familiar with building APIs... I have many objects that I prefer to represent as a string rather than a Json object, for simplicity purposes.
For example, I have a date range which I could (and used to) place into an object (with start end end date members), but considering we can have multiple of these ranges, I could instead have this...
['20130210-20130315','20130520-20130524']
Which IMO looks a lot simpler and cleaner than
[
{
"start":"2013-02-10",
"end":"2013-03-15"
},
{
"start":"2013-05-20",
"end":"2013-05-24"
}
]
And this holds for various other objects which are in the main Json object for the service.
My dilemma of just treating them as Strings is that then I lose the ability to mark them with interfaces, which are used all throughout the code. (For instance, this Json in particular might be marked with a "Filter" interface which many methods take in.)
That said, is there any way to satisfy both of these conditions, i.e. having a custom Json object (implementing my own interfaces, etc.) AND have Jackson parse it like a String primitive? I'm hoping this can be accomplished without much work involving custom serialization & deserialization, since I have lots of objects.
Hate duplicating posts, so in an attempt to add some value here -- this does exactly what I want with arrays --
public class MyAwesomeJson extends JacksonObject implements S {
private final String value;
public MyAwesomeJson(String value) {
this.value = value;
}
#JsonValue
public String getValue() {
return value;
}
}
Then to get the array form --
public class MyAwesomeJsonArray extends JacksonObject implements A {
private final Set<MyAwesomeJson> values = Sets.newLinkedHashSet();
public MyAwesomeJsonArray(MyAwesomeJson... values) {
this.values.addAll(Arrays.asList(values));
}
#JsonValue
public Set<MyAwesomeJson> getValues() {
return values;
}
}
System.out.println(new MyAwesomeJsonArray(new MyAwesomeJson("Yellow"),
new MyAwesomeJson("Goodbye")));
["Yellow","Goodbye"]

serialization/deserialization mechanism

Say, I have a class X which has a field value, that is,
class X implements Serializable {
private int value;
// ...
}
Further it has getters and setters not displayed here. This class is serialized.
At the deserialzation, end same class has value field and access specifier is public. Further, this class does not have getters and setters. So, my questions are:
Does deserialization fail in case the access specifier of the field changes OR some or all of the methods go missing in the class at the deserialization end?
What is the mechanism by which fields are assigned their values during deserialization?
Some good links The Java serialization algorithm revealed
1) does deserialization fail in case the access specifier of the field
changes OR some or all of the methods go missing in the class at the
deserialization end ?
Serialization happens using Using Reflection
Java Detects the changes to a class using the
private static final long serialVersionUID
The default involves a hashcode. Serialization creates a single hashcode, of type long, from the following information:
The class name and modifiers
The names of any interfaces the class implements
Descriptions of all methods and constructors except private methods and constructors
Descriptions of all fields except private, static, and private transient
The default behavior for the serialization mechanism is a classic "better safe than sorry" strategy. The serialization mechanism uses the suid, which defaults to an extremely sensitive index, to tell when a class has changed. If so, the serialization mechanism refuses to create instances of the new class using data that was serialized with the old classes.
2) what is the mechanism by which fields are assigned their values
during deserialization ?
The real details can be read in the Java Object Serialization Specification.
To answer your questions:
Serialization has a basic sanity check to see if the serialization ends use the same version of a class: the serialVersionUID member must be equal. Read the section Stream Unique Identifiers to know more about it. Basically, it's a static value which you can either manage yourself by declaring it on your class, or let the compiler generate one for you. If the compiler generates it, ANY change to a class will result in a change of serialVersionUID and hence will make the deserialization fail if the ends do not have exactly the same classes. If you want to avoid this, declare the variable yourself and update it manually when a change to the class' member variables does make classes incompatible.
The Java Virtual Machine does a lot of the magic here, it can access all internal state directly without the need for getters (fields marked transient or static aren't serialized though). Also, while the Serializable interface doesn't specify any methods to implement, there are a number of 'magic methods' which you can declare to influence the serialization process. Read section "The writeObject Method" and onwards to know more. Be aware though that you should use these sparingly as they might confuse any maintenance developers!
You don't need to have getters/setter to serialize/deserialize using java serialization, for example, check this code:
public class Main {
public static class Q implements Serializable {
private int x;
public Q() {
x = 10;
}
public void printValue() {
System.out.println(x);
}
}
public static void main(String[] args) throws Exception {
Q q = new Q();
FileOutputStream fos = new FileOutputStream("c:\\temp.out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(q);
fos.close();
FileInputStream fis = new FileInputStream("c:\\temp.out");
ObjectInputStream oin = new ObjectInputStream(fis);
Q q2 = (Q)oin.readObject();
fis.close();
q2.printValue();
}
}
I don't really know how you get this results, but what you tell is not the default behaviour of serialisation. So, I guess you are using it wrong. Here is some sample code:
public class X implements Serializable
{
private int value;
public int getValue() { return value; }
}
Here the serialisation/deserialisation process:
X x = new X();
x.setValue(4);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputSteam(buffer);
oos.writeObject(x);
oos.flush();
oos.close();
ByteArrayInputStream in = new ByteArrayInputStream(buffer.toByteArray());
ObjectInputStream ois = new ObjectInputStream(in);
Object obj = ois.readObject();
if (obj instanceof X)
{
X readObject = (X) obj;
System.out.println(readObject.getValue());
}
You probably used Java Reflection to get your results. Make sure you use getDeclaredFields(); and getDeclaredMethods(); instead of the variants without Declared in the method name.
Does deserialization fail in case the access specifier of the field changes
No.
OR some or all of the methods go missing in the class at the deserialization end?
Yes, unless the receiving class has a serialVersionUID member whose value equals the value encoded in the stream.
what is the mechanism by which fields are assigned their values during deserialization?
Too broad, but:
Reflection, and
name matching (rather than matching by position in the class and stream).

create a common converter for objects from different packages

I have 5 webservices, A, B, C, D, and E. Each has autogenerated objects of the exact same structure, but with different names and in different packages.
com.ws.a.carA contains parameters and com.ws.a.wheelA
com.ws.b.carB contains parameters and com.ws.b.wheelB
com.ws.c.carC contains parameters and com.ws.c.wheelC
com.ws.d.carD contains parameters and com.ws.d.wheelD
com.ws.e.carE contains parameters and com.ws.e.wheelE
I want to create one function that can convert each of these objects (and the inner wheel) to a object named
com.model.car,
but I dont wan't many functions like :
com.model.car convert(com.ws.a.objA obj)
com.model.car convert(com.ws.b.objB obj)
...
The problem is, I can't give all the objects a common interface to implement, because I don't want to manually change the autogenerated classes (they are recreated frequently).
I need a way, probably with generics, to create a common function
com.model.car convert(T obj)
that will work for all the car types but I'm not sure how to implement it.
You can use reflection for this. The easiest and cleanest way would probably be to use Apache Common BeanUtils, either PropertyUtils#copyProperties or BeanUtils#copyProperties.
PropertyUtils#copyProperties copies the values from one object to another, where the field names are the same. So with copyProperties(dest, orig), it calls dest.setFoo(orig.getFoo()) for all fields which exist in both objects.
BeanUtils#copyProperties does the same, but you can register converters so that the values get converted from String to Int, if necessary. There are a number of standard converters, but you can register your own, in your case com.ws.a.wheelA to com.model.wheel, or whatever.
You can also check out Dozer
I think you should consider using reflection.
Using commons beanutils library you may do this utility class:
public class BeanUtilCopy {
private static BeanUtilsBean beanUtilsBean;
private static ConvertUtilsBean convertUtilsBean = new ConvertUtilsBean();
static {
convertUtilsBean.register(new Converter() { //2
public <T> T convert(Class<T> type, Object value) {
T dest = null;
try {
dest = type.newInstance();
BeanUtils.copyProperties(dest, value);
} catch (Exception e) {
e.printStackTrace();
}
return dest;
}
}, Wheel.class);
beanUtilsBean = new BeanUtilsBean(convertUtilsBean);
}
public static void copyBean(Object dest, Object orig) throws Exception {
beanUtilsBean.copyProperties(dest, orig); //1
}
When (1) beanUtilsBean use the converter (2) to pass the Wheel**X** values to the Wheel in destination bean.
Use sample:
CarB carB = new CarB();
carB.setName("car B name");
carB.setWeight(115);
WheelB wheelB = new WheelB();
wheelB.setName("wheel B name");
wheelB.setType(05);
carB.setWheel(wheelB);
Car car1 = new Car();
BeanUtilCopy.copyBean(car1, carB);
System.out.println(car1.getName());
System.out.println(car1.getWeight());
System.out.println(car1.getWheel().getName());
System.out.println(car1.getWheel().getType());
The output:
car B name
115
wheel B name
5

How can I map a String to a function in Java?

Currently, I have a bunch of Java classes that implement a Processor interface, meaning they all have a processRequest(String key) method. The idea is that each class has a few (say, <10) member Strings, and each of those maps to a method in that class via the processRequest method, like so:
class FooProcessor implements Processor
{
String key1 = "abc";
String key2 = "def";
String key3 = "ghi";
// and so on...
String processRequest(String key)
{
String toReturn = null;
if (key1.equals(key)) toReturn = method1();
else if (key2.equals(key)) toReturn = method2();
else if (key3.equals(key)) toReturn = method3();
// and so on...
return toReturn;
}
String method1() { // do stuff }
String method2() { // do other stuff }
String method3() { // do other other stuff }
// and so on...
}
You get the idea.
This was working fine for me, but now I need a runtime-accessible mapping from key to function; not every function actually returns a String (some return void) and I need to dynamically access the return type (using reflection) of each function in each class that there's a key for. I already have a manager that knows about all the keys, but not the mapping from key to function.
My first instinct was to replace this mapping using if-else statements with a Map<String, Function>, like I could do in Javascript. But, Java doesn't support first-class functions so I'm out of luck there. I could probably dig up a third-party library that lets me work with first-class functions, but I haven't seen any yet, and I doubt that I need an entire new library.
I also thought of putting these String keys into an array and using reflection to invoke the methods by name, but I see two downsides to this method:
My keys would have to be named the same as the method - or be named in a particular, consistent way so that it's easy to map them to the method name.
This seems WAY slower than the if-else statements I have right now. Efficiency is something of a concern because these methods will tend to get called pretty frequently, and I want to minimize unnecessary overhead.
TL; DR: I'm looking for a clean, minimal-overhead way to map a String to some sort of a Function object that I can invoke and call (something like) getReturnType() on. I don't especially mind using a 3rd-party library if it really fits my needs. I also don't mind using reflection, though I would strongly prefer to avoid using reflection every single time I do a method lookup - maybe using some caching strategy that combines the Map with reflection.
Thoughts on a good way to get what I want? Cheers!
There aren't any first-class standalone functions, but you can do what you want with an interface. Create an interface that represents your function. For example, you might have the following:
public interface ComputeString
{
public String invoke();
}
Then you can create a Map<String,ComputeString> object like you want in the first place. Using a map will be much faster than reflection and will also give more type-safety, so I would advise the above.
While you can't have first class functions, there are anonymous classes which can be based on an interface:
interface ProcessingMethod {
String method();
}
Map<String, ProcessingMethod> methodMap = new HashMap<String, ProcessingMethod>();
methodMap.put("abc", new ProcessingMethod() {
String method() { return "xyz" }
});
methodMap.put("def", new ProcessingMethod() {
String method() { return "uvw" }
});
methodMap.get("abc").method();
Or you could use Scala :-)
Couldn't you do String to Method? Then you can cache the methods you need to execute.
This example uses an enum of named functions and an abstract FunctionAdapter to invoke functions with a variable number of homogeneous parameters without reflection. The lookup() function simply uses Enum.valueOf, but a Map might be worth it for a large number of functions.
As you've noticed, you can do what you want using the Reflection API, but you loose some benefits of the Java compiler, on top of the issues you've already come up with. Would wrapping your Strings in an object and using the Visitor pattern solve your issue? Each StringWrapper would only accept a Visitor that has the right method, or something along those lines.
Use a Map where the key is a string and the value is an object that implements an interface containing method(). That way you can get the object containing the method you want out of the map. Then just call that method on the object. For example:
class FooProcessor implements Processor{
Map<String, FooMethod> myMap;
String processRequest(String key){
FooMethod aMethod = myMap.getValue(key);
return aMethod.method();
}
}
What about Method class from the reflection API? You can find methods of a class based on name, parameters, or return type. Then you just call Method.invoke(this, parameters).
That's pretty much the same as a Map from JavaScript you are talking about.
public class CarDetailsService {
private final CarRepository carRepository;
private final Map<String, Function<CarDTO, String>> carColumnMapper = new HashMap<>();
public ApplicationDetailsServiceImpl(CarRepository carRepository) {
this.carRepository = carRepository;
//---- Initialise all the mappings ------- //
carColumnMapper.put("BRAND", CarDTO::getBrandName);
carColumnMapper.put("MILEAGE", CarDTO::getMileage);
}
public Map<String, List<CarDTO>> getListOfCars(String groupBy) {
return carRepository.findAll()
.stream()
.map(toCarDTO)
.collect(groupingBy(carColumnMapper.get(groupBy.toUpperCase())));
}
Function<CarDetails, CarDTO> toCarDTO = (carDetails) -> CarDTO
.builder()
.brand(carDetails.getBrand())
.engineCapacity(carDetails.getEngineCapacity())
.mileage(carDetails.getMileage())
.fuel(carDetails.getFuel())
.price(carDetails.getPrice())
.build();
}

Categories