0

The scenario is simple: UI call RESTful API to get an object tree, then UI change some data and call RESTful API to update it.

But for security or performance reason..., my RESTful API can NOT bring the whole object tree to the UI.

We have two choose for this purpose: creating an individual Java Bean for RESTful API or extend existing business Java Bean plus @JsonIgnore.

The second looks smarter because we re-use business class.

But Now we have a trouble: I need to merge the object from UI with the object from DB, otherwise I will lose some data.

But how do I know which piece of data will come from UI? I know I can hard code to copy fields one by one. But this way is dangerous.

I am asking for generic way to avoid hard code to copy fields.

I tried org.apache.commons.beanutils.BeanUtils, but it can't meet the requirement because it always overwrite target fields.

So I am thinking this way:
If the field in UI bean is not Null, then overwrite the value of the same name field in destination bean. but how do I handle if the field is some kind of primitive type like int which have default value 0? I don't know if the field really carry an UI value 0 or just not comes back from UI.

I tried to convert primitive type to object type, but it still have troubles on boolean type, many java tools don’t support “ Boolean isValid(){…}” like BeanUtils. And this kind converting is dangerous on existing code.

I tried those code:

JacksonAnnotationIntrospector ai = new JacksonAnnotationIntrospector();
AnnotatedClass ac = AnnotatedClass.construct(MyClassDTO.class, ai, null);
    String[] ignoredList = ai.findPropertiesToIgnore(ac);       
    for(String one: ignoredList){
        System.out.println(one);
    }

but ignoredList is always null. I am using Jackson 1.9.2

Justin
  • 1,050
  • 11
  • 26
  • Can you do it with reflection? Like reading all fields in your ui-bean and transfer them to the database bean? Can you give a simple example? – Ria Mar 31 '15 at 17:05
  • To Ria: I know how to merge the java bean in a generic way, but I need to know which fields comes from UI. – Justin Mar 31 '15 at 17:22
  • Ok now I understood. Just some brainstorming: add a list to the transferred object which holds the field names changed by the user? – Ria Mar 31 '15 at 17:29

2 Answers2

0

You could consider using JsonPatch. We use it and it works quite well. Of course it means you apply patches at the JSON level and not in the bean directly so if you need to support more than just JSON, it might be a problem.

Here's an implementation: https://github.com/fge/json-patch

Community
  • 1
  • 1
mprivat
  • 21,582
  • 4
  • 54
  • 64
0

I found the solution on Jackson:

MyBean defaults = objectMapper.readValue(defaultJson, MyBean.class);
ObjectReader updater = objectMapper.readerForUpdating(defaults);
MyBean merged = updater.readValue(overridesJson);

it comes from :

readerForUpdating

merging on Jackson

Community
  • 1
  • 1
Justin
  • 1,050
  • 11
  • 26