当前位置: 首页 > 知识库问答 >
问题:

无法使用RestTemplate反序列化HATEOS JSON

空俊语
2023-03-14

我试图调用一个Spring Cloud Data Flow REST Endpoint,它应该返回一个任务的所有执行列表,该任务的名称在输入中传递。

首先,我在浏览器中运行了以下网址:

http://dataflow-server.myhost.net/tasks/executions?task1225

浏览器上显示了以下JSON:

{
    "_embedded": {
        "taskExecutionResourceList": [
            {
                "executionId": 2908,
                "exitCode": 0,
                "taskName": "task1225",
                "startTime": "2021-06-25T18:40:24.823+0000",
                "endTime": "2021-06-25T18:40:27.585+0000",
                "exitMessage": null,
                "arguments": [
                    "--spring.datasource.username=******",
                    "--spring.cloud.task.name=task1225",
                    "--spring.datasource.url=******",
                    "--spring.datasource.driverClassName=org.h2.Driver",
                    "key=******",
                    "batchId=20210625_025755702",
                    "--spring.cloud.data.flow.platformname=default",
                    "--spring.cloud.task.executionid=2908"
                ],
                "jobExecutionIds": [],
                "errorMessage": null,
                "externalExecutionId": "task1225-kp7mvwkmll",
                "parentExecutionId": null,
                "resourceUrl": "Docker Resource [docker:internal.artifactrepository.myhost.net/myProject/myimage:0.1]",
                "appProperties": {
                    "spring.datasource.username": "******",
                    "spring.cloud.task.name": "task1225",
                    "spring.datasource.url": "******",
                    "spring.datasource.driverClassName": "org.h2.Driver"
                },
                "deploymentProperties": {
                    "spring.cloud.deployer.kubernetes.requests.memory": "512Mi",
                    "spring.cloud.deployer.kubernetes.limits.cpu": "1000m",
                    "spring.cloud.deployer.kubernetes.limits.memory": "8192Mi",
                    "spring.cloud.deployer.kubernetes.requests.cpu": "100m"
                },
                "taskExecutionStatus": "COMPLETE",
                "_links": {
                    "self": {
                        "href": "http://dataflow-server.myhost.net/tasks/executions/2908"
                    }
                }
            }
        ]
    },
    "_links": {
        "first": {
            "href": "http://dataflow-server.myhost.net/tasks/executions?page=0&size=20"
        },
        "self": {
            "href": "http://dataflow-server.myhost.net/tasks/executions?page=0&size=20"
        },
        "next": {
            "href": "http://dataflow-server.myhost.net/tasks/executions?page=1&size=20"
        },
        "last": {
            "href": "http://dataflow-server.myhost.net/tasks/executions?page=145&size=20"
        }
    },
    "page": {
        "size": 20,
        "totalElements": 2908,
        "totalPages": 146,
        "number": 0
    }
}

接下来,我尝试通过Java调用同一个RESTendpoint;然而,无论我尝试什么,响应对象似乎都是空的,没有填充任何属性:

方法1:创建自定义域类来反序列化响应。(不工作。响应中收到空内容)

ParameterizedTypeReference<Resources<TaskExecutions>> ptr = new ParameterizedTypeReference<Resources<TaskExecutions>>() {
            };

            ResponseEntity<Resources<TaskExecutions>> entity = restTemplate.exchange(
                    "http://dataflow-server.myhost.net/tasks/executions?task1225",
                    HttpMethod.GET, null, ptr);
            System.out.println(entity.getBody().getContent()); **//empty content**

其中,TaskExecutions域如下所示:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "taskExecutionResourceList" })
@JsonIgnoreProperties(ignoreUnknown = true)
public class TaskExecutions {
    
    public TaskExecutions() {
    }

    @JsonProperty("taskExecutionResourceList")
    List<TaskExecutionResource> taskExecutionResourceList = new ArrayList<>();
    
    @JsonProperty("taskExecutionResourceList")
    public List<TaskExecutionResource> getTaskExecutionResourceList() {
        return taskExecutionResourceList;
    }
    
    @JsonProperty("taskExecutionResourceList")
    public void setTaskExecutionResourceList(List<TaskExecutionResource> taskExecutionResourceList) {
        this.taskExecutionResourceList = taskExecutionResourceList;
    }
    
    
}

TaskExecutionResource如下所示:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "executionId",
    "exitCode",
    "taskName",
    "startTime",
    "endTime",
    "exitMessage",
    "arguments",
    "jobExecutionIds",
    "errorMessage",
    "externalExecutionId",
    "parentExecutionId",
    "resourceUrl",
    "appProperties",
    "deploymentProperties",
    "taskExecutionStatus",
    "_links" })
@JsonIgnoreProperties(ignoreUnknown = true)
public class TaskExecutionResource {

    @JsonProperty("executionId")
    private Integer executionId;
    @JsonProperty("exitCode")
    private Integer exitCode;
    @JsonProperty("taskName")
    private String taskName;
    @JsonProperty("startTime")
    private String startTime;
    @JsonProperty("endTime")
    private String endTime;
    @JsonProperty("exitMessage")
    private Object exitMessage;
    @JsonProperty("arguments")
    private List<String> arguments = new ArrayList<String>();
    @JsonProperty("jobExecutionIds")
    private List<Object> jobExecutionIds = new ArrayList<Object>();
    @JsonProperty("errorMessage")
    private Object errorMessage;
    @JsonProperty("externalExecutionId")
    private String externalExecutionId;
    @JsonProperty("parentExecutionId")
    private Object parentExecutionId;
    @JsonProperty("resourceUrl")
    private String resourceUrl;
    @JsonProperty("appProperties")
    private AppProperties appProperties;
    @JsonProperty("deploymentProperties")
    private DeploymentProperties deploymentProperties;
    @JsonProperty("taskExecutionStatus")
    private String taskExecutionStatus;
    @JsonProperty("_links")
    private Links links;

    @JsonProperty("executionId")
    public Integer getExecutionId() {
        return executionId;
    }

    @JsonProperty("executionId")
    public void setExecutionId(Integer executionId) {
        this.executionId = executionId;
    }

    @JsonProperty("exitCode")
    public Integer getExitCode() {
        return exitCode;
    }

    @JsonProperty("exitCode")
    public void setExitCode(Integer exitCode) {
        this.exitCode = exitCode;
    }

    @JsonProperty("taskName")
    public String getTaskName() {
        return taskName;
    }

    @JsonProperty("taskName")
    public void setTaskName(String taskName) {
        this.taskName = taskName;
    }

    @JsonProperty("startTime")
    public String getStartTime() {
        return startTime;
    }

    @JsonProperty("startTime")
    public void setStartTime(String startTime) {
        this.startTime = startTime;
    }

    @JsonProperty("endTime")
    public String getEndTime() {
        return endTime;
    }

    @JsonProperty("endTime")
    public void setEndTime(String endTime) {
        this.endTime = endTime;
    }

    @JsonProperty("exitMessage")
    public Object getExitMessage() {
        return exitMessage;
    }

    @JsonProperty("exitMessage")
    public void setExitMessage(Object exitMessage) {
        this.exitMessage = exitMessage;
    }

    @JsonProperty("arguments")
    public List<String> getArguments() {
        return arguments;
    }

    @JsonProperty("arguments")
    public void setArguments(List<String> arguments) {
        this.arguments = arguments;
    }

    @JsonProperty("jobExecutionIds")
    public List<Object> getJobExecutionIds() {
        return jobExecutionIds;
    }

    @JsonProperty("jobExecutionIds")
    public void setJobExecutionIds(List<Object> jobExecutionIds) {
        this.jobExecutionIds = jobExecutionIds;
    }

    @JsonProperty("errorMessage")
    public Object getErrorMessage() {
        return errorMessage;
    }

    @JsonProperty("errorMessage")
    public void setErrorMessage(Object errorMessage) {
        this.errorMessage = errorMessage;
    }

    @JsonProperty("externalExecutionId")
    public String getExternalExecutionId() {
        return externalExecutionId;
    }

    @JsonProperty("externalExecutionId")
    public void setExternalExecutionId(String externalExecutionId) {
        this.externalExecutionId = externalExecutionId;
    }

    @JsonProperty("parentExecutionId")
    public Object getParentExecutionId() {
        return parentExecutionId;
    }

    @JsonProperty("parentExecutionId")
    public void setParentExecutionId(Object parentExecutionId) {
        this.parentExecutionId = parentExecutionId;
    }

    @JsonProperty("resourceUrl")
    public String getResourceUrl() {
        return resourceUrl;
    }

    @JsonProperty("resourceUrl")
    public void setResourceUrl(String resourceUrl) {
        this.resourceUrl = resourceUrl;
    }

    @JsonProperty("appProperties")
    public AppProperties getAppProperties() {
        return appProperties;
    }

    @JsonProperty("appProperties")
    public void setAppProperties(AppProperties appProperties) {
        this.appProperties = appProperties;
    }

    @JsonProperty("deploymentProperties")
    public DeploymentProperties getDeploymentProperties() {
        return deploymentProperties;
    }

    @JsonProperty("deploymentProperties")
    public void setDeploymentProperties(DeploymentProperties deploymentProperties) {
        this.deploymentProperties = deploymentProperties;
    }

    @JsonProperty("taskExecutionStatus")
    public String getTaskExecutionStatus() {
        return taskExecutionStatus;
    }

    @JsonProperty("taskExecutionStatus")
    public void setTaskExecutionStatus(String taskExecutionStatus) {
        this.taskExecutionStatus = taskExecutionStatus;
    }

    @JsonProperty("_links")
    public Links getLinks() {
        return links;
    }

    @JsonProperty("_links")
    public void setLinks(Links links) {
        this.links = links;
    }
}

方法2:在我的项目中添加sping-Cloud-data-flow-rest作为maven依赖项,并使用在该项目中定义的TaskExectuion Resources实体。:

TaskExecutionResource.Page = restTemplate.getForObject("http://dataflow-server.myhost.net/tasks/executions?task1225",
                TaskExecutionResource.Page.class);//**Empty content**

问题:如何反序列化使用HATEOAS的rest enndpoint返回的JSON响应?这似乎是一项非常艰巨的任务。

共有1个答案

苏边浩
2023-03-14

不确定您是如何构建RestTemboard的,但它不像hateoas那样工作,您需要执行一些额外的步骤。

要了解我们做了什么,请参阅ObjectMapper配置。还有hal模块和额外的mixin,这是mapper需要知道的,才能让这些东西工作。

 类似资料:
  • 我正在尝试使用RestTemplate使用REST服务。我无法反序列化JSON响应。我正在使用一个自定义反序列化程序,我的JSON有3个节点,但看起来只有一个节点到达反序列化程序。以下是更多详细信息。 以下是JSON的响应: 我正在使用@jsondeselizer对属性Hello的响应类使用自定义反序列化器。 当我执行如下readTree时: 它到达了反序列化方法,看起来它只有一个节点,而不是下面

  • 代码试图采用java.awt.color类使用jackson对象映射器对其进行序列化。获取生成的json字符串并将其反序列化回java.awt.color类。但是在进行反序列化时会出现以下错误。 线程"main"com.fasterxml.jackson.databind.JsonMappingException中的异常:找不到适合类型[简单类型,类java.awt.颜色]的构造函数:无法从JSO

  • 问题内容: 我试图序列化和反序列化内部对象的数组列表: HairList对象也是一个可序列化的对象。 此代码执行返回以下错误: 排队 我不知道我在做什么错。你能给个小费吗? 更新: 解决: 仅使用HairBirt的本机数组而不是ArrayList即可工作: 代替 感谢大家的帮助。 问题答案: 不要使用-而是使用二进制数据并对它进行base64编码,以将其转换为字符串而不会丢失信息。 我强烈怀疑这是

  • 问题内容: 作为一个小项目,我一直在尝试做一个小事,它可以读取序列化的lambda(从本地或从FTP)并调用它们的运行函数作为测试的一部分,以测试Windows中的文件关联(即打开某些文件类型)使用特定程序打开它们),但不管如何,无论如何,它似乎从未正确地反序列化。 lambda被这样声明 并使用由ObjectOutputStream包装的[n可选] BufferedOutputStream包装的

  • 问题内容: 在hibernate状态下执行条件查询时,出现以下异常: 可能是什么问题呢? PS:虽然可能不相关,但我的hibernate版本是hibernate-4.0.1 final。 问题答案: 问题在于被引用的实体对实体有另一个引用,并且该关系未由任何-like注释进行注释。