从JAR运行时编码错误,从Eclipse运行完美

时间:2012-11-28 06:13:10

标签: java utf-8 character-encoding gson netty

我遇到类似How to Force a jar to uses(or the jvm runs in) utf-8 instead of the system's default encoding的问题。有一个服务器和客户端java应用程序。如果我从Eclipse运行它们,那么一切正常。如果我制作jar,那么在它们之间交换的字符串会被破坏(编码错误)。

如果我使用-Dfile.enconding=utf-8 JVM参数运行两个图像,那么它可以正常工作。但由于上面的链接说它不是最好的解决方案(至少需要从bat运行jar)我试图通过为BufferedReader指定编码来解决问题。但它失败了,使用jar很难调试。

此代码用于发送请求并以JSON格式获取一行作为回复。证明该回复具有UTF-8编码。

public static String sendRequest (String request) {
    if (request == null) return null;

    try {
        URL url = new URL(request);
        HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
        BufferedReader inReader = new BufferedReader(new InputStreamReader(con.getInputStream(), Charset.forName("UTF-8")));
        String line = inReader.readLine();
        inReader.close();
        return line;
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }

    return null;
}

这就是线条的样子

  

{ “响应”:[{ “UID”:123456 “如first_name”: “Имя”, “姓氏”: “Фамилия”}]}

然后我准备在Gson.fromJson()

中使用它
int beginIndex = reply.indexOf('[');
int endIndex = reply.indexOf(']');
reply = reply.substring(beginIndex + 1, endIndex);
SocialPerson vkPerson = new Gson().fromJson(reply, SocialPerson.class);

之后,使用通过ChannelBuffers.wrappedBuffer()和NettyUtils.writeStrings()生成的Netty的ChannelBuffer将String发送到服务器

我尝试调试Eclipse中的Client和从jar运行的Server,然后Eclipse显示,直到字符串真正被赋予框架才能提供它看起来有效。

然后我调试服务器和客户端从Jar运行,一旦收到字符串,它已经看起来像垃圾。

在服务器端

    private final String username;
    private final String password;

    public SimpleCredentials(ChannelBuffer buffer)
    {
        this.username = NettyUtils.readString(buffer);
        this.password = NettyUtils.readString(buffer);
    }

您认为问题在哪里?抱歉,我无法在此处发布所有代码。

UPD: username是从firstName和lastName

生成的
ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(opCode, NettyUtils.writeStrings(userId, userName, refKey));

2 个答案:

答案 0 :(得分:2)

当您阅读网络流时,如果自动方式失败,您需要手动重新编码字符串。您正在使用的库可能忽略了内容编码,或者可能在HTTP响应中丢失了。

代码中的某个地方将是一个字节数组,您可以在String构造函数中进行转换:

String xxx = new String(bytes, "utf-8");

如果您使用错误的编码获取String,则可以检查以下代码:

String rightEncoded = new String(wrongEncodedString.getBytes("Cp1252"), "utf-8");

答案 1 :(得分:1)

您不应该使用file.encoding系统属性。

避免此类编码问题的最佳方法是永远不要假设任何有关默认平台编码的内容,并在构造读者或将字节转换为字符串时始终提供编码,反之亦然。

关于处理编码,你的sendRequest方法似乎没问题:它从输入中读取字符,明确提到它希望流以UTF-8编码。

但是,我们无法看到客户端/服务器序列的另一端。引用你:

  

之后,使用Netty将String发送到服务器   ChannelBuffer使用ChannelBuffers.wrappedBuffer()生成   NettyUtils.writeStrings()

你还提到你不能在这里附上整个代码,这是可以理解的;因此,我建议你研究一下你是如何准确地发送这些字符串的,以及你是否明确指定了编码。

根据OP的更新,

编辑:嗯,我很抱歉我不熟悉Netty,但我仍然会在这里拍摄。 NettyUtils.writeStrings()或任何调用它的代码都不接受字符编码吗?我无法在线找到任何NettyUtils的JavaDoc。在这里与我合作。 : - )