所以我试图在POST后验证一些有效负载。
有效负载(JSON)如下所示:
{"value":"\"<html><body><a href='http://www.example.com'>Hi there!</a></body></html>\""}
然后我尝试将上面的内容转换为JsonNode并提取&#34; 值&#34;的值。但是,这两种方法asText()
&amp; toString()
,返回不同的字符串值。
这两种方法的工作原理有何不同?
给定字符串"\"<html><body><a href='http://www.example.com'>Hi there!</a></body></html>\""
toString 会返回"<html><body><a href='http://www.example.com'>Hi there!</a></body></html>"
asText()返回<html><body><a href='http://www.example.com'>Hi there!</a></body></html>
答案 0 :(得分:6)
<强> asText ()
强>
这是来自JsonNode
的抽象方法,在TextNode
中被覆盖。而且,根据它的实现,它应该在没有任何操作的情况下返回值。
@Override
public String asText() {
return _value;
}
<强> toString ()
强>
它被Object
覆盖。因此,它是 对象的文本表示 。因此,toString
实际上会返回给定对象上的完整文本形式。并且,根据其在TextNode
中的实施情况。它会在您的值附加引用(在开头和结尾)。
/**
* Different from other values, Strings need quoting
*/
@Override
public String toString()
{
int len = _value.length();
len = len + 2 + (len >> 4);
return new StringBuilder(len)
// 09-Dec-2017, tatu: Use apostrophes on purpose to prevent use as JSON producer:
.append('\'')
.append(_value)
.append('\'')
.toString();
}
而且,打印时也可以看到相同的区别。
答案 1 :(得分:0)
asText()和toString()
之间的区别public abstract String asText()
如果节点是值节点(方法isValueNode()返回true),则返回容器值的有效String表示的方法,否则为空String。
public String readNameNode()
{
JsonNode nameNode=rootNode.path("name");
String name=nameNode.asText();
logger.info("\n----------------------------\nEmployee Name: "+name+"\n");
return name;
}
public abstract String toString()
注意:标记为抽象以确保所有实现类都正确定义它。
覆盖: 类中的toString
public String readNameNode()
{
JsonNode nameNode=rootNode.path("name");
String name=nameNode.toString();
logger.info("\n----------------------------\nEmployee Name: "+name+"\n");
return name;
}
希望你能理解asText方法和toString方法之间的确切区别
答案 2 :(得分:0)
只有master分支具有接受的答案的行为;之前的版本(例如Jackson 2.9),toString()
所做的不只是“在字符串周围添加引号”。
如果要检查包含键值对(JSON对象)的某个JsonNode的文本表示形式,则必须使用toString()
; asText()
会让您""
,因为它不是ValueNode
。并且,在此过程中,Unicode(\uxxxx
)将转换为实际字符。
详细信息:
我测试了拥有的lib,然后发现我不同意接受的答案。我的是2.9。
就我而言,toString()
所做的不只是添加引号。至少从版本2.0到2.9,它还将保留字符串内容中的转义字符。
检查来源here(注意URL中的版本。您可以在页面中选择版本,直到2.10)
2.0:
/**
* Different from other values, Strings need quoting
*/
@Override
public String toString()
{
int len = _value.length();
len = len + 2 + (len >> 4);
StringBuilder sb = new StringBuilder(len);
appendQuoted(sb, _value);
return sb.toString();
}
protected static void appendQuoted(StringBuilder sb, String content)
{
sb.append('"');
CharTypes.appendQuoted(sb, content);
sb.append('"');
}
fasterxml.jackson.core.io.CharTypes.appendQuoted()
将保留一些转义字符。在here处检查其来源。(请注意,该代码来自2.0分支,而不是master分支)
public static void appendQuoted(StringBuilder sb, String content)
{
final int[] escCodes = sOutputEscapes128;
int escLen = escCodes.length;
for (int i = 0, len = content.length(); i < len; ++i) {
char c = content.charAt(i);
if (c >= escLen || escCodes[c] == 0) {
sb.append(c);
continue;
}
sb.append('\\');
int escCode = escCodes[c];
if (escCode < 0) { // generic quoting (hex value)
// We know that it has to fit in just 2 hex chars
sb.append('u');
sb.append('0');
sb.append('0');
int value = -(escCode + 1);
sb.append(HEX_CHARS[value >> 4]);
sb.append(HEX_CHARS[value & 0xF]);
} else { // "named", i.e. prepend with slash
sb.append((char) escCode);
}
}
}
但是,现在master
分支似乎将这种行为简化为“仅添加引号”,正如公认的答案所说。可以在this page中看到。实际上,此提交的标题为
删除对CharTypes.appendQuoted()的依赖;将
JsonNode.toString()
的引号更改为单引号以尝试防止用于JSON生成
但是,我再次使用2.9,仍然使用CharTypes.appendQuoted()
。因此,通常,如果您不使用master分支,toString()
将保留转义字符。
示例:
JsonNode node = new TextNode("{\"en_us\":\"54\",\"es_es\":\"54\"}");
node.asText(); // -> {"en_us":"54","es_es":"54"}, no quotations, no escaping
node.toString(); // -> "{\"en_us\":\"54\",\"es_es\":\"54\"}", add quotations, perserves escaping.
因此,使用lib版本并不总是“主”!
对于带有对象的toString()
中的JsonNode
,请检查以下内容:(杰克逊数据绑定2.9)
@Test
public void testToString() {
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.createObjectNode();
((ObjectNode) node).put("es_es", "Categor\u00eda ra\u00edz/CATEGORY_OMS_DATA/");
System.out.println((node.toString())); // {"es_es":"Categoría raíz/CATEGORY_OMS_DATA/"}, note: not quotations around!! not like TextNode!
System.out.println(node.asText()); // empty
}
答案 3 :(得分:0)
我要补充的一件事是,如果字符串很长,对我来说,只使用 .toString()
工作,因为其他两个(.asText()
和 .textValue()
)将返回空字符串和分别为null。