3

我面临类似于How to Force a jar to uses(or the jvm running in) utf-8 而不是系统的默认编码的问题。有一个服务器和客户端 java 应用程序。如果我从 Eclipse 运行它们,那么一切正常。如果我制作罐子,那么它们之间交换的字符串就会被破坏(编码错误)。

如果我使用-Dfile.enconding=utf-8JVM 参数运行两个图像,那么它可以正常工作。但是由于上面的链接说它不是最好的解决方案(至少需要从 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;
}

这就是这条线的样子

{"response":[{"uid":123456,"first_name":"Имя","last_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 将字符串发送到服务器

我尝试在 Eclipse 中调试客户端和从 jar 运行的服务器,然后 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: 用户名由 firstName 和 lastName 生成

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

2 回答 2

3

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

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

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

如果你得到了错误编码的字符串,你可以检查这个代码:

String rightEncoded = new String(wrongEncodedString.getBytes("Cp1252"), "utf-8");
于 2012-11-28T06:34:20.967 回答
1

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

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

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

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

之后,使用由 ChannelBuffers.wrappedBuffer() 和 NettyUtils.writeStrings() 生成的 Netty 的 ChannelBuffer 将字符串发送到服务器

您还提到这里不能附上整个代码,这是可以理解的;因此,我建议您查看您发送这些字符串的确切方式,以及您在这样做时是否明确指定了编码。

根据 OP 的更新进行编辑:好吧,我很抱歉我不熟悉 Netty,但我还是会在这里试一试。NettyUtils.writeStrings()或任何调用它的代码不接受字符编码吗?NettyUtils我在网上找不到任何 JavaDoc 。在这里和我一起工作。:-)

于 2012-11-28T06:29:49.507 回答