JSON에서 문자열을 어떻게 이스케이프해야합니까?
JSON 데이터를 수동으로 생성 할 때 문자열 필드를 어떻게 이스케이프해야합니까? 아파치 코 몬즈 랭의 같은해야 내가 사용 무언가 StringEscapeUtilities.escapeHtml, StringEscapeUtilities.escapeXml또는 사용해야합니까 java.net.URLEncoder?
문제는을 사용할 때 SEU.escapeHtml따옴표를 이스케이프하지 않고 전체 문자열을 's 쌍으로 감싸면 잘못된 JSON이 생성된다는 것입니다.
이상적으로는 적절한 데이터 구조를 제공 할 수있는 언어로 된 JSON 라이브러리를 찾고 이스케이프 처리 방법에 대해 걱정하도록하십시오 . 훨씬 더 건강하게 유지합니다. 어떤 이유로 든 귀하의 언어로 된 라이브러리가 없다면, 하나를 사용하고 싶지 않거나 (이 제안하지 않을 것 ¹) JSON 라이브러리를 작성하는 경우 계속 읽으십시오.
RFC에 따라 이스케이프 처리하십시오. JSON은 매우 진보적이다 : 당신이 유일한 문자가 있어야 탈출은 \, "제어 코드 (아무것도 덜 U + 0020 이상)합니다.
이스케이프 구조는 JSON에만 해당됩니다. JSON 특정 기능이 필요합니다. 모든 이스케이프는 해당 문자의 UTF-16 코드 단위 ¹가있는 \uXXXX위치 로 작성할 수 있습니다 XXXX. 과 같은 몇 가지 단축키 \\가 있습니다. (그리고 그것들은 더 작고 더 선명한 결과를 낳습니다.)
자세한 내용 은 RFC를 참조하십시오 .
¹JSON의 탈출은 그래서 사용 JS에 내장되는 \uXXXX경우, XXXXUTF-16 코드 유닛이다. BMP 외부의 코드 포인트의 경우 이는 대리 쌍을 인코딩하는 것을 의미하며 약간 털이 될 수 있습니다. (또는 JSON의 인코딩은 유니 코드 텍스트이므로 이러한 특정 문자를 허용하므로 문자를 직접 출력 할 수 있습니다.)
Jettison 에서 추출 :
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, \ f, \ t 및 기타 제어 문자를 이스케이프합니다. JavaScript 코드를 이스케이프 처리하는 데 사용할 수 있습니다.
import org.json.simple.JSONObject;
String test = JSONObject.escape("your string");
Apache commons lang은 이제 이것을 지원합니다. 클래스 경로에 최신 버전의 Apache Commons lang이 있는지 확인하십시오. 버전 3.2 이상이 필요합니다
버전 3.2 릴리스 정보
LANG-797 : StringEscapeUtils에 escape / unescapeJson을 추가했습니다.
org.json.JSONObject quote(String data) 방법은 일을한다
import org.json.JSONObject;
String jsonEncodedString = JSONObject.quote(data);
문서에서 추출하십시오.
데이터를 JSON 문자열로 인코딩합니다. 이것은 따옴표와 필요한 문자 이스케이프를 적용합니다 . [...] Null은 빈 문자열로 해석됩니다.
StringEscapeUtils.escapeJavaScript/ StringEscapeUtils.escapeEcmaScript트릭도 수행해야합니다.
fastexml jackson을 사용중인 경우 다음을 사용할 수 있습니다. com.fasterxml.jackson.core.io.JsonStringEncoder.getInstance().quoteAsString(input)
codehaus jackson을 사용하는 경우 다음을 사용할 수 있습니다. org.codehaus.jackson.io.JsonStringEncoder.getInstance().quoteAsString(input)
'json 수동으로 생성'의 의미가 확실하지 않지만 gson ( http://code.google.com/p/google-gson/ ) 과 같은 것을 사용할 수 있으며 HashMap, Array, String 등을 변형시킬 수 있습니다. , JSON 값으로. 나는 이것을위한 프레임 워크를 사용하는 것이 좋습니다.
나는 100 % 확실하게하는 데 시간을 소비하지 않았지만 온라인 JSON 유효성 검사기에서 입력을 받아 들일 수있을 정도로 입력에 효과적이었습니다.
org.apache.velocity.tools.generic.EscapeTool.EscapeTool().java("input")
비록 더 나아 보이지는 않지만 org.codehaus.jettison.json.JSONObject.quote("your string")
이미 프로젝트에서 속도 도구를 사용하고 있습니다. "수동 JSON"건물은 속도 템플릿 내에있었습니다.
나 같은 명령 줄 솔루션을 찾는 사람들에게 cURL의 --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'
그리고 지금, 이것은 커맨드 라인에서 Freebase를 쿼리하는 방법에 대한 튜토리얼입니다 :-)
commons lang API에서 EscapeUtils 클래스를 사용하십시오.
EscapeUtils.escapeJavaScript("Your JSON string");
Moshi 의 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 구문을 사용하면이 문제를 해결할 수 있습니다 .Google UTF-16 기호 이름으로 XXXX를 찾을 수 있습니다 (예 : utf-16 큰 따옴표)
실제 구현을 보여주는 여기의 방법은 모두 잘못되었습니다.
Java 코드는 없지만 레코드 용 으로이 C # 코드를 쉽게 변환 할 수 있습니다.
Courtesy of the mono-project @ 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();
}
This can be compacted into
// 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();
}
}
I think the best answer in 2017 is to use the javax.json APIs. Use javax.json.JsonBuilderFactory to create your json objects, then write the objects out using javax.json.JsonWriterFactory. Very nice builder/writer combination.
Apache commons-text now has a StringEscapeUtils.escapeJson(String).
참고URL : https://stackoverflow.com/questions/3020094/how-should-i-escape-strings-in-json
'Programming' 카테고리의 다른 글
| 긴 단어가 내 div를 깨는 것을 방지하는 방법은 무엇입니까? (0) | 2020.06.13 |
|---|---|
| 왜 2 mod 4 = 2입니까? (0) | 2020.06.13 |
| timedelta를 총 초로 변환 (0) | 2020.06.13 |
| log4j vs 로그 백 (0) | 2020.06.13 |
| 팬더에서 특정 열 이름 바꾸기 (0) | 2020.06.13 |