• Android之网络编程


    本文主要包括三方面内容

    1. Httpurlconnection中doGet与doPost方法实现提交数据到服务器

    2. HttpClient中doGet与doPost方法实现提交数据到服务器

    3. android-async-http开源库方法实现提交数据到服务器

    首先是服务器端的实现

    public class LoginServlet extends HttpServlet {
    
        /**
         * The doGet method of the servlet. <br>
         *
         * This method is called when a form has its tag value method equals to get.
         * 
         * @param request the request send by the client to the server
         * @param response the response send by the server to the client
         * @throws ServletException if an error occurred
         * @throws IOException if an error occurred
         */
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            String username = request.getParameter("username"); // 采用的编码是: iso-8859-1
            String password = request.getParameter("password");
    
            // 采用iso8859-1的编码对姓名进行逆转, 转换成字节数组, 再使用utf-8编码对数据进行转换, 字符串
            username = new String(username.getBytes("iso8859-1"), "utf-8");
            password = new String(password.getBytes("iso8859-1"), "utf-8");
    
            System.out.println("姓名: " + username);
            System.out.println("密码: " + password);
    
            if("lisi".equals(username) && "123".equals(password)) {
                /*
                 * getBytes 默认情况下, 使用的iso8859-1的编码, 但如果发现码表中没有当前字符, 
                 * 会使用当前系统下的默认编码: GBK
                 */ 
                response.getOutputStream().write("登录成功".getBytes("utf-8"));
            } else {
                response.getOutputStream().write("登录失败".getBytes("utf-8"));
            }
        }
    
        /**
         * The doPost method of the servlet. <br>
         *
         * This method is called when a form has its tag value method equals to post.
         * 
         * @param request the request send by the client to the server
         * @param response the response send by the server to the client
         * @throws ServletException if an error occurred
         * @throws IOException if an error occurred
         */
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            System.out.println("doPost");
            doGet(request, response);
        }
    
    }

    Httpurlconnection实现提交数据到服务器

    public class NetUtils {
    
        private static final String TAG = "NetUtils";
    
        /**
         * 使用post的方式登录
         * @param userName
         * @param password
         * @return
         */
        public static String loginOfPost(String userName, String password) {
            HttpURLConnection conn = null;
            try {
                URL url = new URL("http://10.0.2.2:8080/ServerItheima28/servlet/LoginServlet");
    
                conn = (HttpURLConnection) url.openConnection();
    
                conn.setRequestMethod("POST");
                conn.setConnectTimeout(10000); // 连接的超时时间
                conn.setReadTimeout(5000); // 读数据的超时时间
                conn.setDoOutput(true); // 必须设置此方法, 允许输出
    //          conn.setRequestProperty("Content-Length", 234);     // 设置请求头消息, 可以设置多个
    
                // post请求的参数
                String data = "username=" + userName + "&password=" + password;
    
                // 获得一个输出流, 用于向服务器写数据, 默认情况下, 系统不允许向服务器输出内容
                OutputStream out = conn.getOutputStream();  
                out.write(data.getBytes());
                out.flush();
                out.close();
    
                int responseCode = conn.getResponseCode();
                if(responseCode == 200) {
                    InputStream is = conn.getInputStream();
                    String state = getStringFromInputStream(is);
                    return state;
                } else {
                    Log.i(TAG, "访问失败: " + responseCode);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if(conn != null) {
                    conn.disconnect();
                }
            }
            return null;
        }
    
        /**
         * 使用get的方式登录
         * @param userName
         * @param password
         * @return 登录的状态
         */
        public static String loginOfGet(String userName, String password) {
            HttpURLConnection conn = null;
            try {
                String data = "username=" + URLEncoder.encode(userName) + "&password=" + URLEncoder.encode(password);
                URL url = new URL("http://10.0.2.2:8080/ServerItheima28/servlet/LoginServlet?" + data);
                conn = (HttpURLConnection) url.openConnection();
    
                conn.setRequestMethod("GET");       // get或者post必须得全大写
                conn.setConnectTimeout(10000); // 连接的超时时间
                conn.setReadTimeout(5000); // 读数据的超时时间
    
                int responseCode = conn.getResponseCode();
                if(responseCode == 200) {
                    InputStream is = conn.getInputStream();
                    String state = getStringFromInputStream(is);
                    return state;
                } else {
                    Log.i(TAG, "访问失败: " + responseCode);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if(conn != null) {
                    conn.disconnect();      // 关闭连接
                }
            }
            return null;
        }
    
        /**
         * 根据流返回一个字符串信息
         * @param is
         * @return
         * @throws IOException 
         */
        private static String getStringFromInputStream(InputStream is) throws IOException {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = -1;
    
            while((len = is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            is.close();
    
            String html = baos.toString();  // 把流中的数据转换成字符串, 采用的编码是: utf-8
    
    //      String html = new String(baos.toByteArray(), "GBK");
    
            baos.close();
            return html;
        }
    }

    HttpClient实现提交数据到服务器

    public class NetUtils2 {
    
        private static final String TAG = "NetUtils";
    
        /**
         * 使用post的方式登录
         * @param userName
         * @param password
         * @return
         */
        public static String loginOfPost(String userName, String password) {
            HttpClient client = null;
            try {
                // 定义一个客户端
                client = new DefaultHttpClient();
    
                // 定义post方法
                HttpPost post = new HttpPost("http://10.0.2.2:8080/ServerItheima28/servlet/LoginServlet");
    
                // 定义post请求的参数
                List<NameValuePair> parameters = new ArrayList<NameValuePair>();
                parameters.add(new BasicNameValuePair("username", userName));
                parameters.add(new BasicNameValuePair("password", password));
    
                // 把post请求的参数包装了一层.
    
                // 不写编码名称服务器收数据时乱码. 需要指定字符集为utf-8
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters, "utf-8");
                // 设置参数.
                post.setEntity(entity);
    
                // 设置请求头消息
    //          post.addHeader("Content-Length", "20");
    
                // 使用客户端执行post方法
                HttpResponse response = client.execute(post);   // 开始执行post请求, 会返回给我们一个HttpResponse对象
    
                // 使用响应对象, 获得状态码, 处理内容
                int statusCode = response.getStatusLine().getStatusCode();  // 获得状态码
                if(statusCode == 200) {
                    // 使用响应对象获得实体, 获得输入流
                    InputStream is = response.getEntity().getContent();
                    String text = getStringFromInputStream(is);
                    return text;
                } else {
                    Log.i(TAG, "请求失败: " + statusCode);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if(client != null) {
                    client.getConnectionManager().shutdown();   // 关闭连接和释放资源
                }
            }
            return null;
        }
    
        /**
         * 使用get的方式登录
         * @param userName
         * @param password
         * @return 登录的状态
         */
        public static String loginOfGet(String userName, String password) {
            HttpClient client = null;
            try {
                // 定义一个客户端
                client = new DefaultHttpClient();
    
                // 定义一个get请求方法
                String data = "username=" + userName + "&password=" + password;
                HttpGet get = new HttpGet("http://10.0.2.2:8080/ServerItheima28/servlet/LoginServlet?" + data);
    
                // response 服务器相应对象, 其中包含了状态信息和服务器返回的数据
                HttpResponse response = client.execute(get);    // 开始执行get方法, 请求网络
    
                // 获得响应码
                int statusCode = response.getStatusLine().getStatusCode();
    
                if(statusCode == 200) {
                    InputStream is = response.getEntity().getContent();
                    String text = getStringFromInputStream(is);
                    return text;
                } else {
                    Log.i(TAG, "请求失败: " + statusCode);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if(client != null) {
                    client.getConnectionManager().shutdown();   // 关闭连接, 和释放资源
                }
            }
            return null;
        }
    
        /**
         * 根据流返回一个字符串信息
         * @param is
         * @return
         * @throws IOException 
         */
        private static String getStringFromInputStream(InputStream is) throws IOException {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = -1;
    
            while((len = is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            is.close();
    
            String html = baos.toString();  // 把流中的数据转换成字符串, 采用的编码是: utf-8
    
    //      String html = new String(baos.toByteArray(), "GBK");
    
            baos.close();
            return html;
        }
    }

    在onCreate方法中的调用

    public class MainActivity extends Activity {
    
        private EditText etUserName;
        private EditText etPassword;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            etUserName = (EditText) findViewById(R.id.et_username);
            etPassword = (EditText) findViewById(R.id.et_password);
        }
    
        public void doGet(View v) {
            final String userName = etUserName.getText().toString();
            final String password = etPassword.getText().toString();
    
            new Thread(
                    new Runnable() {
    
                        @Override
                        public void run() {
                            // 使用get方式抓去数据
                            final String state = NetUtils.loginOfGet(userName, password);
    
                            // 执行任务在主线程中
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    // 就是在主线程中操作
                                    Toast.makeText(MainActivity.this, state, 0).show();
                                }
                            });
                        }
                    }).start();
        }
    
        public void doPost(View v) {
            final String userName = etUserName.getText().toString();
            final String password = etPassword.getText().toString();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    final String state = NetUtils.loginOfPost(userName, password);
                    // 执行任务在主线程中
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            // 就是在主线程中操作
                            Toast.makeText(MainActivity.this, state, 0).show();
                        }
                    });
                }
            }).start();
        }
    }

    使用runOnUiThread方法,可以在子线程中实现对主线程的操作

    使用android-async-http开源库方法实现提交数据到服务器 ,使用方法也是将src文件夹中的内容复制到程序中即可

    public class MainActivity2 extends Activity {
    
        protected static final String TAG = "MainActivity2";
        private EditText etUserName;
        private EditText etPassword;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            etUserName = (EditText) findViewById(R.id.et_username);
            etPassword = (EditText) findViewById(R.id.et_password);
        }
    
        public void doGet(View v) {
            final String userName = etUserName.getText().toString();
            final String password = etPassword.getText().toString();
    
            AsyncHttpClient client = new AsyncHttpClient();
    
            String data = "username=" + URLEncoder.encode(userName) + "&password=" + URLEncoder.encode(password);
    
            client.get("http://10.0.2.2:8080/ServerItheima28/servlet/LoginServlet?" + data, new MyResponseHandler());
        }
    
        public void doPost(View v) {
            final String userName = etUserName.getText().toString();
            final String password = etPassword.getText().toString();
    
            AsyncHttpClient client = new AsyncHttpClient();
    
            RequestParams params = new RequestParams();
            params.put("username", userName);
            params.put("password", password);
    
            client.post("http://10.0.2.2:8080/ServerItheima28/servlet/LoginServlet", 
                    params, 
                    new MyResponseHandler());
        }
    
        class MyResponseHandler extends AsyncHttpResponseHandler {
    
            @Override
            public void onSuccess(int statusCode, Header[] headers,
                    byte[] responseBody) {
    //          Log.i(TAG, "statusCode: " + statusCode);
    
                Toast.makeText(MainActivity2.this, 
                        "成功: statusCode: " + statusCode + ", body: " + new String(responseBody), 
                        0).show();
            }
    
            @Override
            public void onFailure(int statusCode, Header[] headers,
                    byte[] responseBody, Throwable error) {
                Toast.makeText(MainActivity2.this, "失败: statusCode: " + statusCode, 0).show();
            }
        }
    }

    可以看到使用开源框架可以更加简单,高效,安全的实现相同的效果.

    完成

  • 相关阅读:
    【学习笔记】整除分块
    【Luogu P2201】【JZOJ 3922】数列编辑器
    【SSL1786】麻将游戏
    【SSL2325】最小转弯问题
    【JZOJ 3910】Idiot 的间谍网络
    【Luogu P1879】[USACO06NOV]玉米田Corn Fields
    【JZOJ 3909】Idiot 的乘幂
    【JZOJ 3918】蛋糕
    【Luogu P3174 】[HAOI2009]毛毛虫
    【SSL1194】最优乘车
  • 原文地址:https://www.cnblogs.com/jjx2013/p/6223720.html
Copyright © 2020-2023  润新知