Search code examples
javaspringspring-bootalgorithmreactive-programming

Deeply nested JSON response from third party


I'm getting this deeply nested JSON response from an api that I have no control,

What should be the best way to get to "generalDetails" and then find the first true value under security, address, account and mobile?

{
    "info_code": "201",
    "info_description": "info description",
    "data": {
        "status": "here goes the status",
        "failure_data": {
            "source": "anySource",
            "details": {
                "data": {
                    "server_response": {
                        "generalDetails": {
                            "security": {
                                "isAccountLocked": "false"
                            },
                            "address": {
                                "isAddresExists": "true"
                            },
                            "account": {
                                "accountExists": "true",
                                "isValidAccount": "true"
                            },
                            "mobile": {
                                "mobileExists": "true"
                            }
                        }
                    }
                }
            }
        }
    }
}

My request looks like:

@Autowired
private WebClient.Builder webClientBuilder;


String resp = webClientBuilder.build().get().uri(URL)
                    .accept(MediaType.APPLICATION_JSON)
                    .retrieve()
                    .bodyToMono(String.class).block();


Solution

  • First, build the model, automatic here https://codebeautify.org/json-to-java-converter.

    Then read data with the model

    .bodyToMono(MyData.class)
    

    Then decide how you want evaluate the requirement find the first true value under security, address, account and mobile.

    What means "first" ? JSON has no natural order without indicating explicity (e.g. field "order": 2).

    N.B. "true", "false" of the response are Strings, not booleans.

    Once you have the model with data, you may do:

    Object firstTrue(GeneralDetails gd)  {
        // No null checks here
        if ("true".equals(gd.getSecurtity().isLockedAccount())) return gd.getSecurtity();
        if ("true".equals(gd.getAddress().isAddressExists())) return gd.getAddress();
        if ("true".equals(gd.getAccount().isAccountExists()) || "true".equals(gd.getAccount().isAccountValid())) return gd.getAccount();
        if ("true".equals(gd.getMobile().isMobileExists())) return gd.getMobile();
    
        return null;
    }