2012-06-19 105 views
10

我有一個Java servlet通過HTTP GET請求從上游系統接收數據。該請求包含一個名爲「text」的參數。如果上游系統這個參數設置爲:servlet請求參數字符編碼

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"); 

如果我打印的值3210到控制檯,它顯示爲:

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請忽略:」。我的猜測是,我可以通過指定請求參數的字符編碼來實現這一點,但我不知道如何做到這一點。

+1

GET參數必須是ASCII或URL編碼,你不能在那裏使用一種特殊的字符集。 –

+0

什麼是您的Web容器?什麼是你的HTML文件字符集? –

+0

[This](http://stackoverflow.com/questions/3278900/httpservletrequest-setcharacterencoding-seems-to-do-nothing)可能會有所幫助。 –

回答

1

看起來像是用UTF-16LE(小端)編碼進行編碼,這裏是成功打印你的字符串類:

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: 

UPDATE

爲了得到這個與你Servlet你可以嘗試的工作:

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

UPDATE

看到下面的link,它驗證生成的hex其實UTF-16LE

+0

最後一個字符應該是':'而不是'?'。 –

+0

@Don,這是因爲'3a'中缺少最後一個'00',如果再添​​加它,它會正確解碼,或者該字符串的編碼器被搞亂了,或者您可能忘記複製最後兩個零的 – epoch

+0

'是正確的,可能是我的部分複製粘貼錯誤。順便說一句,你確定這不是高端的?感謝您的幫助 –

1

嘗試使用此過濾器

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() { 
    } 

這應該設置編碼適合整個應用程序

8

使用這樣

new String(req.getParameter("<my request value>").getBytes("ISO-8859-1"),"UTF-8") 
+1

這解決了我的問題,但我不' t完全理解爲什麼...... :( – pataluc

+5

[隱藏編輯]我深入瞭解一點,發現調用'request.setCharacterEncoding(「UTF-8」);'是我唯一需要的東西(並且它更有意義) – pataluc