[安卓笔记]android客户端向tomcat服务器发送请求中文乱码问题解决
投稿于 被查看 35595 次 评论:102
[安卓笔记]android客户端向tomcat服务器发送请求中文乱码问题解决
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,Mappost请求: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方式向服务端发送请求,并将服务端的响应结果以字符串方式返回。如果没有响应内容则返回空字符串 * @param url 请求的url地址 * @param params 请求参数 * @param charset url编码采用的码表 * @return */ public static String getDataByPost(String url,Mapstream2String方法(将流对象中的数据转化为字符串):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 ""; }
/** * 将输入流对象中的数据输出到字符串中返回 * @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详解
用户评论