如何将 Json 反序列化为不可变对象 - Spring,RestTemplate

How to deserialise Json into Immutable Object - Spring, RestTemplate

我有一个看起来像这样的模型:

@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;
    }
}

接下来,我有一个使用 restTempate.

调用另一个服务的方法

我应该将调用的结果保存在上面显示的模型中。

我有这段代码应该调用并且 return 来自外部服务:

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;

所以,在这段代码中我使用

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());
}

RegistrationRequestDto 模型中的变量只是 private.

时,我可以使用它

但现在变量是 public final 我不确定如何将结果存储在地图中?

您可以根据来自 api 的响应 return 创建 Pojo。

即如果你有一些 api https://www.mockapis.not/users/user/123 并且它 return 响应是这样的,

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

然后您可以使用给定的属性创建一个 java class。

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

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

然后你可以调用你的 api 如下,你可以从响应实体中获取用户对象。

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

现在您不需要解析对象。它将被自动解析。

更多详情请访问Resttemplate

你的 dto class 必须在其构造函数上有一个 fasterxml @JsonCreator。 类似于下面的 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;
    }

}

并且在其余调用中传递 User.class 而不是 Object.class。如下所示:

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

User user = response.getBody();

注:@JsonProperty("...")这里是必须的。此外 @Value@Data.

更适合您的用例