Home > Net >  How to populate Map with final variables in Java, SpringBoot
How to populate Map with final variables in Java, SpringBoot

Time:11-24

I have a model that looks like this:

@Data
public class RegistrationRequestDto {

    public final String email;
    public final String username;
    public final String password;
    public final String confirmPassword;
    public final String firstName;
    public final String lastName;
    public final String keycloakId;

    public RegistrationRequestDto(
            String email,
            String username,
            String password,
            String confirmPassword,
            String firstName,
            String lastName,
            String keycloakId) {
        notNull(email, "email must be set");
        notNull(username, "username must be set");
        notNull(password, "password must be set");
        notNull(firstName, "firstName must be set");
        notNull(lastName, "lastName must be set");
        this.email = email;
        this.username = username;
        this.password = password;
        this.confirmPassword = confirmPassword;
        this.firstName = firstName;
        this.lastName = lastName;
        this.keycloakId = keycloakId;
    }
}

Next, I have a method that is calling another service with restTempate.

The result of that call I should save in the model shown above.

I have this piece of code that should call and return result from external service:

RegistrationRequestDto userProfile = new RegistrationRequestDto();
        try {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            // httpHeaders.set("Authorization", "Bearer "   responseToken.getAccess_token());
            HttpEntity<String> request = new HttpEntity<String>(httpHeaders);

            ResponseEntity<Object> result = restTemplate.exchange(uri, HttpMethod.POST, request, Object.class);
            log.info("{}", result);
            log.info("{}", result.getBody());

            LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>) result.getBody();

            if (map != null) {
                userProfile.setUserId(map.get("sub").toString());
                userProfile.setGiven_name(map.get("given_name").toString());
                userProfile.setFamily_name(map.get("family_name").toString());
                userProfile.setEmail(map.get("email").toString());
                userProfile.setEmail_verified(map.get("email_verified").toString());
                //userProfile.setPhoto(Optional.ofNullable(map.get("photo").toString()));
            }
    
        } catch (Exception e) {
            e.printStackTrace();
        }
        return userProfile;

So, in this code I am using

if (map != null) {
   userProfile.setUserId(map.get("sub").toString());
   userProfile.setGiven_name(map.get("given_name").toString());
   userProfile.setFamily_name(map.get("family_name").toString());
   userProfile.setEmail(map.get("email").toString());
   userProfile.setEmail_verified(map.get("email_verified").toString());
}

Which I was able to use when variables in RegistrationRequestDto model were just private.

But now as variables are public final I am not sure how to store result in map?

CodePudding user response:

You can create the Pojo as per the response returned from the api.

i.e If you have some api https://www.mockapis.not/users/user/123 and it return the response something like this,

{
   "name":"stack",
   "age":21,
   "phone":123456789,
   "dob":"01-06-2011"
}

Then you can create a java class with the given properties.

class User {
    private String name;
    private int age;
    private long phone;
    private Date dob;

    //getter setter or lombok @Data or @Getter @Setter
}

Then you can call your api as below and you can get User object from the response entity.

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<User> response = restTemplate.exchange(apiUrl, HttpMethod.GET, User.class);
User user = response.getBody();

Now you don't need to parse the object. It will be parsed by automatically.

For more details you can visit Resttemplate

CodePudding user response:

Your dto class must have a fasterxml @JsonCreator on its constructor. something like below dto:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Value;

@Value
public class User {
    public final int id;
    public final String name;

    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public User(@JsonProperty("id") int id, @JsonProperty("name") String name) {
        this.id = id;
        this.name = name;
    }

}

And in the rest call pass User.class instead of Object.class. Something like below:

ResponseEntity<User> response = restTemplate.exchange(uri, HttpMethod.GET, HttpEntity.EMPTY, User.class);

User user = response.getBody();

Note: @JsonProperty("...") is necessary here. Also @Value is better for your use case than @Data.

  • Related