[安卓笔记]android客户端向tomcat服务器发送请求中文乱码问题解决

来源:互联网 发布:淘宝 画伊旗舰店 moco 编辑:程序博客网 时间:2024/04/29 16:14
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请求:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
     * 以get方式向服务端发送请求,并将服务端的响应结果以字符串方式返回。如果没有响应内容则返回空字符串
     *
     * @param url 请求的url地址
     * @param params 请求参数
     * @param charset url编码采用的码表
     * @return
     */
    publicstatic String getDataByGet(String url,Map<string,string> 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<string,string> 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);
            intresponseCode = conn.getResponseCode();
            if(responseCode == HttpURLConnection.HTTP_OK)
            {
                returnstream2String(conn.getInputStream(),charset);
            }
        }catch (Exception e)
        {
            Log.i(TAG,e.getMessage());
        }
        return"";
    }</string,string></string,string>
post请求:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
     *  以post方式向服务端发送请求,并将服务端的响应结果以字符串方式返回。如果没有响应内容则返回空字符串
     * @param url 请求的url地址
     * @param params 请求参数
     * @param charset url编码采用的码表
     * @return
     */
    publicstatic String getDataByPost(String url,Map<string,string> 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<string,string> 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
             
            intresponseCode = conn.getResponseCode();
            if(responseCode == HttpURLConnection.HTTP_OK)
            {
                returnstream2String(conn.getInputStream(),charset);
            }
        }catch (Exception e)
        {
            Log.i(TAG,e.getMessage());
        }
        return"";
    }</string,string></string,string>
stream2String方法(将流对象中的数据转化为字符串):
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
     * 将输入流对象中的数据输出到字符串中返回
     * @param in
     * @return
     * @throws IOException
     */
    privatestatic String stream2String(InputStream in,String charset)throws IOException
    {
        if(in ==null)
            return"";
        byte[] buffer =new byte[1024];
        ByteArrayOutputStream bout =new ByteArrayOutputStream();
        intlen = 0;
        while((len = in.read(buffer)) !=-1)
        {
            bout.write(buffer,0, len);
        }
        String result =new String(bout.toByteArray(),charset);
        in.close();
        returnresult;
    }
测试时,我们也确实发现对get请求中url中的中文进行了编码:
\
2、服务端对request和response设置正确的编码格式。 首先在servlet中加上这几行代码.
?
1
2
3
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
这还没有完,以上仅处理了post请求的乱码问题,当用户以get方式请求时仍然有乱码。所以你还需要加上这行代码:
?
1
2
3
4
if(req.getMethod().equalsIgnoreCase("GET"))
{
    name =new String(name.getBytes("iso8859-1"),"utf-8");
}
之所以要判断一下请求的方式是是否为get,是因为如果请求方式为post的话,又会变成乱码了,当然,如果你在servlet中对doPost和doGet分别进行乱码处理,那就不用判断了。只是大多数人更喜欢这样写:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class xxxServlet extendsHttpServlet
{
    @Override
    protectedvoid doGet(HttpServletRequest req, HttpServletResponse resp)
            throwsServletException, IOException
     {
        //TODO   
    }
@Override
    protectedvoid doPost(HttpServletRequest req, HttpServletResponse resp)
            throwsServletException, IOException
    {
        this.doGet(req, resp);
    
}
此时一定要在doget方法中加上判断. 当然你还有另一种选择,那就是过滤器,配置如下所示的过滤器即可处理上述的乱码。 编码格式在web.xml中手动配置,避免硬编码。(context-param中配置)
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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 implementsFilter
{
    privatestatic String charset ="iso8859-1";//默认编码
 
    publicvoid doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain)throws IOException, ServletException
    {
        System.out.println("filter running...");
         
        finalHttpServletRequest 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()
        {
            publicObject invoke(Object proxy, Method method, Object[] args)
                    throwsThrowable
            {
              if(!method.getName().equals("getParameter"))//拦截getParameter方法
                {
                    returnmethod.invoke(req, args);
                }
                if(!req.getMethod().equalsIgnoreCase("get"))//拦截get请求
                {
                    returnmethod.invoke(req, args);
                }
                String value = (String) method.invoke(req, args);
                if(value ==null)
                    returnnull;
                returnnew String(value.getBytes("iso8859-1"),charset);
            }
        }),resp);
    }
 
    publicvoid init(FilterConfig filterConfig)throws ServletException
    {
        String temp = filterConfig.getServletContext().getInitParameter("charset");
        if(temp !=null)
            charset = temp;
    }
    publicvoid destroy()
    {
         
    }
}
对过滤器不熟悉的参考这篇文章:filter详解
1 0
原创粉丝点击