如何防止ObjectMapper转换转义的unicode? [英] How to prevent ObjectMapper from converting escaped unicode?

查看:186
本文介绍了如何防止ObjectMapper转换转义的unicode?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Java中使用Jackson 2.4进行一些JSON任务.我使用Apache HttpGet调用远程服务器,将Jackson的结果反序列化为POJO,操纵这些结果,然后使用Jackson的序列化它们,以使用HttpPost推送回远程服务器.

I'm using Jackson 2.4 in Java to do some JSON legwork. I make a call to a remote server with Apache HttpGet, deserialize the results with Jackson into a POJO, manipulate those results, and then serialize them with Jackson to push back to a remote server with HttpPost.

我发现的问题是,杰克逊正在将Unicode文字转换为Unicode字符,由于两端都有编码问题,我不需要这样做.例如,我可能在JSON中有此内容:

The issue I'm finding is that Jackson is translating unicode literals into unicode characters, which I need it not to do thanks to encoding issues on each end. For example, I might have this in the JSON:

"field1": "\u00a2"

但是杰克逊在反序列化时将"\ u00a2"转换为¢",这导致远程服务器出现问题.必须将其维护为转义的unicode.如果我使用类似Apache EntityUtils(指定UTF-8)之类的东西,或者甚至从我的Web浏览器进行调用以获取数据,则转义的unicode会保留下来,因此我知道它是从服务器正确传入的.如果我让Jackson在响应中使用了来自实体的输入流,它将自动进行转换.

But Jackson is converting the "\u00a2" to "¢" when it's deserialized, which causes problems with the remote server. It has to be maintained as escaped unicode. If I use something like Apache EntityUtils (specifying UTF-8) or even make the call from my web browser to get the data, the escaped unicode is preserved, so I know that it's coming in properly from the server. If I have Jackson consume the input stream from the entity on the response, it does the conversion automatically.

我尝试使用显式设置为UTF-8的JsonGenerator进行写入,以写入HttpPost.它没有用,远程服务器仍然拒绝了它.我已经研究过ObjectMapper和JsonParser的配置选项,但是看不到任何可以覆盖此行为的东西.当然,转义非ASCII,但这不是我在这里要做的.也许我缺少明显的东西,但是如果不替换转义的unicode,我就无法让Jackson对该字符串进行反序列化.

I've tried writing with a JsonGenerator that is explicitly set to UTF-8 to write to the HttpPost. It didn't work, remote server still rejected it. I've dug through the configuration options for ObjectMapper and JsonParser, but I don't see anything that would override this behavior. Escaping non-ASCII, sure, but that's not what I need to do here. Maybe I'm missing something obvious, but I can't get Jackson to deserialize this string without replacing the escaped unicode.

好吧,我的错,唯一有问题的文字包含3或5个前导斜线,而不仅仅是一个.这有点麻烦,但是在反序列化期间,Java似乎是默认情况下将其解压缩的内容,即使从服务器返回的原始文本保留了它也是如此.仍然不确定如何让Java保存而不检查大量文本.

Well, my bad, the only literals having problems have 3 or 5 leading slashes, not just one. That's some screwiness, but Java seems to be what's unpacking it by default during the deserialization, even if the raw text that came back from the server preserves it. Still not sure how to get Java to preserve this without checking an insane amount of text.

推荐答案

您期望的超出Jackosn的范围.是Java,它在读取字符串时会转换它.出于同样的原因,如果您有一个值为 \ u00a2 的属性文件,并使用jdk API进行读取,则将获得转换后的值.根据文件的大小,您可以在将字符串传递给Json之前对字符串\进行两次转义,或者使用Deserializer(仅对于字符串)将字符串转义"回去,如下所示:

What you are expecting is outside scope of Jackosn. It's java that converts the String while reading it. For same reason, if you have a properties file with value \u00a2 and read it using jdk API, you will get converted value. Depending on the file size, either you can double escape char \ before passing the string to Json or "escape" the string back using your Deserializer (only for string) and something like below:

谢谢

package com.test.json;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import java.util.Map;

public class Jackson {

    static ObjectMapper _MAPPER = new ObjectMapper();

    public static void main(String[] args) throws Exception {
        String json = "{\"field1\": \"\\u00a2\",\"field2\": \"\\u00a2 this\",\"numberField\": 121212}";
        SimpleModule testModule
                = new SimpleModule("StOvFl", _MAPPER.version()).addDeserializer(String.class,
                        new UnEscapedSerializaer());

        _MAPPER.registerModule(testModule);

        Map m = _MAPPER.readValue(json, new TypeReference<Map<String, Object>>() {
        });
        System.out.println("m" + m);

    }
}

class UnEscapedSerializaer extends JsonDeserializer<String> {

    @Override
    public String deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        String s = jp.getValueAsString();
        return org.apache.commons.lang.StringEscapeUtils.StringEscapeUtils.escapeJava(s);

    }
}

这篇关于如何防止ObjectMapper转换转义的unicode?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆