Android网络编程之传递数据给服务器(一)

请尊重他人的劳动成果,转载请注明出处:Android网络编程之传递数据给服务器(一)

因为Android程序需要和服务器进行通信,所以需要服务器端提供的支持。

一、通过GET方式传递数据给服务器

通过GET方式上传数据主要适用于数据大小不超过2KB,且对安全性要求不高的情况下。

1.创建服务器端:

服务器端项目结构:

通过GET方式传递数据给服务器——服务器端项目结构

第一步:创建控制器Servlet

  1. package com.jph.sgm.servlet;
  2. import java.io.IOException;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. /**
  9. * Servlet implementation class ServletForGETMethod
  10. */
  11. @WebServlet("/ServletForGETMethod")
  12. public class ServletForGETMethod extends HttpServlet {
  13. private static final long serialVersionUID = 1L;
  14. /**
  15. * @see HttpServlet#HttpServlet()
  16. */
  17. public ServletForGETMethod() {
  18. super();
  19. // TODO Auto-generated constructor stub
  20. }
  21. /**
  22. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
  23. */
  24. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  25. // TODO Auto-generated method stub
  26. //获取请求的参数(使用utf-8进行解码,然后用进行ISO8859-1编码)
  27. // String name=new String(request.getParameter("name").getBytes("ISO8859-1"),"utf-8");
  28. String name=request.getParameter("name");
  29. String pwd=request.getParameter("pwd");
  30. System.out.println("name:"+name+" pwd:"+pwd);
  31. }
  32. /**
  33. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  34. */
  35. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  36. // TODO Auto-generated method stub
  37. }
  38. }
  39.  

第二步:测试Servlet

发布项目并在浏览器中输入:http://localhost:8080/ServerForGETMethod/ServletForGETMethod?name=aa&pwd=124

可以再控制台看到如下图的输出:

通过GET方式传递数据给服务器——服务器端测试结果

至此服务器端项目已经完成。下面开始创建Android端项目。

2.创建Android端:

Android端项目结构:

通过GET方式传递数据给服务器——Android端项目结构

第一步:创建Android端项目的业务逻辑层

核心代码:SendDateToServer.java:

  1. package com.jph.sdg.service;
  2. import java.net.HttpURLConnection;
  3. import java.net.URL;
  4. import java.net.URLEncoder;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. import android.os.Handler;
  8. /**
  9. * 通过GET方式向服务器发送数据
  10. * @author jph
  11. * Date:2014.09.27
  12. */
  13. public class SendDateToServer {
  14. private static String url="http://10.219.61.117:8080/ServerForGETMethod/ServletForGETMethod";
  15. public static final int SEND_SUCCESS=0x123;
  16. public static final int SEND_FAIL=0x124;
  17. private Handler handler;
  18. public SendDateToServer(Handler handler) {
  19. // TODO Auto-generated constructor stub
  20. this.handler=handler;
  21. }
  22. /**
  23. * 通过Get方式向服务器发送数据
  24. * @param name 用户名
  25. * @param pwd 密码
  26. */
  27. public void SendDataToServer(String name,String pwd) {
  28. // TODO Auto-generated method stub
  29. final Map<String, String>map=new HashMap<String, String>();
  30. map.put("name", name);
  31. map.put("pwd", pwd);
  32. new Thread(new Runnable() {
  33. @Override
  34. public void run() {
  35. // TODO Auto-generated method stub
  36. try {
  37. if (sendGetRequest(map,url,"utf-8")) {
  38. handler.sendEmptyMessage(SEND_SUCCESS);//通知主线程数据发送成功
  39. }else {
  40. //将数据发送给服务器失败
  41. }
  42. } catch (Exception e) {
  43. // TODO Auto-generated catch block
  44. e.printStackTrace();
  45. }
  46. }
  47. }).start();
  48. }
  49. /**
  50. * 发送GET请求
  51. * @param map 请求参数
  52. * @param url 请求路径
  53. * @return
  54. * @throws Exception
  55. */
  56. private boolean sendGetRequest(Map<String, String> param, String url,String encoding) throws Exception {
  57. // TODO Auto-generated method stub
  58. //http://localhost:8080/ServerForGETMethod/ServletForGETMethod?name=aa&pwd=124
  59. StringBuffer sb=new StringBuffer(url);
  60. if (!url.equals("")&!param.isEmpty()) {
  61. sb.append("?");
  62. for (Map.Entry<String, String>entry:param.entrySet()) {
  63. sb.append(entry.getKey()+"=");
  64. sb.append(URLEncoder.encode(entry.getValue(), encoding));
  65. sb.append("&");
  66. }
  67. sb.deleteCharAt(sb.length()-1);//删除字符串最后 一个字符“&”
  68. }
  69. HttpURLConnection conn=(HttpURLConnection) new URL(sb.toString()).openConnection();
  70. conn.setConnectTimeout(5000);
  71. conn.setRequestMethod("GET");//设置请求方式为GET
  72. if (conn.getResponseCode()==200) {
  73. return true;
  74. }
  75. return false;
  76. }
  77. }
  78.  

第三步:创建Activity

  1. package com.jph.sdg.activity;
  2. import com.jph.sdg.R;
  3. import com.jph.sdg.service.SendDateToServer;
  4. import android.os.Bundle;
  5. import android.os.Handler;
  6. import android.os.Message;
  7. import android.app.Activity;
  8. import android.view.View;
  9. import android.view.View.OnClickListener;
  10. import android.widget.Button;
  11. import android.widget.EditText;
  12. import android.widget.Toast;
  13. /**
  14. * 通过GET方式向服务器发送数据,通过GET方式上传数据主要适用于数
  15. * 据大小不超过2KB,且对安全性要求不高的情况下。
  16. * @author jph
  17. * Date:2014.09.27
  18. */
  19. public class MainActivity extends Activity {
  20. private EditText edtName,edtPwd;
  21. private Button btnSend;
  22. Handler handler=new Handler(){
  23. public void handleMessage(Message msg) {
  24. switch (msg.what) {
  25. case SendDateToServer.SEND_SUCCESS:
  26. Toast.makeText(MainActivity.this, "登陆成功", Toast.LENGTH_SHORT).show();
  27. break;
  28. case SendDateToServer.SEND_FAIL:
  29. Toast.makeText(MainActivity.this, "登陆失败", Toast.LENGTH_SHORT).show();
  30. break;
  31. default:
  32. break;
  33. }
  34. };
  35. };
  36. @Override
  37. protected void onCreate(Bundle savedInstanceState) {
  38. super.onCreate(savedInstanceState);
  39. setContentView(R.layout.activity_main);
  40. edtName=(EditText)findViewById(R.id.edtName);
  41. edtPwd=(EditText)findViewById(R.id.edtPwd);
  42. btnSend=(Button)findViewById(R.id.btnSend);
  43. btnSend.setOnClickListener(new OnClickListener() {
  44. @Override
  45. public void onClick(View v) {
  46. // TODO Auto-generated method stub
  47. String name=edtName.getText().toString();
  48. String pwd=edtPwd.getText().toString();
  49. if (edtName.equals("")||edtPwd.equals("")) {
  50. Toast.makeText(MainActivity.this, "用户名或密码不能为空", Toast.LENGTH_LONG).show();
  51. }else {
  52. new SendDateToServer(handler).SendDataToServer(name, pwd);
  53. }
  54. }
  55. });
  56. }
  57. }
  58.  

至此Android端项目已经完成了。下面就让我们看一下APP运行效果吧:

Android运行效果图:

通过GET方式传递数据给服务器——Android端运行效果图

二、关于通过GET方式传递数据给服务器时,中文乱码的解决方案

当客户端向服务器发送中文时服务器端会出现乱码现象,如下图:

关于通过GET方式传递数据给服务器时,中文乱码的解决方案

出现乱码的原因主要是,Android客户端我们采用的是UTF-8编码,而Tomcat默认采用的是ISO8859-1编码,所以会出现中文乱码的现象。

解决方案有两种:

第一种解决方案:

是使用UTF-8解码请求参数得到汉字,然后再通过ISO8859-1进行编码。此时服务器端的Servlet是:

  1. package com.jph.sgm.servlet;
  2. import java.io.IOException;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. /**
  9. * Servlet implementation class ServletForGETMethod
  10. */
  11. @WebServlet("/ServletForGETMethod")
  12. public class ServletForGETMethod extends HttpServlet {
  13. private static final long serialVersionUID = 1L;
  14. /**
  15. * @see HttpServlet#HttpServlet()
  16. */
  17. public ServletForGETMethod() {
  18. super();
  19. // TODO Auto-generated constructor stub
  20. }
  21. /**
  22. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
  23. */
  24. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  25. // TODO Auto-generated method stub
  26. //获取请求的参数(使用utf-8进行解码,然后用进行ISO8859-1编码)
  27. String name=new String(request.getParameter("name").getBytes("ISO8859-1"),"utf-8");
  28. // String name=request.getParameter("name");
  29. String pwd=request.getParameter("pwd");
  30. System.out.println("name:"+name+" pwd:"+pwd);
  31. }
  32. /**
  33. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  34. */
  35. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  36. // TODO Auto-generated method stub
  37. }
  38. }
  39.  

运行结果如下图:

UTF-8解码请求参数得到汉字,然后再通过ISO8859-1进行编码

第二种解决方案:

下面我们采用过滤器的方式来解决乱码的问题:

第一步:建立一个Filter过滤器。

EncodingFilter.java

  1. package com.jph.sgm.filter;
  2. import java.io.IOException;
  3. import javax.servlet.Filter;
  4. import javax.servlet.FilterChain;
  5. import javax.servlet.FilterConfig;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.ServletRequest;
  8. import javax.servlet.ServletResponse;
  9. import javax.servlet.annotation.WebFilter;
  10. import javax.servlet.http.HttpServletRequest;
  11. /**
  12. * Servlet Filter implementation class EncodingFilter
  13. */
  14. @WebFilter("/*")
  15. public class EncodingFilter implements Filter {
  16. /**
  17. * Default constructor.
  18. */
  19. public EncodingFilter() {
  20. // TODO Auto-generated constructor stub
  21. }
  22. /**
  23. * @see Filter#destroy()
  24. */
  25. public void destroy() {
  26. // TODO Auto-generated method stub
  27. }
  28. /**
  29. * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
  30. */
  31. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  32. // TODO Auto-generated method stub
  33. HttpServletRequest req=(HttpServletRequest) request;
  34. if ("GET".equals(req.getMethod())) {
  35. HttpServletRequestEncodingWrapper wrapper=new HttpServletRequestEncodingWrapper(req);
  36. chain.doFilter(wrapper, response);
  37. }else {
  38. req.setCharacterEncoding("utf-8");
  39. chain.doFilter(request, response);
  40. }
  41. }
  42. /**
  43. * @see Filter#init(FilterConfig)
  44. */
  45. public void init(FilterConfig fConfig) throws ServletException {
  46. // TODO Auto-generated method stub
  47. }
  48. }
  49.  

上面的过滤器因为设置了过滤路径为*/所以会过滤所有的Servlet。

在上面的过滤器中用到了一个包装器,HttpServletRequestEncodingWrapper.java

  1. package com.jph.sgm.filter;
  2. import java.io.UnsupportedEncodingException;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletRequestWrapper;
  5. public class HttpServletRequestEncodingWrapper extends
  6. HttpServletRequestWrapper {
  7. private HttpServletRequest request;
  8. public HttpServletRequestEncodingWrapper(HttpServletRequest request) {
  9. // TODO Auto-generated constructor stub
  10. super(request);
  11. this.request=request;
  12. }
  13. @Override
  14. public String getParameter(String name) {
  15. // TODO Auto-generated method stub
  16. String value=request.getParameter(name);
  17. if (value!=null) {
  18. try {//用utf-8进行解码,然后用ISO8859-1进行编码
  19. return new String(value.getBytes("ISO8859-1"),"utf-8");
  20. } catch (UnsupportedEncodingException e) {
  21. // TODO Auto-generated catch block
  22. e.printStackTrace();
  23. }
  24. }
  25. return super.getParameter(name);
  26. }
  27. }
  28.  

重新运行项目可以看到服务器会将客户端发来的数据用UTF-8进行解码,用ISO8859-1进行编码。运行效果图如下:

采用过滤器的方式来解决乱码的问题

Android网络编程之传递数据给服务器(二)——通过POST的方式将数据传递给服务器