【问题标题】:How to auto-map attributes from Java Map to POJO class attributes如何将 Java Map 中的属性自动映射到 POJO 类属性
【发布时间】:2019-07-01 04:10:41
【问题描述】:

我正在开发一个 spring boot 应用程序并开发一个 spring rest (PATCH) 服务。

我有一种情况,我需要将在 HashMap 中的 PATCH 请求中收到的数据从前端映射到 java POJO 类。

我需要在 POJO 类中映射的属性存在于 Hashmap 的键中。我们需要遍历map,将map中key的值关联到POJO类属性。

最好的方法是什么?我知道有一种非常麻烦的方法,我手动检查映射中的每个键并将相应的值关联到 POJO 类中的适当设置器。但是如果 POJO 类中的属性数量很多,这就非常麻烦了。

有没有一种有效的方法来实现这一点?

代码sn-p

@CrossOrigin
    @RequestMapping(value="/{id}", method = RequestMethod.PATCH)
    public Project editProject(@RequestBody Map<String, String> project, @PathVariable("id") String id) throws Exception {

        logger.info("Inside editProject() API ");

        if(project == null) {
            return null;
        }

        for(String key: project.keySet()) {
            logger.info("Keys passed for update ==> Key(" + key + "): Value(" + project.get(key) + ")");
        }

        Project projectRec = null;

        try {

            logger.info("updateProject() :: Before save :: ");

            projectRec = projectService.updateProjectInfo(project, id);

            logger.info("updateProject() :: After save :: Saved successfully ::: ", projectRec.toString());
        }
        catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }

        logger.info("Leaving createProject() API");

        return projectRec;
    }

public Project updateProjectInfo(Map<String, String> projectRec, String id) {

        logger.info("Inside updateProjectInfo() API in ProjectServiceImpl");

        Project dbRec = projectRepository.findOne(id);

        setAttributesfromMaptoDBRec(projectRec, dbRec);

        Project updatedProjectRec = null;

        logger.info(" Leaving updateProjectInfo() API in ProjectServiceImpl");

        return updatedProjectRec;
    }

private void setAttributesfromMaptoDBRec(Map<String, String> updatedProjectRecMap, Project updatedProjectRec) {

        logger.info(" Inside setAttributesfromMaptoDBRec() API in ProjectServiceImpl");

        Set<String> nonUpdateableAttributes = ProjectServiceImpl.nonUpdateableKeys.get(ProjectServiceImpl.nonUpdateable);

        if(updatedProjectRecMap == null) {
            logger.warn(" Input Map to service is null in ProjectServiceImpl ===> " + (updatedProjectRecMap == null));
            return;
        }

        for(String key: updatedProjectRecMap.keySet()) {

            logger.info(" Project property ===>  " + key);

            logger.info(" nonUpdateableAttributes contains key  ===> " + nonUpdateableAttributes.contains(key));

            if(!nonUpdateableAttributes.contains(key)) {
                try {
                    System.out.println("Field name: " + updatedProjectRec.getClass().getField(key));
                    System.out.println("HOW TO AUTOMATICALLY SET THE ATTRIBUTE TO THE POJO CLASS BASED ON THE KEY ??");
                } catch(Exception ex) {
                    ex.printStackTrace();
                }

            }
        }


    }

【问题讨论】:

  • 如果 map 中的键和 POJO 的属性名相同,可以尝试使用反射
  • 在使用 Jackson objectMapper.readObject & writeObject 之前,我已经安静了很久。

标签: java spring-boot spring-mvc pojo spring-rest


【解决方案1】:

我很久以前就使用 Jackson 数据绑定 API 做过类似的事情。 不确定,但这可能会有所帮助:

import java.util.Map;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ObjectMarshalUtility {

    public static <T> Map marshalObject(T obj){
        ObjectMapper oMapper = new ObjectMapper();
        oMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        return oMapper.convertValue(obj, Map.class);
    }

    public static <T> T unMarshalObject(Class<T> classType, Map<String, Object> map){
        ObjectMapper oMapper = new ObjectMapper();
        oMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        return oMapper.convertValue(map, classType);
    }
}

用于将 DTO 转换为 MAP:

Map<String,Object> searchInputMap=ObjectMarshalUtility.marshalObject(searchInputDTO);

用于将 Map 转换为 DTO:

SearchInputDTO searchInputDTO=ObjectMarshalUtility.unMarshalObject(searchInputMap);

【讨论】:

    猜你喜欢
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    相关资源
    最近更新 更多