欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot将对象转化Map

程序员文章站 2022-07-10 08:22:04
SpringBoot将对象转化Map前言我们在开发的过程中可能会遇到这样的一个场景:我们需要将一个对象中的属性名和值放在一个Map中,当属性比较少的时候你可以选择逐一放,但是如果我们要动态获取指定属性或者属性特别多的时候,这种“笨方法”显然是行不通的,本篇博客提供两种方式:通过反射将对象转化为Map和利用JackJson将对象转化为Map。正文通过反射将对象转化为Map依赖 org.pr...

SpringBoot将对象转化Map

前言

我们在开发的过程中可能会遇到这样的一个场景:我们需要将一个对象中的属性名和值放在一个Map中,当属性比较少的时候你可以选择逐一放,但是如果我们要动态获取指定属性或者属性特别多的时候,这种“笨方法”显然是行不通的,本篇博客提供两种方式:通过反射将对象转化为Map和利用JackJson将对象转化为Map

正文

通过反射将对象转化为Map

依赖

<!--lombok-->
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.2</version>
  <optional>true</optional>
</dependency>

UserPojo对象

@Setter
@Getter
public class UserPojo implements Serializable {
    /**
     * 用户名
     */
    String userName;

    /**
     * 密码
     */
    String password;
}

ObjectToMapUtils:工具类

public class ObjectToMapUtils {


    /**
     * 将一个类查询方式加入map(属性值为int型时,0时不加入,
     * 属性值为String型或Long时为null和“”不加入)
     *注:需要转换的必须是对象,即有属性
     */
    public static Map<String, Object> setConditionMap(Object obj){
        Map<String, Object> map = new HashMap<>();
        if(obj==null){
            return null;
        }
        Field[] fields = obj.getClass().getDeclaredFields();//获取类的各个属性值
        for(Field field : fields){
            String fieldName =  field.getName();//获取类的属性名称
            if(getValueByFieldName(fieldName,obj)!=null)//获取类的属性名称对应的值
            {
                map.put(fieldName,  getValueByFieldName(fieldName,obj));
            }
        }
        return map;
    }
    /**
     * 根据属性名获取该类此属性的值
     * @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());
        }
    }
}

运行效果:
SpringBoot将对象转化Map

利用JackJson将对象转化为Map

  • 如果我们对象是Spring容器的提早放在缓存中的对象时,我们就不能再使用上面利用反射的方式来将对象转化为Map
  • Spring创建bean的原则是不等bean创建完成就将beanFactory提早放到缓存中,如果其他bean依赖这个bean可以直接使用,但是这种方式我们获取的实际上是其代理对象,这个时候就无法达到我们将对象转化为Map的目的。

依赖

<!--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.18.2</version>
  <optional>true</optional>
</dependency>

<!--springboot-->
<!--除去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>

UserPojo对象

  • @JsonIgnoreProperties(value = { "$$beanFactory"})我们使用@JsonIgnoreProperties来忽略代理对象的属性,从而只提取我们目标对象的属性。
@JsonIgnoreProperties(value = { "$$beanFactory"})
@Setter
@Getter
@Configuration
@ToString
public class UserPojo implements Serializable {
    /**
     * 用户名
     */
    @Value("${userName:xiyuan}")
    String userName;


    /**
     * 密码
     */
    @Value("${password:123456}")
    String password;
}

AppTest:测试类

@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() {

        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();
        }
    }
}

运行效果:
SpringBoot将对象转化Map

这里userName的值为luo的原因是:
Springboot加载配置属性的优先级(由高到低)

  1. 在命令行中传入的参数 java -jar xxx.jar --server.port=8888
  2. SPRING_APPLICATION_JSON中的属性。它是以JSON格式配置在系统环境变量中的内容。
  3. java:comp/env中的JNDI属性
  4. java的系统属性,可以通过System.getProperties()获得的内容
  5. 操作系统的环境变量
  6. 通过random.*配置的随机属性
  7. 位于当前应用jar包之外,针对不同{profile}环境的配置文件内容,如application-dev.properties
  8. 位于当前应用jar包之内,针对不同{profile}环境的配置文件内容,如application-dev.properties
  9. 位于当前应用jar包之外,配置文件内容,如application-dev.properties
  10. 位于当前应用jar包之内,配置文件内容,如application-dev.properties
  11. @Configuration注解修改的类,通过@PropertySource注解定义的属性。
  12. 应用的默认值,使用SpringApplication.setDefaultProperties定义的内容

@ConfigurationuserName的值被操作系统的环境变量所覆盖。

SpringBoot将对象转化Map

本文地址:https://blog.csdn.net/weixin_40990818/article/details/112003355