我正在尝试使用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));
}
也许有人也有和我一样的问题。如何解决这个问题?
您正在使用的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种方法中提到的格式