输入字符串是编码的,需要原始字符串 - Java代码

时间:2015-10-20 07:03:54

标签: java utf-8 character-encoding iso-8859-1

我有一个REST Web服务,它以JSON的形式获取输入(作为多部分表单数据)。

@POST
@Consumes ({"application/ds-json",MediaType.APPLICATION_FORM_URLENCODED,MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML,"text/html",MediaType.MULTIPART_FORM_DATA})
@Produces({ text_html, "application/ds-json" })
@Path("/abc")
public Response abc(@Context HttpServletRequest req, @Context HttpServletResponse response){
           .
           .
           .
           .
     String strInput = inputJSON.getString("data");
           .
           .
           .
}

我发送的输入JSON是{"data":"Sécurité"},而我得到的字符串strInput的值是Sécurité

我尝试java.net.URLDecoder.decode(strInput, "iso-8859-1")将其解码回原始角色,但失败了。

我还尝试String strInput = new String((inputJSON.getString("data")).getBytes(), "iso-8859-1");预期传入的字符将根据要求存储在变量strInput中,但失败了。

我觉得这里完全迷失了。有人可以帮忙吗?

编辑:

更清楚的是,下面是我将JSON发送到此服务的确切方式(仅用于测试目的):

  1. 我创建了一个可以向网络服务发送POST请求的HTML页面
  2. 
    
    <!DOCTYPE html>
    <html>
    
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Insert title here</title>
    </head>
    
    <body>
    
      <form action="http://localhost:8080/xxxx/abc" method="POST" enctype="multipart/form-data">
    
        JSON:
        <input type="text" name="data">
        <input type="submit" name="submit">
      </form>
    </body>
    
    </html>
    &#13;
    &#13;
    &#13;

    1. 在页面中,我输入的文字为Sécurité

3 个答案:

答案 0 :(得分:1)

所有Java字符都使用UTF-16存储在内存中。问题来自传输的字节。你写了

  

我发送的是{"data":"Sécurité"}

它只是一种表示,它不提供有关用于传输文本的字节表示的信息。如果使用的表示不是响应的一部分,则接收方无法发明它。如果编码丢失,发件人和消费者都必须依赖相同的约定。例如,某些协议具有默认值,但这意味着发送方和接收方都遵守标准默认值,并且它们也必须与规范同步(默认编码随时间变化)。

根据您的特定问题,当Java请求处理器收到发送的字节时,它已使用Charset将其转换为Java char。此转换中仅丢失了不支持的字节。

可能的解决方案:

  1. 使发件人始终指定使用编码
  2. 添加一个请求过滤器,根据某些请求元数据猜测默认编码(即User-Agent
  3. 停止使用IE(据我所知,IE8在编码方面做错了,尤其是XHR)
  4. 注意:must-read文章:The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

答案 1 :(得分:0)

尝试添加Consumes参数:

  

+ “;字符集= UTF-8”

例子:

  

MediaType.APPLICATION_JSON +“; charset = utf-8”

我使用它,但输出和工作正常。

答案 2 :(得分:0)

谢谢大家,我设法解决了这个问题,@ kayaman的评论帮助我到达了这里

  

您所看到的是UTF-8数据解码为ISO-8859-1。 - 卡亚曼

我只是根据strInput编码将输入字符串ISO-8859-1转换为字节,并再次根据UTF-8编码创建新字符串。这对我来说很有意义。

byte[] inputBytes = strInput.getBytes("iso-8859-1");
strInput = new String(inputBytes, "UTF-8"); 

之前我提取输入字符串的字节为byte[] inputBytes = strInput.getBytes();,默认情况下返回UTF-8个解码字节,这个字节比我预期的更多(我提到@Kayaman):

  

@Kayaman是的,你非常正确,我在一个单独的测试类中进行了测试。但在我目前的情况下(Web服务),我作为输入获得的数据似乎以某种方式被破坏。我尝试打印输入和预期字符串的字节:byte [] s = strInput.getBytes(“UTF-8”); byte [] s1 =“Sécurité”.getBytes(“UTF-8”);结果:s = [83,-61,-125,-62,-87,99,117,114,105,116,-61,-125,-62,-87] s1 = [83,-61, -87,99,117,114,105,116,-61,-87]这些都应该是相同的,但我得到额外的字节{-125,-62} - Ankan Priya

但是,由于字符串是ISO-8859-1编码形式,我需要使用相同的解码方案获取字节并且它有效(参见上面的代码片段)