如何将 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
.
更适合您的用例
我有一个看起来像这样的模型:
@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
.