Java JsonGetter提供空值

Java JsonGetter提供空值,java,json,spring,spring-boot,resttemplate,Java,Json,Spring,Spring Boot,Resttemplate,在我的SpringBoot应用程序中,我正在创建一个RESTAPI,它正在调用其他一些外部RESTAPI。我创建了用户类,它是从外部API下载的RESTAPI接收的对象。我的用户模型如下所示: @JsonIgnoreProperties(ignoreUnknown = true) public class User { private String fullName; private String department; @J

在我的SpringBoot应用程序中,我正在创建一个RESTAPI,它正在调用其他一些外部RESTAPI。我创建了用户类,它是从外部API下载的RESTAPI接收的对象。我的用户模型如下所示:

    @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属性,因为我希望在camelCase中返回json属性作为响应,但外部API中给出的属性返回时带有下划线: 外部API响应:

{
    "full_name": "User A",
    "department": "A",
}
{
    "fullName": "User A",
    "department": "A",
}
我的API回应:

{
    "full_name": "User A",
    "department": "A",
}
{
    "fullName": "User A",
    "department": "A",
}
在我开始创建一些Http请求测试之前,一切似乎都很正常(用Postman点击我的API会给出正确的响应)。在测试中,我收到一个断言错误,即fullName属性为null,而在postman中执行相同的请求时,它会以正确的响应进行响应。 我的测试班:

@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;
    }
@GetMapping(“users/{name}”)
公共响应属性getSpecificUserByName(@PathVariable(“name”)字符串名){
HttpHeaders=新的HttpHeaders();
headers.add(HttpHeaders.CONTENT\u TYPE、MediaType.APPLICATION\u JSON\u VALUE);
headers.add(HttpHeaders.ACCEPT,MediaType.APPLICATION\u JSON\u VALUE);
HttpEntity=新的HttpEntity(标题);
ResponseEntity response=restTemplate.exchange(createUrString(名称),HttpMethod.GET,entity,User.class);
返回响应;
}
测试结果:

java.lang.AssertionError: 
    Expecting:
     <[null]>
    to contain:
     <["User A"]>
    but could not find:
     <["User A"]>
java.lang.AssertionError:
期望:
包含:
但找不到:
我非常感谢您对此问题提供的任何帮助:)

@JsonSetter(“全名”)
希望您的API响应在反序列化过程中包含属性
全名。由于
@JsonGetter(“全名”)
全名
转换为
全名
,字段
私有字符串全名从未设置

您应该将
@JsonSetter(“全名”)
更改为
@JsonSetter(“全名”)

让我们举个例子

假设RESTAPI返回到用户类的对象下面

User reponse = new User();
response.setFullName("User A");
response.setDepartment("A");
因此,当我们调用RESTAPI时,JSON响应如下所示

{
   "fullName":"User A",
   "department":"A"
}
@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;
    }

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

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

代码
this.restTemplate.getForObject(“http://localhost:“+端口+”/users/a“,User.class)

首先,它调用API来序列化User对象,然后将其反序列化为User类。反序列化时,它会查找名为
setFullName不带任何

 @Setter
 @JsonProperty
 @JsonAlias
注释 或者将使用

@Setter("fullName")
@JsonProperty("fullName"),
@JsonAlias("fullName")
但是在您的情况下,全名setter被视为

public void setFull_name(String fullName) {
 this.fullName = fullname;
}
因此,找不到全名的setter,但因为您将用户类标记为

@JsonIgnoreProperties(ignoreUnknown = true) 
因此,不会引发任何异常,但会忽略响应JSON的fullName,因此不会设置fullName,它将保持为null,并且测试用例将失败

因此,要么更改测试用例,要么用

@JsonAlias("fullName")
注释。 i、 e.您的用户类如下所示

{
   "fullName":"User A",
   "department":"A"
}
@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;
    }

}

但是当我将@JsonSetter(“full_name”)更改为@JsonSetter(“fullName”)时,API不会将fullName属性设置为外部API传递的值(我通过Postman调用进行了检查)。因此,实际上您需要将“fullName”改为“full_name”