получение данных объекта внутри объекта в java

#java #object

#java #объект

Вопрос:

у меня есть объект x, который содержит объект внутри, и я хотел бы получить доступ к нему из метода без дополнительного кода записи. Допустим, это мой объект :

 {
    "status": "Success",
    "code": "200 OK",
    "message": "OK",
    "data": {
        "renter": {
            ....some Hashmap information.......
        }
    }
}
 

допустим , я хочу получить доступ к информации , которую предоставляет арендатор объекта внутри данных объекта .
Для этого

в моем методе Y я сделал это :

  @Override
    public Y methodY(String userName) throws Exception{
        ObjectMapper mapper = new ObjectMapper();

        Map<String,Object> clienteFeignOnMap=  client.findByRenterName(userName);

        //////////ACCESSING THE OBJECT DATA//////////////////
        Map<String,Object> objectResponseData= (Map<String, Object>) clienteFeignOnMap.get("data");

        //////////ACCESSING THE OBJECT RENTER INSIDE DATA FOR DESERIALIZING TO TyPE RENTER//////////////////
        Renter renter = mapper.convertValue(objectResponseData.get("renter"), new TypeReference<Renter>(){ });
......more code.............
    }

 

Этот способ успешен и работает, но все же я думаю, что мог бы найти лучший вариант, который позволит мне в одну строку возобновить этот доступ от арендатора внутреннего объекта.

Заранее спасибо за любую помощь или предложение. С наступающим 2021 годом

Ответ №1:

Если вы не хотите создавать класс Java для сопоставления атрибутов, как предложил @Migwel, и хотите использовать java.util.Map , то вам, возможно, придется использовать Apache BeanUtils или что-то эквивалентное, чтобы добраться до глубоких элементов.

 BeanUtils.getNestedProperty( map, elementPath )
 

где elementPath — разделенный точкой путь к элементу. data.renter , в вашем случае.

PropertyUtils.getNestedProperty( map, elementPath ) также делает то же самое.

Однако это не позволит вам получить доступ к индексированным свойствам, если у вас есть массивы внутри объектов. Для этого, насколько я знаю, вам нужно будет написать пользовательский код, аналогичный приведенному ниже методу.

 public static <T> T getMapElement( Map<String, ? super Object> map, String path ) {
    if( isEmpty( path ) ) return null;
    
    String[] parts = path.split( "[\[\]\.]" );
    
    Object currElem = null;
    try{
        currElem = map;
        for( int i = 0; i < parts.length; i   ){
            String part = parts[ i ];
            boolean done = false;
            
            /* Handle List. */
            if( currElem instanceof List ) {
                int index = integer( part, -1 );
                if( index >= 0 ) {
                    currElem = ( (List) currElem ).get( index );
                    done = true;
                }
            }
            
            if( done ) continue;
            
            /* Handle Map. */
            if( currElem instanceof Map ) currElem = ( (Map) currElem ).get( part );
            
            if( currElem == null ) break;
        };
    }
    catch( Exception e ){}
    
    return (T) currElem;
}
 

Редактировать

Существует также json-path from group com.jayway.jsonpath , которая также позволяет проверять JSON непосредственно в глубоких элементах. Отказ от ответственности: я не использовал и не уверен, что он использует для десериализации JSON. Однако, возможно, стоит провести исследование.

Ответ №2:

Вместо использования maps вы должны создавать правильные объекты.

Например:

 public class Response {
    private String status;
    private String code;
    private String message;
    private Data data;
    // constructor, getters, setters
    ...
}
 

И так далее с классом Data и классом и т.д. Renter

Затем, при использовании ObjectMapper, вы можете напрямую десериализовать его в свой объект ответа