Skip to content

Instantly share code, notes, and snippets.

@varren
Last active October 10, 2017 14:40
Show Gist options
  • Save varren/c84da2f357a1d86b24bf137f3144cc3a to your computer and use it in GitHub Desktop.
Save varren/c84da2f357a1d86b24bf137f3144cc3a to your computer and use it in GitHub Desktop.
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by varren on 09.10.17.
*/
public class Main10 {
public static class A {
@JsonProperty("b")
@JsonIdentityReference(alwaysAsId = true) // used for serialization only
private B b;
@Override
public String toString() {
return "A{b=" + b + '}';
}
}
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = MyObjectIdResolver.class, // used for deserialization only
property = "id", scope = B.class)
public static class B {
@JsonProperty("id")
private int id;
@JsonProperty("a")
private List<A> a = new ArrayList<>();
public B() {
}
public B(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "B{id=" + id +", a=" + a + '}';
}
}
private static class MyObjectIdResolver implements ObjectIdResolver {
private Map<ObjectIdGenerator.IdKey,Object> _items = new HashMap<>();
@Override
public void bindItem(ObjectIdGenerator.IdKey id, Object pojo) {
if (!_items.containsKey(id)) _items.put(id, pojo);
}
@Override
public Object resolveId(ObjectIdGenerator.IdKey id) {
Object object = _items.get(id);
return object == null ? getById(id) : object;
}
protected Object getById(ObjectIdGenerator.IdKey id){
Object object = null;
try {
//can resolve object here if you want extra logic
object = id.scope.getConstructor().newInstance(); // create instance
id.scope.getMethod("setId", int.class).invoke(object, id.key); // set id
} catch (Exception e) {
e.printStackTrace();
}
return object;
}
@Override
public ObjectIdResolver newForDeserialization(Object context) {
return new MyObjectIdResolver();
}
@Override
public boolean canUseFor(ObjectIdResolver resolverType) {
return resolverType.getClass() == getClass();
}
}
public static void main(String[] args) throws IOException {
final ObjectMapper mapper = new ObjectMapper();
String json = "{\"b\": 1}";
A newB = mapper.readValue(json, A.class);
System.out.println("From json : "+ json);
System.out.println("To Object : "+newB);
System.out.println("Back to json : "+mapper.writeValueAsString(newB));
}
}
@Configuration // need this for ApplicationContextAware to work without HandlerInstantiator config for jackson
public class MyObjectIdResolver implements ObjectIdResolver {
private static PersistenceService service;
public MyObjectIdResolver() {}
@Autowired
public MyObjectIdResolver(PersistenceService service) {
MyObjectIdResolver.service = service;
}
private Map<ObjectIdGenerator.IdKey, Object> _items = new HashMap<>();
@Override
public void bindItem(ObjectIdGenerator.IdKey id, Object pojo) {
if (!_items.containsKey(id)) _items.put(id, pojo);
}
@Override
public Object resolveId(ObjectIdGenerator.IdKey id) {
Object object = _items.get(id);
return object == null ? getById(id) : object;
}
protected Object getById(ObjectIdGenerator.IdKey id) {
Object object = null;
try {
object = service.getObjectById((Integer) id.key, id.scope);
//can resolve object here if you want extra logic
//object = id.scope.getConstructor().newInstance(); // create instance
// id.scope.getMethod("setId", int.class).invoke(object, id.key); // set id
} catch (Exception e) {
e.printStackTrace();
}
return object;
}
@Override
public ObjectIdResolver newForDeserialization(Object context) {
return new MyObjectIdResolver();
}
@Override
public boolean canUseFor(ObjectIdResolver resolverType) {
return resolverType.getClass() == getClass();
}
}
@Service("persistenceService")
public class PersistenceService {
public Object getObjectById(int id, Class classObj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//just normal spring flow we are in spring been now.
// can access db
//just for tests we still use reflection
Object object = classObj.getConstructor().newInstance(); // create instance
classObj.getMethod("setId", int.class).invoke(object, id); // set id
classObj.getMethod("setName", String.class).invoke(object, "name From getObjectById"); // set id
return object;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment