我有一个Java servlet,它通过HTTP GET请求从上游系统接收数据。该请求包括名为“text”的参数。如果上游系统将此参数设置为:
TEST3 please ignore:
它出现在上游系统的日志中:
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:
(//注释实际上不会出现在日志中)
在我的servlet中,我用以下内容读取了这个参数:
String text = request.getParameter("text");
如果我将text
的值打印到控制台,则显示为:
T E S T 3 p l e a s e i g n o r e :
如果我在调试器中检查text
的值,则显示为:
\u000T\u000E\u000S\u000T\u0003\u0000 \u000p\u000l\u000e\u000a\u000s\u000e\u0000
\u000i\u000g\u000n\u000o\u000r\u000e\u000:
所以似乎字符编码存在问题。上游系统应该使用UTF-16。我的猜测是servlet假定为UTF-8,因此读取的字符数应该是它的两倍。对于消息“TEST3,请忽略:”每个字符的第一个字节是00
。这被解释为servlet读取时的空间,它解释了当servlet记录消息时每个字符之前出现的空间。
显然,当我阅读text
请求参数时,我的目标只是获取消息“TEST3,请忽略:”。我的猜测是我可以通过指定请求参数的字符编码来实现这一点,但我不知道如何做到这一点。
答案 0 :(得分:9)
像这样使用
new String(req.getParameter("<my request value>").getBytes("ISO-8859-1"),"UTF-8")
答案 1 :(得分:2)
尝试使用过滤器
public class CustomCharacterEncodingFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
public void destroy() {
}
这应该为整个应用程序设置编码权
答案 2 :(得分: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"));
}
}
输出:
TEST3 please ignore?
输入两个零添加到输入
TEST3 please ignore:
<强>更新强>
要使用Servlet
,您可以尝试:
String value = request.getParameter("text");
try {
value = new String(value.getBytes(), "UTF-16LE");
} catch(java.io.UnsupportedEncodingException ex) {}
<强>更新强>
请参阅以下link,它会验证生成的十六进制实际上是UTF-16LE