[安卓筆記]android用戶端向tomcat伺服器發送請求中文亂碼問題解決

來源:互聯網
上載者:User

android用戶端請求服務端的url地址中含有中文時將會產生中文亂碼問題。 產生亂碼的原因有主要以下幾個方面: ------------------------------------------------------------------------------------------------ 1.當以get方式請求服務端的資源時,沒有對url中的中文進行編碼。 2.忽略了tomcat預設的編碼格式(iso8859-1)。 3.servlet沒有對request和response設定正確的編碼格式。 4.servlet沒有處理get請求方式中的亂碼問題。 ------------------------------------------------------------------------------------------------- 解決方案: 步驟: 1、用戶端對url中中文參數進行編碼(使用URLEncoder類)。 這裡採用的是最原始的java.net包中提供的URL,HTTPURLConnection類。 請求資料全部封裝到map中。 get請求:

/**     * 以get方式向服務端發送請求,並將服務端的響應結果以字串方式返回。如果沒有響應內容則返回Null 字元串     *      * @param url 請求的url地址     * @param params 請求參數     * @param charset url編碼採用的碼錶     * @return     */    public static String getDataByGet(String url,Map params,String charset)    {        if(url == null)        {            return "";        }        url = url.trim();        URL targetUrl = null;        try        {            if(params == null)            {                targetUrl = new URL(url);            }            else            {                StringBuilder sb = new StringBuilder(url+"?");                for(Map.Entry me : params.entrySet())                {//                    解決請求參數中含有中文導致亂碼問題                    sb.append(me.getKey()).append("=").append(URLEncoder.encode(me.getValue(),charset)).append("&");                }                sb.deleteCharAt(sb.length()-1);                targetUrl = new URL(sb.toString());            }            Log.i(TAG,"get:url----->"+targetUrl.toString());//列印log            HttpURLConnection conn = (HttpURLConnection) targetUrl.openConnection();            conn.setConnectTimeout(3000);            conn.setRequestMethod("GET");            conn.setDoInput(true);            int responseCode = conn.getResponseCode();            if(responseCode == HttpURLConnection.HTTP_OK)            {                return stream2String(conn.getInputStream(),charset);            }        } catch (Exception e)        {            Log.i(TAG,e.getMessage());        }        return "";    }
post請求:
/**     *  以post方式向服務端發送請求,並將服務端的響應結果以字串方式返回。如果沒有響應內容則返回Null 字元串     * @param url 請求的url地址     * @param params 請求參數     * @param charset url編碼採用的碼錶     * @return     */    public static String getDataByPost(String url,Map params,String charset)    {        if(url == null)        {            return "";        }        url = url.trim();        URL targetUrl = null;        OutputStream out = null;        try        {            targetUrl = new URL(url);            HttpURLConnection conn = (HttpURLConnection) targetUrl.openConnection();            conn.setConnectTimeout(3000);            conn.setRequestMethod("POST");            conn.setDoInput(true);            conn.setDoOutput(true);                        StringBuilder sb = new StringBuilder();            if(params!=null && !params.isEmpty())            {                for(Map.Entry me : params.entrySet())                {//                    對請求資料中的中文進行編碼                    sb.append(me.getKey()).append("=").append(URLEncoder.encode(me.getValue(),charset)).append("&");//                    sb.append(me.getKey()).append("=").append(me.getValue()).append("&");//測試發現也可用                }                sb.deleteCharAt(sb.length()-1);            }            byte[] data = sb.toString().getBytes();            conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");            conn.setRequestProperty("Content-Length", String.valueOf(data.length));            out = conn.getOutputStream();            out.write(data);                        Log.i(TAG,"post:url----->"+targetUrl.toString());//列印log                        int responseCode = conn.getResponseCode();            if(responseCode == HttpURLConnection.HTTP_OK)            {                return stream2String(conn.getInputStream(),charset);            }        } catch (Exception e)        {            Log.i(TAG,e.getMessage());        }        return "";    }
stream2String方法(將流對象中的資料轉化為字串):
/**     * 將輸入資料流對象中的資料輸出到字串中返回     * @param in     * @return     * @throws IOException     */    private static String stream2String(InputStream in,String charset) throws IOException    {        if(in == null)            return "";        byte[] buffer = new byte[1024];        ByteArrayOutputStream bout = new ByteArrayOutputStream();        int len = 0;        while((len = in.read(buffer)) !=-1)        {            bout.write(buffer, 0, len);        }        String result = new String(bout.toByteArray(),charset);        in.close();        return result;    }
測試時,我們也確實發現對get請求中url中的中文進行了編碼:

2、服務端對request和response設定正確的編碼格式。 首先在servlet中加上這幾行代碼.
req.setCharacterEncoding("utf-8");resp.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=utf-8");
這還沒有完,以上僅處理了post請求的亂碼問題,當使用者以get方式請求時仍然有亂碼。所以你還需要加上這行代碼:
if(req.getMethod().equalsIgnoreCase("GET")){    name = new String(name.getBytes("iso8859-1"),"utf-8");}
之所以要判斷一下請求的方式是是否為get,是因為如果請求方式為post的話,又會變成亂碼了,當然,如果你在servlet中對doPost和doGet分別進行亂碼處理,那就不用判斷了。只是大多數人更喜歡這樣寫:
public class xxxServlet extends HttpServlet{    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp)            throws ServletException, IOException     {        //TODO        }@Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp)            throws ServletException, IOException    {        this.doGet(req, resp);    }  }
此時一定要在doget方法中加上判斷. 當然你還有另一種選擇,那就是過濾器,配置如下所示的過濾器即可處理上述的亂碼。 編碼格式在web.xml中手動設定,避免寫入程式碼。(context-param中配置)
package cn.chd.edu.filter;import java.io.IOException;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class CharacterEncodingFilter implements Filter{    private static String charset = "iso8859-1";//預設編碼    public void doFilter(ServletRequest request, ServletResponse response,            FilterChain chain) throws IOException, ServletException    {        System.out.println("filter running...");                final HttpServletRequest req = (HttpServletRequest) request;        HttpServletResponse resp = (HttpServletResponse) response;        req.setCharacterEncoding(charset);        resp.setCharacterEncoding(charset);        resp.setContentType("text/html;charset="+charset);                chain.doFilter((ServletRequest) Proxy.newProxyInstance(CharacterEncodingFilter.class.getClassLoader(), req.getClass().getInterfaces(),new InvocationHandler()        {            public Object invoke(Object proxy, Method method, Object[] args)                    throws Throwable            {              if(!method.getName().equals("getParameter"))//攔截getParameter方法                {                    return method.invoke(req, args);                }                if(!req.getMethod().equalsIgnoreCase("get"))//攔截get請求                {                    return method.invoke(req, args);                }                String value = (String) method.invoke(req, args);                if(value == null)                    return null;                return new String(value.getBytes("iso8859-1"),charset);            }        }),resp);    }    public void init(FilterConfig filterConfig) throws ServletException    {        String temp = filterConfig.getServletContext().getInitParameter("charset");        if(temp != null)            charset = temp;    }    public void destroy()    {            }}
對過濾器不熟悉的參考這篇文章:filter詳解



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.