android重新学_网络3——采用HttpURLConnection提交数据到服务器
前两篇博客android重新学_网络1——采用HttpURLConnection获取网络图片 android重新学_网络2——采用HttpURLConnection获取获取网页源代码,我们分别学习了从网络上获取一张图片和文本以及对中文乱码的处理,那么这一篇博客,我们来学习如何提交数据到服务器。典型的案例就是登录。
一.案例需求。
安卓客户端输入用户名和密码,登录到服务器。
二.界面绘制。
三.代码
1 package com.example.submitdata; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.text.TextUtils; 6 import android.view.View; 7 import android.widget.Button; 8 import android.widget.CheckBox; 9 import android.widget.EditText; 10 import android.widget.Toast; 11 12 import java.io.*; 13 import java.net.HttpURLConnection; 14 import java.net.URL; 15 import java.net.URLEncoder; 16 17 public class MyActivity extends Activity { 18 /** 19 * Called when the activity is first created. 20 */ 21 String name; 22 String ps; 23 @Override 24 public void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 setContentView(R.layout.main); 27 ((Button)findViewById(R.id.btn_submit)).setOnClickListener(new View.OnClickListener() { 28 @Override 29 public void onClick(View v) { 30 name = ((EditText) findViewById(R.id.et_name)).getText().toString().trim(); 31 ps = ((EditText) findViewById(R.id.et_ps)).getText().toString().trim(); 32 if (TextUtils.isEmpty(name) || TextUtils.isEmpty(ps)) { 33 Toast.makeText(MyActivity.this, "请输入用户名及密码", Toast.LENGTH_SHORT).show(); 34 } else { 35 boolean isPost = ((CheckBox) findViewById(R.id.is_post)).isChecked(); 36 if (isPost) { 37 String path = "http://192.168.1.100:8080/web/LoginServlet"; 38 gotoHttp(path, isPost); 39 } else { 40 try { 41 String path = "http://192.168.1.100:8080/web/LoginServlet?username=" + URLEncoder.encode(name,"utf-8") + "&password=" + URLEncoder.encode(ps,"utf-8"); 42 gotoHttp(path, isPost); 43 } catch (UnsupportedEncodingException e) { 44 e.printStackTrace(); 45 } 46 } 47 } 48 } 49 }); 50 } 51 52 private void gotoHttp(String path,boolean isPost) { 53 //1.拼装路径 54 new Thread(){ 55 @Override 56 public void run() { 57 String text; 58 if(isPost){ 59 text = loginByPost(path); 60 }else{ 61 text = loginByGet(path); 62 } 63 64 if(TextUtils.isEmpty(text)){ 65 runOnUiThread(new Runnable() { 66 @Override 67 public void run() { 68 Toast.makeText(MyActivity.this, "登陆失败", Toast.LENGTH_SHORT).show(); 69 } 70 }); 71 }else { 72 runOnUiThread(new Runnable() { 73 @Override 74 public void run() { 75 Toast.makeText(MyActivity.this,text, Toast.LENGTH_SHORT).show(); 76 } 77 }); 78 } 79 } 80 }.start(); 81 } 82 83 private String loginByGet(String path) { 84 try { 85 URL url = new URL(path); 86 HttpURLConnection connection = (HttpURLConnection)url.openConnection(); 87 connection.setConnectTimeout(3000); 88 connection.setRequestMethod("GET"); 89 int code = connection.getResponseCode(); 90 if (code == 200){ 91 InputStream is = connection.getInputStream(); 92 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 93 int len = 0; 94 byte[] buffer = new byte[1024]; 95 while ((len = is.read(buffer)) !=-1){ 96 baos.write(buffer,0,len); 97 } 98 is.close(); 99 baos.close(); 100 return new String(baos.toByteArray()); 101 } else { 102 return null; 103 } 104 } catch (IOException e) { 105 e.printStackTrace(); 106 } 107 return null; 108 } 109 110 private String loginByPost(String path) { 111 try { 112 String data = "username=" + URLEncoder.encode(name,"utf-8") + "&password=" + URLEncoder.encode(ps,"utf-8"); 113 URL url = new URL(path); 114 HttpURLConnection connection = (HttpURLConnection)url.openConnection(); 115 connection.setConnectTimeout(3000); 116 connection.setRequestMethod("POST"); 117 connection.setRequestProperty("Content-Length", data.length() + ""); 118 connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 119 connection.setDoOutput(true); 120 OutputStream os = connection.getOutputStream(); 121 os.write(data.getBytes()); 122 int code = connection.getResponseCode(); 123 if (code == 200){ 124 InputStream is = connection.getInputStream(); 125 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 126 int len = 0; 127 byte[] buffer = new byte[1024]; 128 while ((len = is.read(buffer)) !=-1){ 129 baos.write(buffer,0,len); 130 } 131 is.close(); 132 baos.close(); 133 return new String(baos.toByteArray()); 134 } else { 135 return null; 136 } 137 } catch (IOException e) { 138 e.printStackTrace(); 139 } 140 return null; 141 } 142 }
记得添加网络权限。
四.post请求方式的注意事项
1.与get请求方式的区别
Get:组拼url的方式提交服务器的。url有最大长度的,最长不超过1kb,即1024(ie浏览器)/4kb(http协议定义的)
Post:浏览器以流的方式直接把数据写给服务器
需要注意的是,当以post方式请求服务器的时候,路径就和以get方式请求服务器的路径不一样了,因为以post方式只是提交给某一个servlet(示例中,真实项目不一定),所以路径是http://localhost:8080/web/LoginServlet
记得替换localhost
由于post比get多了几个请求参数,所以我们需要额外进行添加设置。Content-Type,Content-Length,数据的长度是不能够写死的,需要我们提前算出来。因为Post是以流的方式直接把数据写给服务器,所以需要conn调用setDoOutput()方法,允许conn向外写数据,参数设置为true,接着调用getOUtputStream(),得到一个输出流OUputStream,得到这个对象后,调用write()方法,把字符串类型的数据的byte[]作为参数填到里面
2.中文字符乱码的问题解决
上面我们就用了一个小案例做出了提交数据到服务器,服务器返回给我们客户端的数据都是英文,如果是中文,就有可能会出现乱码,为什么呢?服务器将响应的结果以流的方式写入到客户端的,那么他所采用的编码集是什么呢?如果是utf-8,客户端也是utf-8就不会出现乱码的情况。如果服务器端显式指定编码集市utf-8,那么就不会出现乱码,如果服务器端不指定编码集,那服务器端是这样处理的:如果响应结果的内容在iso8859-1中有,就会以iso8859-1的编码进行转化byte,如果没有,就会用本地的码表,其实就是gbk的码表,也就是说,响应结果中的中文字符,最终是以gbk的编码返回的。而我们客户端采用的是直接new出一个string,其默认编码是utf-8,如果我们客户端显式的指定是gbk,也是没有问题的。
如果我们客户端童鞋和服务器端同学关系比较好,可以让服务器同学进行一下指定的编码集,客户端什么都不需要做,就可以解决乱码问题。但又很多时候是后台的代码是开发好的,不能再动了,这个时候我们解决乱码问题就需要知道服务器返回的数据是什么编码集了。只要两边用的码表一致就不会有乱码问题出现。
以上是服务器返回的数据中有中文,下面我们来解决一下客户端提交的数据中有中文,会出现乱码的问题
我们可以看一下服务器端的代码,request.getParameter()方法是servlet中的方法,由于是国外人写的方法,所以他们会采用自己默认的码表,即iso8859-1,其实直到服务器上,我们提交的都是中文,但是中文是不在iso8859-1码表中的,所以servlet中获取不到,也就是乱码的原因,如果想显示出来,肯定是用我们自己的码表,所以就需要对服务器端的代码进行修改。服务器修改了,那客户端就不用修改了吗?不是客户端也需要修改对url进行编码,对username和password进行编码,用URLEncoder的api调用encode()方法,注意是两个参数的,一个参数的过时了,其实一个参数的调用的也是两个参数的。上面的是get方法请求服务器中文乱码的解决。但是如果是post,服务器会直接拒绝的,如果有中文,中文数据也是需要进行编码的,不编码长度有可能是不正确的。当然,改的方法也是一样的。