JsonGetter giving null value



在我的Spring Boot应用程序中,我正在创建一个REST API,它正在调用其他一些外部REST API。我创建了User类,它是从外部API下载的Rest API接收的对象。我的用户模型看起来像:

@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
private String fullName;
private String department;
@JsonGetter("fullName")
public String getFullName() {
return fullName;
}
@JsonSetter("full_name")
public void setFullName(String fullName) {
this.fullName = fullName;
}
@JsonGetter("department")
public String getDepartment() {
return department;
}
@JsonSetter("department")
public void setDepartment(String department) {
this.department = department;
}
}

我正在使用JsonGetter和JsonSetter属性,因为我希望在camelBase中返回响应中的json属性,但在外部API中给定的属性用下划线返回:API外部响应:

{
"full_name": "User A",
"department": "A",
}

我的API响应:

{
"fullName": "User A",
"department": "A",
}

在我开始创建一些Http请求测试之前,一切似乎都很好(用Postman点击我的API会给出正确的响应(。在测试中,我收到fullName属性为null的断言错误,而在poster中执行相同的请求是用正确的响应进行响应。我的测试课程:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HttpRequestTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
public void shouldReturnUserFullName() throws Exception {
assertThat(this.restTemplate.getForObject("http://localhost:" + port + "/users/a",
User.class)).extracting(User::getFullName)
.contains("User A");
}
}

我的控制器方法:

@GetMapping("users/{name}")
public ResponseEntity<User> getSpecificUserByName(@PathVariable("name") String name) {
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
HttpEntity<?> entity = new HttpEntity<>(headers);
ResponseEntity<User> response = restTemplate.exchange(createUriString(name), HttpMethod.GET, entity, User.class);
return response;
}

测试结果:

java.lang.AssertionError: 
Expecting:
<[null]>
to contain:
<["User A"]>
but could not find:
<["User A"]>

我将感谢任何关于这个问题的帮助:(

@JsonSetter("full_name")希望您的API响应在取消序列化期间包含属性full_name。由于@JsonGetter("fullName")full_name转换为fullName,所以从不设置字段private String fullName;

您应该将@JsonSetter("full_name")更改为@JsonSetter("fullName")

让我们举一个的例子

假设您的REST API返回到用户对象类以下

User reponse = new User();
response.setFullName("User A");
response.setDepartment("A");

因此,当我们调用REST API时,JSON响应如下所示

{
"fullName":"User A",
"department":"A"
}

现在,当您传递此JSON以转换为User类时,Jackson将查找名称为setFullNamesetDepartment的方法。

在您的测试用例中,类似的事情正在发生,

用于代码this.restTemplate.getForObject("http://localhost:" + port + "/users/a",User.class)

首先,它调用API以获得User对象Serialized,然后将其反序列化为User类。在反序列化时,它会查找名为
setFullName且没有任何的方法

@Setter
@JsonProperty
@JsonAlias

注释或者将寻找任何具有的setter方法

@Setter("fullName")
@JsonProperty("fullName"),
@JsonAlias("fullName")

但是在您的情况下,fullName设置器被视为

public void setFull_name(String fullName) {
this.fullName = fullname;
}

因此,找不到fullName的setter,但由于您将User类标记为

@JsonIgnoreProperties(ignoreUnknown = true) 

因此,不会引发任何异常,但会忽略响应JSON的fullName,因此永远不会设置fullName,它将保持为null,并且测试用例将失败。

所以,要么改变你的测试用例,要么用标记你的setter

@JsonAlias("fullName")

注释。即,您的用户类将如下所示

@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
private String fullName;
private String department;
@JsonGetter("fullName")
public String getFullName() {
return fullName;
}
@JsonAlias({"fullName","full_name"})
public void setFullName(String fullName) {
this.fullName = fullName;
}
@JsonGetter("department")
public String getDepartment() {
return department;
}
@JsonSetter("department")
public void setDepartment(String department) {
this.department = department;
}
}

最新更新