问题描述
请不要为我编辑问题.我的问题是关于字符串操作,改变文本的流向很可能会改变问题的含义并引起混淆.
这个问题可以看作是一个字符串操作问题.但我希望杰克逊有一个解决方案来解决我的问题.
假设我收到一个字符串 {"payload":{"foo":"bar","ipsum":["lorem","lorem"]},"signature":"somehmacsign"}代码>.显示的时候是这样的:
Suppose I have received a String {"payload":{"foo":"bar","ipsum":["lorem","lorem"]},"signature":"somehmacsign"}
. When it's displayed, it's like:
{
"payload": {
"foo": "bar",
"ipsum": [
"lorem",
"lorem"
]
},
"signature": "somehmacsign"
}
如何从第 11 个字符 {
直到 ,"signature"
之前的 }
提取其子字符串.即,{"foo":"bar","ipsum":["lorem","lorem"]}
.从语义上讲,我想为 payload
字段提取 original 字符串表示.我想它不应该涉及将 JSON 字符串解析为 Java 对象并返回到字符串.我不想冒失去字段顺序、间距或任何小功能的风险,因为它是 HMAC 签名的.
How can I extract its substring from 11th character {
till the }
just before ,"signature"
. Namely, {"foo":"bar","ipsum":["lorem","lorem"]}
. Semantically, I want to extract the original string representation for the payload
field. I suppose it should not involve parsing the JSON string to Java objects and back to String. I don't want to risk losing the order of fields, spacing, or whatever small features because it's meant to be HMAC signed.
编辑 1: 改写以澄清此问题与 Java 字符串文字无关.
EDIT 1: Rephrased to clarify that this problem has nothing to do with Java String literal.
编辑 2: 虽然现在说可能有点早,但总的来说,我的问题没有明显的现成解决方案(如何部分提取/解析 JSON 字符串).事实上,我自己发现我的懒惰/部分解析理论有点冗长.它需要太多的传递才能定位一个深层嵌套的节点.
EDIT 2: Though it may be a bit early to say, there is no obvious off-the-shelf solution to my question in general (how to partial extract/parse a JSON string). In fact, I myself find my lazy/partial parsing theory a bit verbose. It requires way too many of passes to locate a deeply-nested node.
特别是在我的情况下,我发现在请求正文中附加签名是一个坏主意,因为它给接收方带来了困难.我正在考虑将签名移动到 HTTP 标头,也许是 X-Auth-Token
?
In particular for my situation, I found appending the signature in the body of a request a bad idea as it poses difficulties for the receiving party. I'm considering moving the signature to HTTP header, maybe X-Auth-Token
?
编辑 3: 事实证明,我真的太早下结论了.Cassio 的回答通过使用自定义反序列化器和神奇的 skipChildren
完美地解决了这个问题!
EDIT 3: As it turns out, I was really concluding too early. Cassio's answer perfectly solves the problem by using custom deserializer and the magic skipChildren
!
推荐答案
您可以将签名移至 HTTP 标头以简化操作.
You could move the signature to a HTTP header to make things simpler.
但是,如果您想在请求负载中保留签名,请按照以下步骤操作.
However, if you want to keep the signature in the request payload, follow the steps described below.
创建一个可以获取原始 JSON 字符串值的自定义反序列化器:
Create a custom deserializer that can get the raw JSON string value:
public class RawJsonDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
long begin = jp.getCurrentLocation().getCharOffset();
jp.skipChildren();
long end = jp.getCurrentLocation().getCharOffset();
String json = jp.getCurrentLocation().getSourceRef().toString();
return json.substring((int) begin - 1, (int) end);
}
}
创建一个 Java 类来保存值
创建一个Java类来保存值(注意@JsonDeserialize
注释):
public class Request {
@JsonDeserialize(using = RawJsonDeserializer.class)
private String payload;
private String signature;
// Getters and setters ommitted
}
解析 JSON
使用 ObjectMapper
并且 Jackson 将使用您在上面定义的反序列化器:
Parsing the JSON
Parse the JSON using ObjectMapper
and Jackson will use the deserializer you have defined above:
String json = "{"payload":{"foo":"bar","ipsum":["lorem"," +
""lorem"]},"signature":"somehmacsign"}";
ObjectMapper mapper = new ObjectMapper();
Request request = mapper.readValue(json, Request.class);
如果 payload
是无效的 JSON,Jackson 会抛出异常.
If the payload
is an invalid JSON, Jackson will throw an exception.
这篇关于如何使用 Jackson 从 JSON 中提取部分*原始*文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!