如何用u'反序列化JSON? Java中的unicode标记?

时间:2017-11-29 09:39:52

标签: java json amazon-web-services serialization unicode

我有这个HTTP响应主体来反序列化:

String response = "result : {'url': u'https://somedomain/', 'fields': {'policy': 
u'eyJjb25kaXRpb25zIjogW1siYfgfhudGVudC1sZjMyWiJ9', 'AWSAccessKeyId': 
u'ASIccccccNA', 'x-amz-security-token': 'FQofgF', 'key': u'bbb.file', 
'signature': u'rm9gdflkjfs='}}"

我正在使用jackson.core(2.9.0)java包和lib(也尝试过GSON)并收到此错误:

Exception in thread "main" com.fasterxml.jackson.core.JsonParseException: 
Unrecognized token 'u': was expecting ('true', 'false' or 'null')

反序列化代码:

MyResponse deserializedResponse = new ObjectMapper()
  .configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
  .configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
  .configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true)
                        .readValue(response, MyResponse.class);

我考虑过这样的事情,但感觉应该有更好/更安全的方式:

String sanitizedResponse = response.replaceAll("u'", "'"); 

-

使用Java 1.8。

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:2)

由于python导致了这个问题,我认为最好的解决方案是让python修复它;-)。幸运的是,使用jython,您可以坚持使用纯Java实现。

首先,您需要在pom.xml中添加jython独立依赖项:

<dependencies>
    <dependency>
        <groupId>org.python</groupId>
        <artifactId>jython-standalone</artifactId>
        <version>2.7.1</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.5</version>
    </dependency>
</dependencies>

(正如你所看到的,我也使用了apache commons io作为我的例子,所以我也添加了它)

我将您的(无效)json字符串放入文本文件“c:/temp/json.txt”,其中包含以下内容:

{'url': u'https://somedomain/', 'fields': {'policy': 
u'eyJjb25kaXRpb25zIjogW1siYfgfhudGVudC1sZjMyWiJ9', 'AWSAccessKeyId': 
u'ASIccccccNA', 'x-amz-security-token': 'FQofgF', 'key': u'bbb.file', 
'signature': u'rm9gdflkjfs='}}

现在这里是读取json文件的代码,设置Python解释器并移交json来清理它:

String content = FileUtils.readFileToString(new File("c:/temp/json.txt"), "UTF-8");

PythonInterpreter pi = new PythonInterpreter();
pi.exec("import json");
pi.exec("jsondata = " + content);
pi.exec("jsonCleaned = json.dumps(jsondata)");
PyObject jsonCleaned = (PyObject) pi.get("jsonCleaned");
System.out.println(jsonCleaned.asString());
pi.close();

输出结果为:

{"url": "https://somedomain/", "fields": {"signature": "rm9gdflkjfs=", "AWSAccessKeyId": "ASIccccccNA", "x-amz-security-token": "FQofgF", "key": "bbb.file", "policy": "eyJjb25kaXRpb25zIjogW1siYfgfhudGVudC1sZjMyWiJ9"}}

当你把它放在json验证器(https://jsonlint.com/)中时,你可以看到它现在是一个有效的json。 我无法判断性能是否足以满足您的使用情况,因此您必须对其进行测试。

<强>注: 在Eclipse中,似乎有一个jython版本的bug。它显示以下错误:

console: Failed to install '': java.nio.charset.UnsupportedCharsetException: cp0.

虽然它可以工作但你可以通过在运行配置中添加以下VM-Argument来消除它:

-Dpython.console.encoding=UTF-8

备注2:为了完整起见并完全回答这个问题 - 以下是如何反序列化已清理的JSON:

将GSON依赖项添加到您的pom.xml:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.2</version>
</dependency>

创建代表类:

信息类

public class Info {
    private String url;
    private Fields fields;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Fields getFields() {
        return fields;
    }

    public void setFields(Fields fields) {
        this.fields = fields;
    }

}

字段类

import com.google.gson.annotations.SerializedName;

public class Fields {
    private String signature;
    private String AWSAccessKeyId;

    @SerializedName("x-amz-security-token")
    private String x_amz_security_token;

    private String key;
    private String policy;

    public String getSignature() {
        return signature;
    }

    public void setSignature(String signature) {
        this.signature = signature;
    }

    public String getAWSAccessKeyId() {
        return AWSAccessKeyId;
    }

    public void setAWSAccessKeyId(String aWSAccessKeyId) {
        AWSAccessKeyId = aWSAccessKeyId;
    }

    public String getX_amz_security_token() {
        return x_amz_security_token;
    }

    public void setX_amz_security_token(String x_amz_security_token) {
        this.x_amz_security_token = x_amz_security_token;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getPolicy() {
        return policy;
    }

    public void setPolicy(String policy) {
        this.policy = policy;
    }

}

最后在获得清理的JSON后添加以下代码:

Gson gson = new Gson();
Info info = gson.fromJson(jsonCleaned.asString(), Info.class);

答案 1 :(得分:0)

您需要使用以下正则表达式从字边界的开头替换u'以替换为'

String regexPattern = "(\\bu')";