当手动创建JSON数据,我应该怎么逃串领域? 我应该使用类似的Apache Commons Lang中的StringEscapeUtilities.escapeHtml
, StringEscapeUtilities.escapeXml
,或者我应该使用java.net.URLEncoder
?
问题是,当我使用SEU.escapeHtml
,它并没有逃脱引号,当我换整串的一对'
S,一个畸形的JSON将产生。
当手动创建JSON数据,我应该怎么逃串领域? 我应该使用类似的Apache Commons Lang中的StringEscapeUtilities.escapeHtml
, StringEscapeUtilities.escapeXml
,或者我应该使用java.net.URLEncoder
?
问题是,当我使用SEU.escapeHtml
,它并没有逃脱引号,当我换整串的一对'
S,一个畸形的JSON将产生。
理想的情况下, 找到您的语言的JSON库 ,你可以喂一些合适的数据结构, 并让它担心如何逃脱的事情 。 这将让你更加健壮。 如果出于某种原因你没有在你的语言库,你不希望使用一个(我不会建议this¹),或者你正在写一个JSON库,阅读。
根据RFC逃避它。 JSON是相当自由的:你必须转义字符只有\
, "
和(不是U + 0020少任何东西)控制代码。
逃逸的这种结构是专用于JSON。 你需要一个JSON特定功能。 所有逃逸的可以写成\uXXXX
,其中XXXX
是该字符的UTF-16代码unit¹。 有几个快捷键,如\\
,其正常工作。 (他们得到一个更小,更清晰的输出。)
有关详情,请参阅的RFC 。
¹JSON的转义是建立在JS,所以它使用\uXXXX
,其中XXXX
是一个UTF-16代码单元。 对于BMP外码点,这意味着编码代理对,其可以得到位有毛。 (或者,你可以直接输出的字符直接,因为JSON的编码为是Unicode文本,并允许这些特殊字符)。
提取抛弃 :
public static String quote(String string) {
if (string == null || string.length() == 0) {
return "\"\"";
}
char c = 0;
int i;
int len = string.length();
StringBuilder sb = new StringBuilder(len + 4);
String t;
sb.append('"');
for (i = 0; i < len; i += 1) {
c = string.charAt(i);
switch (c) {
case '\\':
case '"':
sb.append('\\');
sb.append(c);
break;
case '/':
// if (b == '<') {
sb.append('\\');
// }
sb.append(c);
break;
case '\b':
sb.append("\\b");
break;
case '\t':
sb.append("\\t");
break;
case '\n':
sb.append("\\n");
break;
case '\f':
sb.append("\\f");
break;
case '\r':
sb.append("\\r");
break;
default:
if (c < ' ') {
t = "000" + Integer.toHexString(c);
sb.append("\\u" + t.substring(t.length() - 4));
} else {
sb.append(c);
}
}
}
sb.append('"');
return sb.toString();
}
试试这个org.codehaus.jettison.json.JSONObject.quote("your string")
在这里下载: http://mvnrepository.com/artifact/org.codehaus.jettison/jettison
org.json.simple.JSONObject.escape()逃逸报价,\,/,\ R,\ N,\ B,\楼\吨和其它控制字符。 它可以用来逃跑的JavaScript代码。
import org.json.simple.JSONObject;
String test = JSONObject.escape("your string");
阿帕奇公共朗现在支持这一点。 只要确保你的Apache Commons Lang中的最新版本,足以在你的类路径。 你需要的版本3.2+
发行说明3.2版
LANG-797:增加逃生/ unescapeJson到StringEscapeUtils。
org.json.JSONObject
quote(String data)
方法执行工作
import org.json.JSONObject;
String jsonEncodedString = JSONObject.quote(data);
从文档摘录:
数据编码JSON字符串。 这适用报价和任何必要的字符转义 。 [...]空将被解释为空字符串
StringEscapeUtils.escapeJavaScript
/ StringEscapeUtils.escapeEcmaScript
应该做的伎俩。
如果您正在使用fastexml杰克逊,你可以使用以下命令: com.fasterxml.jackson.core.io.JsonStringEncoder.getInstance().quoteAsString(input)
如果您正在使用Codehaus的杰克逊,你可以使用以下命令: org.codehaus.jackson.io.JsonStringEncoder.getInstance().quoteAsString(input)
不知道你的“手动创建JSON”的意思,但你可以使用像GSON( http://code.google.com/p/google-gson/ ),这将改变你的HashMap,数组,字符串,等等涉及一种JSON值。 我建议您用这个框架去。
我没有花时间,使100%肯定,但它的工作对我的投入,足以通过网上JSON验证被接受:
org.apache.velocity.tools.generic.EscapeTool.EscapeTool().java("input")
虽然它不看任何优于org.codehaus.jettison.json.JSONObject.quote("your string")
我简单地使用速度的工具在我的项目已经 - 我的“手动JSON”建设是一个Velocity模板中
对于那些谁来到这里寻找一个命令行的解决方案,像我这样的,卷曲的--data-进行urlencode正常工作:
curl -G -v -s --data-urlencode 'query={"type" : "/music/artist"}' 'https://www.googleapis.com/freebase/v1/mqlread'
发送
GET /freebase/v1/mqlread?query=%7B%22type%22%20%3A%20%22%2Fmusic%2Fartist%22%7D HTTP/1.1
, 例如。 较大的JSON数据可以放在一个文件,你应该使用@语法指定文件从待转义的数据来发出声音。 例如,如果
$ cat 1.json
{
"type": "/music/artist",
"name": "The Police",
"album": []
}
你会使用
curl -G -v -s --data-urlencode query@1.json 'https://www.googleapis.com/freebase/v1/mqlread'
而现在,这也是关于如何通过命令行查询的游离碱的教程:-)
使用EscapeUtils类公郎API。
EscapeUtils.escapeJavaScript("Your JSON string");
考虑莫西的JsonWriter类。 它有一个美好的API,并且减少复制到最低限度,一切都可以很好地传输到一个提交的OutputStream等
OutputStream os = ...;
JsonWriter json = new JsonWriter(Okio.buffer(Okio.sink(os)));
json.beginObject();
json.name("id").value(getId());
json.name("scores");
json.beginArray();
for (Double score : getScores()) {
json.value(score);
}
json.endArray();
json.endObject();
如果你想在手头的字符串:
Buffer b = new Buffer(); // okio.Buffer
JsonWriter writer = new JsonWriter(b);
//...
String jsonString = b.readUtf8();
如果您需要逃避JSON JSON字符串内,使用org.json.JSONObject.quote(“需要进行转义你的JSON字符串”)似乎运作良好
使用为\ uXXXX语法就可以解决这个问题,谷歌UTF-16与符号的名称,你可以找到XXXX,例如:UTF-16双引号
在这里,显示实际执行的方法都是错误的。
我没有Java代码,而只是备案,你可以很容易地转换这个C#-code:
单项目的礼貌@ https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility.cs
public static string JavaScriptStringEncode(string value, bool addDoubleQuotes)
{
if (string.IsNullOrEmpty(value))
return addDoubleQuotes ? "\"\"" : string.Empty;
int len = value.Length;
bool needEncode = false;
char c;
for (int i = 0; i < len; i++)
{
c = value[i];
if (c >= 0 && c <= 31 || c == 34 || c == 39 || c == 60 || c == 62 || c == 92)
{
needEncode = true;
break;
}
}
if (!needEncode)
return addDoubleQuotes ? "\"" + value + "\"" : value;
var sb = new System.Text.StringBuilder();
if (addDoubleQuotes)
sb.Append('"');
for (int i = 0; i < len; i++)
{
c = value[i];
if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62)
sb.AppendFormat("\\u{0:x4}", (int)c);
else switch ((int)c)
{
case 8:
sb.Append("\\b");
break;
case 9:
sb.Append("\\t");
break;
case 10:
sb.Append("\\n");
break;
case 12:
sb.Append("\\f");
break;
case 13:
sb.Append("\\r");
break;
case 34:
sb.Append("\\\"");
break;
case 92:
sb.Append("\\\\");
break;
default:
sb.Append(c);
break;
}
}
if (addDoubleQuotes)
sb.Append('"');
return sb.ToString();
}
这可以被压缩成
// https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cs
public class SimpleJSON
{
private static bool NeedEscape(string src, int i)
{
char c = src[i];
return c < 32 || c == '"' || c == '\\'
// Broken lead surrogate
|| (c >= '\uD800' && c <= '\uDBFF' &&
(i == src.Length - 1 || src[i + 1] < '\uDC00' || src[i + 1] > '\uDFFF'))
// Broken tail surrogate
|| (c >= '\uDC00' && c <= '\uDFFF' &&
(i == 0 || src[i - 1] < '\uD800' || src[i - 1] > '\uDBFF'))
// To produce valid JavaScript
|| c == '\u2028' || c == '\u2029'
// Escape "</" for <script> tags
|| (c == '/' && i > 0 && src[i - 1] == '<');
}
public static string EscapeString(string src)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
int start = 0;
for (int i = 0; i < src.Length; i++)
if (NeedEscape(src, i))
{
sb.Append(src, start, i - start);
switch (src[i])
{
case '\b': sb.Append("\\b"); break;
case '\f': sb.Append("\\f"); break;
case '\n': sb.Append("\\n"); break;
case '\r': sb.Append("\\r"); break;
case '\t': sb.Append("\\t"); break;
case '\"': sb.Append("\\\""); break;
case '\\': sb.Append("\\\\"); break;
case '/': sb.Append("\\/"); break;
default:
sb.Append("\\u");
sb.Append(((int)src[i]).ToString("x04"));
break;
}
start = i + 1;
}
sb.Append(src, start, src.Length - start);
return sb.ToString();
}
}
我认为在2017年最好的答案就是使用javax.json的API。 使用javax.json.JsonBuilderFactory来创建JSON对象,然后写出来的对象使用javax.json.JsonWriterFactory。 非常漂亮的建设者/刻录组合。
阿帕奇公地文本现在有一个StringEscapeUtils.escapeJson(字符串) 。