繁体   English   中英

解码Java中的拆分16位字符

[英]Decoding split 16-bit character in Java

在我的应用程序中,我收到URL-UTF8编码的字符串,由发送客户端分割。 拆分后,每个消息部分都包含一些标头信息,这些标头信息将用于重建消息。

使用英文字符,这非常简单

String content = new String(request.getParameter("content").getBytes("UTF-8"));

我将其与标题信息一起存储在每个接收到的部分的缓冲区中。 收到所有部分后,我只需根据标题信息将每个单独的部分连接起来,即可重新组成消息。

对于使用16位编码的语言,有时可能无法正常工作。 如果拆分不会在单个字符中间发生,则一切正常。

例如,这是客户端发送的由三个希伯来字符组成的字符串:

%D7%93%D7%99%D7%91

如果最终拆分如下:{%D7%93%D7%99} {%D7%91},那么重建就不是问题。

但是有时客户会在中间将其拆分(例如:{%D7%93%D7} {%99%D7%91})

发生这种情况时,重建后我会在边界点得到两个字符,而不是单个正确的希伯来字符。

我认为无法正确保留单字节信息与传递字符串有关,因此我尝试将字节数组从request.getParameter(“ content”)。getBytes(“ UTF-8”)传递至缓冲区,而没有包装在将字节数组连接在一起的字符串。 在缓冲区中,在将最终数组转换为字符串之前,我加入了所有这些数组。

即使这样做,我仍然似乎“丢失”了单个字节保存的信息。 我猜这是因为getBytes(“ UTF-8”)方法无法正确解析单个字节,因为它们不是有效字符。 那正确吗?

有什么办法可以解决这个问题并保留这些尾部/头部字节?

您的客户是这里的问题。 显然,它将文本数据视为字节数组以进行拆分,然后将无效片段作为文本发送(HTTP请求参数本质上是文本)。 那时,您已经迷路了。

您要么更改客户端以将数据拆分为文本(即沿字符边界),要么更改协议以将片段作为二进制数据发送,即不作为参数而是作为请求正文发送,以通过ServletRequest.getInputStream()进行检索。 ServletRequest.getInputStream() -然后,在解码之前将数据串联起来应该可以。

(注意:以上假设您确实是在编写Servlet代码,这是我从request.getParameter()方法推断出的;但是即使巧合,也适用相同的原理:在将任何数据转换为byte [之前,将数据拆分为String [ ]发生在客户端,或确保在转换为String之前将服务器上的字节数组连接起来。)

您必须首先收集所有字节,然后立即将它们全部转换为字符串。

遵循方案是可以解决的,但在您的情况下应该可以使用,

  • 将服务器/页面设置为Latin-1模式。 如果这是GET,则客户端无法设置编码。 您必须在服务器端执行此操作。 例如,您需要在Tomcat的连接器中添加URIEncoding="iso-8859-1"

  • 获取内容为Latin1。 此时将是错误的值,但请放心,

    字符串内容= request.getParameter(“ content”);

  • 将字符串连接为Latin-1。

    数据=数据+内容;

  • 当您了解所有内容后,需要像这样将字符串重新编码为UTF-8,

    字符串值=新的String(data.getBytes(“ iso-8859-1”),“ utf-8”);

value应包含正确的字符。

您永远不需要将字符串转换为字节然后转换为String java,这是完全没有意义的。 一旦将一系列字节解码为String,它就是Java String编码(我认为是UTF-16E)。

您遇到的问题是应用服务器正在对传入的HTTP请求的编码进行假设,通常是平台编码。 通过在其他调用getParameter()之前调用ServletRequest.setCharacterEncoding(String) ,可以为应用程序服务器提供有关所需编码的提示。

浏览器假定表单字段应使用与该页面一起使用的相同编码提交回服务器。 这是一条通用规则,因为HTTP规范无法指定传入请求的编码,而只能指定响应。

如果您将其定义为web.xml中的每个第一个过滤器,那么大多数编码问题都将消失,Spring会为您提供一个好用的CharacterEncodingFilter过滤器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM