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

Java 从JAR运行时编码错误,从Eclipse运行时编码是完美的,java,utf-8,character-encoding,gson,netty,Java,Utf 8,Character Encoding,Gson,Netty,我面临着类似的问题。有一个服务器和客户端java应用程序。如果我从Eclipse运行这两个程序,那么一切都正常。如果我制作JAR,那么它们之间交换的字符串就会被破坏(编码错误) 如果我使用JVM参数-Dfile.enconding=utf-8运行这两个映像,那么它可以正常工作。但是因为上面的链接说这不是最好的解决方案(至少需要从bat运行jar),所以我尝试通过指定BufferedReader的编码来解决这个问题。但是它失败了,而且使用jar很难调试 此代码用于发送请求并获取JSON格式的一行作

我面临着类似的问题。有一个服务器和客户端java应用程序。如果我从Eclipse运行这两个程序,那么一切都正常。如果我制作JAR,那么它们之间交换的字符串就会被破坏(编码错误)

如果我使用JVM参数
-Dfile.enconding=utf-8运行这两个映像,那么它可以正常工作。但是因为上面的链接说这不是最好的解决方案(至少需要从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,“名字”:“аааа”,“姓氏”:“Фаааааааааа

然后我准备在Gson.fromJson()中使用它

之后,将使用由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));

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

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

您的
sendRequest
方法在处理编码方面似乎还可以:它从输入中读取字符,明确指出它希望流以UTF-8编码

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

之后,字符串将使用Netty的 使用ChannelBuffers.wrappedBuffer()和 NettyUtils.writeStrings()

您还提到您不能在这里附加整个代码,这是可以理解的;因此,我建议您研究如何准确地发送这些字符串,以及在发送时是否显式指定编码


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

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

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

String xxx = new String(bytes, "utf-8");
如果获取的字符串编码错误,可以检查以下代码:

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

你能给我们看一下调用NettyUtils.writeStrings()的代码吗?@Isaac,我已经把它放在了更新中。我已经从框架中得到了字符串。我应该从字符串中获取字节并用指定的编码构造一个新字符串吗?顺便说一句,否决票不是我的:)我能知道我得到的字符串的编码吗?我不确定它是CP1252在一个忍者谷歌上我发现这个编码可能是默认编码。如果这不起作用,试试其他类似我们的ascii码。这听起来是一个值得研究的问题,因为以编程方式安装系统属性会影响同一JVM中运行的所有代码,这是危险的,尤其是在讨论这样一个低级系统属性时。我似乎不是一个讨厌的东西,而是一个来自框架作者的类,所以我可能也需要联系他我同意。我查看了
NettyUtils
的代码,它最终调用
StringEncoderWrapper
来实际执行序列化。我确信它(或一些最终被它调用的代码)最终会对默认平台编码进行假设。
String rightEncoded = new String(wrongEncodedString.getBytes("Cp1252"), "utf-8");