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

通用域名格式。fasterxml。杰克逊。数据绑定。使用fasterxml将json应答解析为对象时发生exc.MismatchedInputException

华泳
2023-03-14

我正在尝试使用fasterxml将json应答解析为POJO。但问题是,json回复包含嵌套的对象,其中包含反斜杠,所以在ObjectMapper读取该值时,我收到了com。fasterxml。杰克逊。数据绑定。exc.不匹配计算异常

我不知道如何用fasterxml解析这个对象?!

我的POJO对象模型如下所示:

@EqualsAndHashCode
@ToString
@Getter
@Builder
public class WsOrderReply {

    private final String topic;
    private final Message message;
    private final Long timestamp;

    @JsonCreator
    public WsOrderReply(
            @JsonProperty("topic") String topic,
            @JsonProperty("message") Message message,
            @JsonProperty("timestamp") Long timestamp) {
        this.topic = topic;
        this.message = message;
        this.timestamp = timestamp;
    }
}

@EqualsAndHashCode
@ToString
@Getter
public class Message {

    private final String entryType;
    private final BigDecimal rate;
    private final String action;
    private final String offerId;
    private final String market;
    private final State state;

    @JsonCreator
    public Message(
            @JsonProperty("entryType") String entryType,
            @JsonProperty("rate") BigDecimal rate,
            @JsonProperty("action") String action,
            @JsonProperty("offerId") String offerId,
            @JsonProperty("market") String market,
            @JsonProperty("state") State state) {
        this.entryType = entryType;
        this.rate = rate;
        this.action = action;
        this.offerId = offerId;
        this.market = market;
        this.state = state;
    }
}

@EqualsAndHashCode
@ToString
@Getter
public class State {

    private final String market;
    private final String offerType;
    private final String id;
    private final BigDecimal currentAmount;
    private final BigDecimal lockedAmount;
    private final BigDecimal rate;
    private final BigDecimal startAmount;
    private final String time;
    private final boolean postOnly;
    private final boolean hidden;
    private final String mode;
    private final BigDecimal receivedAmount;

    public State(
            @JsonProperty("market") String market,
            @JsonProperty("offerType") String offerType,
            @JsonProperty("id") String id,
            @JsonProperty("currentAmount") BigDecimal currentAmount,
            @JsonProperty("lockedAmount") BigDecimal lockedAmount,
            @JsonProperty("rate") BigDecimal rate,
            @JsonProperty("startAmount") BigDecimal startAmount,
            @JsonProperty("time") String time,
            @JsonProperty("postOnly") boolean postOnly,
            @JsonProperty("hidden") boolean hidden,
            @JsonProperty("mode") String mode,
            @JsonProperty("receivedAmount") BigDecimal receivedAmount) {
        this.market = market;
        this.offerType = offerType;
        this.id = id;
        this.currentAmount = currentAmount;
        this.lockedAmount = lockedAmount;
        this.rate = rate;
        this.startAmount = startAmount;
        this.time = time;
        this.postOnly = postOnly;
        this.hidden = hidden;
        this.mode = mode;
        this.receivedAmount = receivedAmount;
    }
}

我收到的原始json消息:

“交易/报价/BTC-PLN-BTC-C-C-PLN,”消息:“信息::““{”交易/交易/报价”主题:“交易/交易/提供/BTC-PLN-BTC-PLN,”消息:“““““““,”消息:“““{”交易/交易/交易/提供/交易/交易/提供/交易/交易/提供/交易/提供/交易/提供/提供/BTC-BTC-CNC-C-PLN-PLN-PLN,”主题:“,,,,,“交易”主题:““,,“交易/价格”主题:“,“交易/交易/交易/交易/交易/交易/交易/交易/交易/利率:”,“利率:“::::::::::::::“22000 0 0 0 0 0 0 0 0 0 0.0.0 0 0 0 0 0 0.0 0.0.0 0 0.0 0 0.0.0.0 0 0 0 0 0.0 0 0.0 0 0 0 0 0005\“,”锁定安装\“:\”11.00\“,”rate\“:”22000.0\“,”startAmount\“:”0.0005\“,”time\“:”1535023208260\“,”postOnly\“:false、”hidden\“:false、”mode\“:”limit\“,”receivedAmount\“:”0\“}”,“timestamp:”1535023208264}”

我的JUnit测试:

public class ReplyMapperTest {

    private static ObjectMapper objectMapper;

    private MessageFactory msgFactory = new quickfix.fix42.MessageFactory();

    private TypeSelector fixMsgBuilder = FixMessageBuilder
            .usingFactory(msgFactory::create)
            .withBeginString(FixVersions.BEGINSTRING_FIX42);

    private ReplyMapper replyMapper = new ReplyMapper(objectMapper, fixMsgBuilder);

    @BeforeClass
    public static void beforeClass() {
        objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    }

    @Test
    public void shouldMapUpdateOrderReplyNew() throws FieldNotFound, IOException {
        String json = IOUtils.toString(this.getClass().getResourceAsStream("/json/UpdateOrderReplyNew.json"), StandardCharsets.UTF_8);

        //When
        List<Message> result = replyMapper.apply(json);

        //Then
        assertThat(result.get(0).getHeader().getString(MsgType.FIELD), is(Heartbeat.MSGTYPE));
    }

也许有人也有和我一样的问题。如何解决这个问题?

共有1个答案

江天宇
2023-03-14

您正在使用的JSON即使在未转义的情况下也是不正确的,因此它将整个对象视为字符串。使用正确的转义json将解决问题,我已经纠正了JSON,你现在看看天气它的工作原理

{\r\n\t\"topic\": \"trading\/offers\/BTC-PLN\",\r\n\t\"message\": {\r\n\t\t\"entryType\": \"Buy\",\r\n\t\t\"rate\": \"22000.0\",\r\n\t\t\"action\": \"update\",\r\n\t\t\"offerId\": \"b96f2da7-55f9-4221-aaa3-8e3ad177567d\",\r\n\t\t\"market\": \"BTC-PLN\",\r\n\t\t\"state\": {\r\n\t\t\t\"market\": \"BTC-PLN\",\r\n\t\t\t\"offerType\": \"Buy\",\r\n\t\t\t\"id\": \"b96f2da7-55f9-4221-aaa3-8e3ad177567d\",\r\n\t\t\t\"currentAmount\": \"0.0005\",\r\n\t\t\t\"lockedAmount\": \"11.00\",\r\n\t\t\t\"rate\": \"22000.0\",\r\n\t\t\t\"startAmount\": \"0.0005\",\r\n\t\t\t\"time\": \"1535023208260\",\r\n\t\t\t\"postOnly\": false,\r\n\t\t\t\"hidden\": false,\r\n\t\t\t\"mode\": \"limit\",\r\n\t\t\t\"receivedAmount\": \"0\"\r\n\t\t}\r\n\t},\r\n\t\"timestamp\": 1535023208264\r\n}

如果无法更改Json,则需要在构造函数中以字符串值的形式获取消息,然后使用对象映射器将其显式转换为对象

public class WsOrderReply {

        private final String topic;
        private final Message message;
        private final Long timestamp;
        ObjectMapper mapper = new ObjectMapper();

        @JsonCreator
        public WsOrderReply(
                @JsonProperty("topic") String topic,
                @JsonProperty("message") String messageString,
                @JsonProperty("timestamp") Long timestamp) {
            this.topic = topic;
            this.message = mapper.readValue(messageString, Message.class);;
            this.timestamp = timestamp;
        }
    }

另一个不需要更改模型类的解决方案是从服务器获取JSON,然后在本地将其更改为第1种方法中提到的格式

 类似资料: