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方式向服务端发送请求,并将服务端的响应结果以字符串方式返回。如果没有响应内容则返回空字符串     *      * @param url 请求的url地址     * @param params 请求参数     * @param charset url编码采用的码表     * @return     */    public static 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);            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方式向服务端发送请求,并将服务端的响应结果以字符串方式返回。如果没有响应内容则返回空字符串     * @param url 请求的url地址     * @param params 请求参数     * @param charset url编码采用的码表     * @return     */    public static 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                        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详解



更多相关文章

  1. Activity之launchMode(运行模式)
  2. Android联网使用HttpClient 和HttpResponse 小结
  3. 总结 使用PHP作为中间介来实现android链接远程数据库。
  4. ObjectHttp使用介绍篇 —— 基础使用
  5. Android(安卓)6.0权限获取方式-shouldShowRequestPermissionRati
  6. Android(安卓)Camera2架构-Frameworks下发预览和拍照请求流程Fra
  7. java Android(安卓)OKHttp HTTPS 请求证书验证 PEM证书(1)
  8. android4启程
  9. android其实很简单 -- Glide简单分析

随机推荐

  1. Android实现底部弹出列表选择器
  2. Android工程中R.java文件突然消失
  3. Android客户端采用Http 协议Post方式请求
  4. Android的垃圾回收机制(android refbase类
  5. android中轮播图的实现
  6. OpenCV自学笔记31. Android 上使用jni和o
  7. 自定义Android(安卓)Toasts风格
  8. Android开发——了解android项目目录结构
  9. 58同城android客户端手机号码解密方法
  10. Android开发FAQ之二