JSON의 끈을 어떻게 벗어나야 할까?
수동으로 JSON 데이터를 생성할 때 문자열 필드를 이스케이프하려면 어떻게 해야 하는가?아파치 커먼즈 랭 같은 걸 써야 할까?StringEscapeUtilities.escapeHtml
,StringEscapeUtilities.escapeXml
또는 내가 사용해야 한다.java.net.URLEncoder
?
문제는 내가 사용할 때SEU.escapeHtml
, 그것은 인용구를 벗어나지 않고 내가 전체 문자열을 한 쌍으로 감싸면'
s, 잘못된 형식의 JSON이 생성될 것이다.
언어에서 적절한 데이터 구조를 제공할 수 있는 JSON 라이브러리를 찾아 어떻게 사물을 탈출할 수 있는지 고민하는 것이 이상적이다.그것은 너를 훨씬 더 건강하게 해 줄 것이다.만약 당신이 당신의 언어로 된 도서관이 없는 이유가 무엇이든 간에, 당신은 도서관을 사용하고 싶지 않다면, 계속 읽으세요.
RFC에 따르면 탈출하라 JSON은 꽤 자유분방하다.당신이 탈출해야 할 유일한 문자는\
,"
, 및 제어 코드(U+0020보다 작은 모든 것).
이러한 탈출구조는 JSON에만 특유하다.JSON별 기능이 필요할 겁니다.모든 탈출구는 다음과 같이 쓰여질 수 있다.\uXXXX
어디에XXXX
해당 문자에 대한 UTF-16 코드 단위 입니다.다음과 같은 몇 가지 지름길이 있다.\\
(그리고 더 작고 선명한 결과를 낳는다.)
자세한 내용은 RFC를 참조하십시오.
¹JSON의 탈출은 JS를 기반으로 구축되어 있어 활용\uXXXX
어디에XXXX
UTF-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.propertiesJSONObject.escape()는 따옴표,\, /, \r, \n, \b, \f, \t 및 기타 제어 문자를 이스케이프한다.자바스크립트 코드 탈출에 사용할 수 있다.
import org.json.simple.JSONObject;
String test = JSONObject.escape("your string");
현재 Apache Commons Text 라이브러리에 StringEscapeUtils#escapeJson(String) 방법이 있다.
관심 방법은 다음과 같다.
이 기능은 처음에 Apache Commons Lang 버전 3.2의 일부로 출시되었지만 그 이후로 사용되지 않고 Apache Commons Text로 이동되었다.따라서 방법이 IDE에서 더 이상 사용되지 않는 것으로 표시된 경우 잘못된 라이브러리에서 구현을 가져오는 경우(두 라이브러리 모두 동일한 클래스 이름을 사용함:StringEscapeUtils).
그 구현은 순수한 Json이 아니다.자바독에 따르면:
Json String 규칙을 사용하여 문자열의 문자를 이스케이프하십시오.
Json String 양식에서 찾은 값에서 벗어난다.견적 및 제어 차(탭, 백슬래시, cr, ff 등)를 올바르게 처리
그래서 탭은 문자 '\'와 't'가 된다.
Java 문자열과 Json 문자열의 유일한 차이점은 Json에서 전방 슬래시(/)가 빠져나간다는 것이다.
자세한 내용은 http://www.ietf.org/rfc/rfc4627.txt을 참조하십시오.
org.json.JSONObject
quote(String data)
방법이 그 일을 한다.
import org.json.JSONObject;
String jsonEncodedString = JSONObject.quote(data);
설명서에서 추출:
데이터를 JSON 문자열로 인코딩하십시오.이것은 따옴표와 모든 필요한 문자의 이스케이프를 적용한다. [...] Null은 빈 문자열로 해석된다.
StringEscapeUtils.escapeJavaScript
/StringEscapeUtils.escapeEcmaScript
너도 한번 해보자.
만약 은 fastexml 을 사용할 수 com.fasterxml.jackson.core.io.JsonStringEncoder.getInstance().quoteAsString(input)
코드하우스 잭슨을 사용하는 경우 다음을 사용하십시오.org.codehaus.jackson.io.JsonStringEncoder.getInstance().quoteAsString(input)
"json을 수동으로 생성"한다는 말의 의미는 확실하지 않지만 gson(http://code.google.com/p/google-gson/),과 같은 것을 사용하면 해시맵, 어레이, 문자열 등을 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를 쿼리하는 방법에 대한 튜토리얼이기도 하다 :-)
공용 언어 API에서 DiscoveryUtils 클래스를 사용하십시오.
EscapeUtils.escapeJavaScript("Your JSON string");
Moshi의 JsonWriter 클래스를 생각해 보십시오.멋진 API를 가지고 있고 복사를 최소한으로 줄이고, 모든 것을 파일, 아웃풋스트림 등으로 잘 스트리밍할 수 있다.
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.따옴표 당신의 json 끈은 탈출해야 한다.)는 잘 작동하는 것 같다.
Apache commons-text에는 이제 StringEscapeUtils.escapeJson(스트링)이 있다.
\uXXX 구문을 사용하면 이 문제를 해결할 수 있으며, XXXXX와 기호의 이름을 함께 검색하면 다음과 같은 경우:utf-16 이중 인용문을 찾을 수 있다.
실제 시행을 보여주는 이곳의 방법들은 모두 잘못된 것이다.
나는 자바코드가 없지만, 단지 기록상으로는 이 C#코드를 쉽게 변환할 수 있다.
단일 프로젝트 제공 @ 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를 사용하는 것이라고 생각한다.havax.json을 사용하십시오.JsonBuilderFactory를 사용하여 json 객체를 생성한 다음 javax.json을 사용하여 객체를 작성하십시오.JsonWriterFactory.아주 멋진 빌더/라이터 조합.
참조URL: https://stackoverflow.com/questions/3020094/how-should-i-escape-strings-in-json
'programing' 카테고리의 다른 글
문자 배열이 비어 있는지 확인하는 가장 좋은 방법 (0) | 2022.04.24 |
---|---|
vue 관련 문제 다시 한 번 발생: vue를 2.5에서 2.6.8로 업데이트하고 [Vue warn]:구성 요소를 마운트하지 못함: 템플릿 또는 렌더 함수가 정의되지 않음 (0) | 2022.04.24 |
Vue.js 계산 함수에서 다중 차원 배열 필터링 (0) | 2022.04.23 |
왜 정적으로 연결된 glibc가 낙담하는가? (0) | 2022.04.23 |
값 쌍의 Java 컬렉션?(튜플이요?) (0) | 2022.04.23 |