Apart from the trick solution using reflection, you could also try jackson with one line as follows:
objectMapper.convertValue(o, Map.class);
A test case:
@Test
public void testConversion() {
User user = new User();
System.out.println(MapHelper.convertObject(user));
}
@Data
static class User {
String name = "Jack";
boolean male = true;
}
// output: you can have the right type normally
// {name=Jack, male=true}
Answer from Hearen on Stack OverflowApart from the trick solution using reflection, you could also try jackson with one line as follows:
objectMapper.convertValue(o, Map.class);
A test case:
@Test
public void testConversion() {
User user = new User();
System.out.println(MapHelper.convertObject(user));
}
@Data
static class User {
String name = "Jack";
boolean male = true;
}
// output: you can have the right type normally
// {name=Jack, male=true}
This is how you'd do it:
import java.util.Map;
import java.util.HashMap;
import java.util.Map.Entry;
import java.lang.reflect.Field;
public class Main {
public int a = 3;
public String b = "Hello";
public static void main(String[] args) {
Map<String, Object> map = parameters(new Main());
for (Entry<String, Object> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
public static Map<String, Object> parameters(Object obj) {
Map<String, Object> map = new HashMap<>();
for (Field field : obj.getClass().getDeclaredFields()) {
field.setAccessible(true);
try { map.put(field.getName(), field.get(obj)); } catch (Exception e) { }
}
return map;
}
}
Basically, you use reflection to get all of the fields in the class. Then, you access all of those fields of the object. Keep in mind that this only works for fields accessible from the method that gets the fields.
Well, you can achieve that with Jackson, too. (and it seems to be more comfortable since you were considering using jackson).
Use ObjectMapper's convertValue method:
final ObjectMapper mapper = new ObjectMapper(); // jackson's objectmapper
final MyPojo pojo = mapper.convertValue(map, MyPojo.class);
No need to convert into JSON string or something else; direct conversion does much faster.
A solution with Gson:
Gson gson = new Gson();
JsonElement jsonElement = gson.toJsonTree(map);
MyPojo pojo = gson.fromJson(jsonElement, MyPojo.class);
use Jackson
import com.fasterxml.jackson.databind.ObjectMapper;
public class Foo {
{
ObjectMapper objectMapper = new ObjectMapper();
YourObject obj = objectMapper.convertValue(YourMap, YourObject.class);
}
}
Whilst it is possible to create classes at runtime with custom class loaders, it is relatively pointless. How would you access the fields (other than reflection and other dynamically created classes)?
Lots of potential solutions, but let's add just one more. Use Jackson (JSON processing lib) to do "json-less" conversion, like:
ObjectMapper m = new ObjectMapper();
Map<String,Object> props = m.convertValue(myBean, Map.class);
MyBean anotherBean = m.convertValue(props, MyBean.class);
(this blog entry has some more examples)
You can basically convert any compatible types: compatible meaning that if you did convert from type to JSON, and from that JSON to result type, entries would match (if configured properly can also just ignore unrecognized ones).
Works well for cases one would expect, including Maps, Lists, arrays, primitives, bean-like POJOs.
There is always apache commons beanutils but of course it uses reflection under the hood