servlet请求参数字符编码

Dón*_*nal 11 java servlets character-encoding

我有一个Java servlet,它通过HTTP GET请求从上游系统接收数据.该请求包括名为"text"的参数.如果上游系统将此参数设置为:

TEST3 please ignore:
Run Code Online (Sandbox Code Playgroud)

它出现在上游系统的日志中:

00 54 00 45 00 53 00 54 00 33 00 20 00 70 00 6c   //TEST3 pl
00 65 00 61 00 73 00 65 00 20 00 69 00 67 00 6e   //ease ign
00 6f 00 72 00 65 00 3a                           //ore:   
Run Code Online (Sandbox Code Playgroud)

(//注释实际上不会出现在日志中)

在我的servlet中,我用以下内容读取了这个参数

String text = request.getParameter("text");
Run Code Online (Sandbox Code Playgroud)

如果我将值打印text到控制台,它显示为:

T E S T 3  p l e a s e  i g n o r e :
Run Code Online (Sandbox Code Playgroud)

如果我检查text调试器中的值,它显示为:

\u000T\u000E\u000S\u000T\u0003\u0000 \u000p\u000l\u000e\u000a\u000s\u000e\u0000 
\u000i\u000g\u000n\u000o\u000r\u000e\u000:
Run Code Online (Sandbox Code Playgroud)

所以似乎字符编码存在问题.上游系统应该使用UTF-16.我的猜测是servlet假定为UTF-8,因此读取的字符数应该是它的两倍.对于消息"TEST3,请忽略:"每个字符的第一个字节是00.这被解释为servlet读取时的空间,这解释了当servlet记录消息时每个字符之前出现的空间.

显然,当我阅读text请求参数时,我的目标只是获取消息"TEST3,请忽略:" .我的猜测是我可以通过指定请求参数的字符编码来实现这一点,但我不知道如何做到这一点.

小智 9

像这样使用

new String(req.getParameter("<my request value>").getBytes("ISO-8859-1"),"UTF-8")
Run Code Online (Sandbox Code Playgroud)

  • [隐藏编辑]我深入挖掘并发现调用`request.setCharacterEncoding("UTF-8");`是我唯一需要的东西(它更有意义) (5认同)

epo*_*och 1

看起来它是用UTF-16LE(Little Endian)编码进行编码的,这是一个成功打印字符串的类:

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;

public class Test {
    public static void main(String[] args) throws UnsupportedEncodingException {
            String hex = "00 54 00 45 00 53 00 54 00 33 00 20 00 70 00 6c"  +
                            "00 65 00 61 00 73 00 65 00 20 00 69 00 67 00 6e" +
                           "00 6f 00 72 00 65 00 3a"; // + " 00";
            System.out.println(new String(new BigInteger(hex.replaceAll(" ", ""), 16).toByteArray(), "UTF-16LE"));
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

TEST3 please ignore?
Run Code Online (Sandbox Code Playgroud)

输入中添加两个零的输出

TEST3 please ignore:
Run Code Online (Sandbox Code Playgroud)

更新

要让它与您一起工作,Servlet您可以尝试:

  String value = request.getParameter("text");
  try {
      value = new String(value.getBytes(), "UTF-16LE");
  } catch(java.io.UnsupportedEncodingException ex) {}
Run Code Online (Sandbox Code Playgroud)

更新

请参阅以下链接,它验证生成的十六进制实际上是UTF-16LE