SpringBoot converts objects to Maps

preface

We may encounter in the process of development of such a scenario: we need to put an object in the attribute names and values in a Map, you can choose one by one when property is less, but if we want to dynamically access the attribute or attribute much more special, this kind of “stupid” obviously doesn’t work, this blog to provide two ways: Convert objects to maps using reflection and to Maps using JackJson.

The body of the

Transform objects into maps by reflection

Rely on

<! --lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.182.</version>
  <optional>true</optional>
</dependency>
Copy the code

UserPojo object

@Setter
@Getter
public class UserPojo implements Serializable {
    /** * User name */
    String userName;

    /** * Password */
    String password;
}
Copy the code

ObjectToMapUtils: utility class

public class ObjectToMapUtils {


    /** * Add a class query to map (0 for int, null for String or Long, and "" for") * note: the class query must be an object, that is, an attribute */
    public static Map<String, Object> setConditionMap(Object obj){
        Map<String, Object> map = new HashMap<>();
        if(obj==null) {return null;
        }
        Field[] fields = obj.getClass().getDeclaredFields();// Get the values of each attribute of the class
        for(Field field : fields){
            String fieldName =  field.getName();// Get the attribute name of the class
            if(getValueByFieldName(fieldName,obj)! =null)// Get the value of the attribute name of the class{ map.put(fieldName, getValueByFieldName(fieldName,obj)); }}return map;
    }
    /** * Gets the value of this attribute * for the class based on the attribute name@param fieldName
     * @param object
     * @return* /
    private static Object getValueByFieldName(String fieldName, Object object){
        String firstLetter=fieldName.substring(0.1).toUpperCase();
        String getter = "get"+firstLetter+fieldName.substring(1);
        try {
            Method method = object.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(object, new Object[] {});
            return value;
        } catch (Exception e) {
            return null; }}public static void main(String[] args) {
        UserPojo userPojo = new UserPojo();
        userPojo.setUserName("xiyuan");
        userPojo.setPassword("123456");
        Map<String, Object> a = setConditionMap(userPojo);
        for (Map.Entry<String, Object> entry : a.entrySet()) {
            System.out.println("key = " + entry.getKey() + ", value = "+ entry.getValue()); }}}Copy the code

Operation effect:

Convert objects to maps using JackJson

  • If our object isSpringWhen the container puts objects in the cache earlier, we can no longer use the above method of using reflection to convert objects toMap.
  • SpringcreatebeanThe principle of inequalitybeanOnce you’ve created itbeanFactoryPut it in cache early, if anything elsebeanRely on thebeanIt can be used directly, but this way we are actually getting its proxy object, which is not possible when we convert the object toMapThe purpose of.

Rely on

<! --web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <! --test--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <! --lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.182.</version>
  <optional>true</optional> </dependency> <! --springboot--> <! <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency>Copy the code

UserPojo object

  • @JsonIgnoreProperties(value = { "$$beanFactory"})We use the@JsonIgnorePropertiesTo ignore the properties of the proxy object, thus extracting only the properties of our target object.
@JsonIgnoreProperties(value = { "$$beanFactory"})
@Setter
@Getter
@Configuration
@ToString
public class UserPojo implements Serializable {
    /** * User name */
    @Value("${userName:xiyuan}")
    String userName;


    /** * Password */
    @Value("${password:123456}")
    String password;
}
Copy the code

AppTest: test class

@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class AppTest {


    @Autowired
    UserPojo userPojo;

    private static ObjectMapper mapper = new ObjectMapper();

    /** * Rigorous Test :-) */
    @Test
    public void shouldAnswerWithTrue(a) {

        try {
            String json = mapper.writeValueAsString(userPojo);
            Map<String, Object> readValue = mapper.readValue(json, HashMap.class);
            for (Map.Entry<String, Object> entry : readValue.entrySet()) {
                System.out.println("key = " + entry.getKey() + ", value = "+ entry.getValue()); }}catch(Exception e) { e.printStackTrace(); }}}Copy the code

Operation effect:

Springboot loads the configuration property with priority (from high to low).

  1. Arguments passed in at the command linejava -jar xxx.jar --server.port=8888
  2. SPRING_APPLICATION_JSONProperty in. It is aJSONFormat What is configured in system environment variables.
  3. java:comp/envIn theJNDIattribute
  4. javaSystem properties, which can be passedSystem. The getProperties ()Acquired content
  5. Environment variables of the operating system
  6. throughrandom.*Random properties configured
  7. Located in the current applicationjarPackage outside, for different{profile}Configuration file contents of the environment, such asapplication-dev.properties
  8. Located in the current applicationjarWithin the package, for different{profile}Configuration file contents of the environment, such asapplication-dev.properties
  9. Located in the current applicationjarPackage outside, configuration file content, such asapplication-dev.properties
  10. Located in the current applicationjarPackage, configuration file content, such asapplication-dev.properties
  11. @ConfigurationAnnotation modified class, passed@PropertySourceAttributes defined by annotations.
  12. The default value of the application is usedSpringApplication.setDefaultPropertiesContent of definition

@ConfigurationIn theuserNameIs overridden by the operating system’s environment variables.