【问题标题】:Fetch response of a GET request in a serializable object在可序列化对象中获取 GET 请求的响应
【发布时间】:2022-12-09 01:03:07
【问题描述】:

我试图将我的 GET 请求的响应存储在我构建的 Bean 类之一中,但我看到在 POJO 内声明的变量中获取的值是 null。

下面是 GET 请求的代码。

 ValidatableResponse response = given().header("Authorization", token).header("Content-type", "application/json")
                    .when().log().all().pathParam("CalendarId", testCaseBean.getCalendarId().toString()).urlEncodingEnabled(false)
                    .queryParam("from", testCaseBean.getStartDate()).queryParam("to", testCaseBean.getEndDate())
                    .queryParam("monthEnd", testCaseBean.getMonthEndBusinessDay())
                    .get(EndPoint.GET_CALENDAR_DETAILS_BY_MULTIPLE_CALENDAR_CODE).then().log().all();
    
            IndexCalendarDateResponseBeanactualRIOutput = CommonUtils.getJSONMapper()
                    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                    .readValue(response.extract().asString(), IndexCalendarDateResponseBean.class)

;

下面是 IndexCalendarDateResponseBean bean 类

package com.tar.indexes.bean;

import java.time.LocalDate;
import java.util.List;

import com.tar.indexes.marketdata.api.dto.IndexCalendarDateResponseWrapper;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor

public class IndexCalendarDateResponseBean {
    
    List<IndexCalendarDateResponseWrapper> calendarId;

}

IndexCalendarDateResponseWrapper 和 API 响应如下。

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.time.LocalDate;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class InCalendarDateResponseWrapper {

    private String calendarId;

    private LocalDate calDat;

    private LocalDate prevBus;

    private LocalDate nextBus;

    private Boolean bus;

    private Boolean  monthEnd;

}

GET API 的响应如下。

{
    "EU": [
        {
            "calendarId": "EU",
            "calDat": "2022-11-01",
            "prevBus": "2022-10-31",
            "nextBus": "2022-11-02",
            "bus": true,
            "monthEnd": false
        }
    ],
    "AU": [
        {
            "calendarId": "AU",
            "calDat": "2022-11-01",
            "prevBus": "2022-10-31",
            "nextBus": "2022-11-02",
            "bus": true,
            "monthEnd": false
        }
    ]
}

当我尝试使用调试和打印响应中的值之一时,

String t = actualRIOutput.getCalendarId().get(0).getCalendarId();
        System.out.println(t);

我得到的 t 值为 null 而不是 EU。我在获取响应值时有什么错误吗?

【问题讨论】:

  • 什么是CommonUtils
  • 您是自己生成 JSON 响应还是依赖 API?
  • 依赖于API

标签: java rest-assured


【解决方案1】:

可以使用自定义解串器。但我必须创建一个特定的枚举 Country 代表“国家”(不是真正的国家,但我没有找到更好的名字 ;-) )。

请参阅下面的代码:

枚举国家

public enum Country {
    EU("EU"), AU("AU");

    String code;

    Country(String code) {
        this.code = code;
    }

    String code() {
        return code;
    }
}

类索引 CalendarDate ResponseBean

import java.util.ArrayList;
import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class IndexCalendarDateResponseBean {

    private List<IndexCalendarDateResponseWrapper> calendarId;

    public IndexCalendarDateResponseBean() {
        super();
        calendarId = new ArrayList<IndexCalendarDateResponseWrapper>();
    }

    public List<IndexCalendarDateResponseWrapper> getCalendarId() {
        return calendarId;
    }

    public void setCalendarId(List<IndexCalendarDateResponseWrapper> calendarId) {
        this.calendarId = calendarId;
    }
}

类 IndexCalendarDateResponseWrapper

import java.time.LocalDate;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class IndexCalendarDateResponseWrapper {

    private String calendarId;

    private LocalDate calDat;

    private LocalDate prevBus;

    private LocalDate nextBus;

    private Boolean bus;

    private Boolean monthEnd;

    public String getCalendarId() {
        return calendarId;
    }

    public LocalDate getCalDat() {
        return calDat;
    }

    public void setCalDat(LocalDate calDat) {
        this.calDat = calDat;
    }

    public LocalDate getPrevBus() {
        return prevBus;
    }

    public void setPrevBus(LocalDate prevBus) {
        this.prevBus = prevBus;
    }

    public LocalDate getNextBus() {
        return nextBus;
    }

    public void setNextBus(LocalDate nextBus) {
        this.nextBus = nextBus;
    }

    public Boolean getBus() {
        return bus;
    }

    public void setBus(Boolean bus) {
        this.bus = bus;
    }

    public Boolean getMonthEnd() {
        return monthEnd;
    }

    public void setMonthEnd(Boolean monthEnd) {
        this.monthEnd = monthEnd;
    }

    public void setCalendarId(String calendarId) {
        this.calendarId = calendarId;
    }
    
    private void appendText(StringBuilder sb, String text) {
        sb.append(text).append("
");
    }
    
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        appendText(sb, "	bus: "+getBus());
        appendText(sb, "	calDat: "+getCalDat());
        appendText(sb, "	calendarId: "+getCalendarId());
        appendText(sb, "	monthEnd: "+getMonthEnd());
        appendText(sb, "	nextBus: "+getNextBus());
        appendText(sb, "	prevBus: "+getPrevBus());
        return sb.toString();
    }
}

自定义国家解串器

import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

public class CustomCountryDeserializer extends StdDeserializer<IndexCalendarDateResponseBean> {

    protected CustomCountryDeserializer(Class<IndexCalendarDateResponseBean> valueClass) {
        super(valueClass);
    }

    @Override
    public IndexCalendarDateResponseBean deserialize(JsonParser jsonParser, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        JsonNode node = jsonParser.getCodec().readTree(jsonParser);
        IndexCalendarDateResponseBean bean = new IndexCalendarDateResponseBean();
        List<IndexCalendarDateResponseWrapper> wrappers = new ArrayList<IndexCalendarDateResponseWrapper>();
        IndexCalendarDateResponseWrapper wrapper;

        Country c = null;
        JsonNode subNode;
        for (Country country : Country.values()) {
            subNode = node.get(country.code()).get(0);
            if (subNode.get("calendarId").asText().equals(country.code())) {
                c = country;
                wrapper = new IndexCalendarDateResponseWrapper();
                wrapper.setBus(subNode.get("bus").asBoolean());
                wrapper.setCalDat(LocalDate.parse(subNode.get("calDat").asText()));
                wrapper.setCalendarId(subNode.get("calendarId").asText());
                wrapper.setMonthEnd(subNode.get("monthEnd").asBoolean());
                wrapper.setNextBus(LocalDate.parse(subNode.get("nextBus").asText()));
                wrapper.setPrevBus(LocalDate.parse(subNode.get("prevBus").asText()));
                wrappers.add(wrapper);
            }
        }
        bean.setCalendarId(wrappers);
        return bean;
    }
}

一个简单的类来测试所有的东西

import java.io.IOException;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;

public class TestRequestWithEnum {
    private String response;

    public TestRequestWithEnum() {
        super();
        this.initialize();
    }

    /**
     * Initialize the response string
     */
    private void initialize() {
        StringBuilder sb = new StringBuilder();
        appendLine(sb, "{");
        appendLine(sb, ""EU": [");
        appendLine(sb, "{");
        appendLine(sb, ""calendarId": "EU",");
        appendLine(sb, ""calDat": "2022-11-01",");
        appendLine(sb, " "prevBus": "2022-10-31",");
        appendLine(sb, " "nextBus": "2022-11-02",");
        appendLine(sb, ""bus": true,");
        appendLine(sb, ""monthEnd": false");
        appendLine(sb, " }");
        appendLine(sb, "],");
        appendLine(sb, ""AU": [");
        appendLine(sb, "{");
        appendLine(sb, ""calendarId": "AU",");
        appendLine(sb, ""calDat": "2022-11-01",");
        appendLine(sb, " "prevBus": "2022-10-31",");
        appendLine(sb, " "nextBus": "2022-11-02",");
        appendLine(sb, " "bus": true,");
        appendLine(sb, " "monthEnd": false");
        appendLine(sb, " }");
        appendLine(sb, "]");
        appendLine(sb, "}");

        this.response = sb.toString();
    }

    private void appendLine(StringBuilder sb, String text) {
        sb.append(text).append("
");
    }

    public void testWithEnum() {
        ObjectMapper oMapper = new JsonMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        oMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);

        //Register a module with deserializer on ObjectMapper
        SimpleModule module = new SimpleModule("CustomCountryDeserializer");
        module.addDeserializer(IndexCalendarDateResponseBean.class, new CustomCountryDeserializer(IndexCalendarDateResponseBean.class));
        oMapper.registerModule(module);
        try {
            //Deserialize string
            IndexCalendarDateResponseBean bean = oMapper.readValue(response, new TypeReference<IndexCalendarDateResponseBean>() {});
            bean.getCalendarId() .forEach(calendarId -> System.out.println(calendarId.toString()));
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        TestRequestWithEnum test = new TestRequestWithEnum();
        test.testWithEnum();
    }
}

希望能帮助到你...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-22
    • 2018-07-07
    • 2019-10-19
    • 2016-09-14
    相关资源
    最近更新 更多