#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, вы можете напрямую десериализовать его в свой объект ответа