在Android中,提供了标准Java接口HttpURLConnection和Apache接口HttpClient,为客户端HTTP编程提供了丰富的支持
在HTTP通信中使用最多的就是GET和POST了,GET请求可以获取静态页面,也可以把参数放在URL字符串的后面,传递给服务器。
POST与GET的不同之处在于POST的参数不是放在URL字符串里面,而是放在HTTP请求数据中。而且当我们把请求发送后,在浏览器端按上F12调试,我们可以发现,POST提交方式会比GET提交方式多两个内容出来,一个是请求长度,一个是请求类型,如下图:
Content-Leng:24 指的是uname=admin&upass=123456 这一串
在这篇博客中,我会介绍如何将数据提交到我们的服务器上,在这之前,我们需要在Eclipse上写好一个Web项目,用来做测试
1).我们新建一个Web项目
然后填写项目名
继续Next,在最后一步时,记得把那个选项选上,让它自动生成web.xml
项目就建好了,然后我们在创建一个Servlet类
把包名和类名写好
建好之后,如果环境没有配置好的话,就会出现报错的情况
这个时候,我们需要右键项目porpoise-->找到environment-->添加target ,把tomcat勾选上,然后项目就不会报错了
然后我们去web.xml上配置
然后我们需要在doGet方法里面,判断输入过来的数据,并且将结果显示在页面上
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String uname=request.getParameter("uname");
String upass=request.getParameter("upass");
PrintWriter printWriter=response.getWriter();
if(uname.equals("admin")&&upass.equals("123")){
printWriter.write("success");
}else {
printWriter.write("fail");
}
printWriter.close();
}
然后启动我们的项目,跑一遍,就大功告成了
至此,我们服务端的准备就可以告一段落了
在安卓客户端,我们先实现界面
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="请输入用户名:"
android:id="@+id/et_data_uname"
/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="请输入密码:"
android:inputType="number"
android:id="@+id/et_data_upass"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录(GET)"
android:onClick="loginGET"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录(POST)"
android:onClick="loginPOST"
/>
然后在Activity里面提交数据,在点击事件里面,我们只能获取输入框的值,而其他的操作我们就需要写到子线程中去
public class CommitDataActivity extends AppCompatActivity {
private EditText et_data_uname;
private EditText et_data_upass;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_commit_data);
et_data_uname = (EditText) findViewById(R.id.et_data_uname);
et_data_upass = (EditText) findViewById(R.id.et_data_upass);
}
public void loginGET(View view){
String uname=et_data_uname.getText().toString();
String upass=et_data_upass.getText().toString();
new MyTask().execute(uname,upass);
}
class MyTask extends AsyncTask{
@Override
protected Object doInBackground(Object[] objects) {
String name=objects[0].toString();
String pass=objects[1].toString();
try {
URL url=new URL("http://192.168.1.100:8080/Web_apptication/aa?uname="+name+"&upass="+pass);
HttpURLConnection connection= (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
if(connection.getResponseCode()==200){
InputStream is=connection.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String str=br.readLine();
//在子线程中不能操作有关界面的数据,要去onPostExecute方法
return str;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
//更新UI
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
String s=(String)o;
if("success".equals(s.trim())){
Toast.makeText(CommitDataActivity.this,"跳转到主页面",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(CommitDataActivity.this,"用户名或密码错误",Toast.LENGTH_SHORT).show();
}
}
}
}
我们GET方式的提交就实现了
然后我们来看POST提交数据,点击事件和GET的一样,只是在参数的地方,我们需要多添加一个类型,为了区分
在doInBackground方法里面,我们需要先判断是哪种类型的提交方式,然后把POST方法里多出来的那两个头部内容添加进去,再把内容提交服务器,就可以了
class MyTask extends AsyncTask{
private HttpURLConnection connection;
private URL url;
@Override
protected Object doInBackground(Object[] objects) {
String name=objects[0].toString();
String pass=objects[1].toString();
String type=objects[2].toString();
try {
if("GET".equals(type)){
//用GET请求方式
url = new URL("http://192.168.1.100:8080/Web_apptication/aa?uname="+name+"&upass="+pass);
}else{
url=new URL("http://192.168.1.100:8080/Web_apptication/aa");
}
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(type);
connection.setConnectTimeout(5000);
if("POST".equals(type)){
//设置可以允许对外输出数据
connection.setDoOutput(true);
//添加请求长度和类型(这里java程序员需要添加到接口里面去)
String str="uname="+name+"&pass="+pass;
connection.setRequestProperty("Content-Length",""+str);
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
//将内容提交到服务器中
connection.getOutputStream().write(str.getBytes());
}
if(connection.getResponseCode()==200){
InputStream is= connection.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String str=br.readLine();
//在子线程中不能操作有关界面的数据,要去onPostExecute方法
return str;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
//更新UI
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
String s=(String)o;
if("success".equals(s.trim())){
Toast.makeText(CommitDataActivity.this,"跳转到主页面",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(CommitDataActivity.this,"用户名或密码错误",Toast.LENGTH_SHORT).show();
}
}
}
在这里,除了POST,GET方式的提交方式,我再多讲一种第三方网络请求框架AsyncHttpClient
我们先把android-async-http-1.4.4.jar下到本地,然后拷到项目里,因为HttpClient有导致一些小问题,所以我们需要在Gradle的版本前添加一句useLibrar'org.apache.http.legacy'
在点击事件里面写提交数据,在httpClient.post方法里面,带来地址,和参数,还有一个Handler,然后重写Handler的两个方法即可,效果图和前面的一样的,我就不展示了
public void loginAsync(View view){
String uname=et_data_uname.getText().toString();
String upass=et_data_upass.getText().toString();
AsyncHttpClient httpClient=new AsyncHttpClient();
RequestParams params=new RequestParams();
params.put("uname",uname);
params.put("upass",upass);
httpClient.post("http://192.168.1.100:8080/Web_apptication/aa",params,new TextHttpResponseHandler(){
@Override
public void onFailure(int statusCode, Header[] headers, String responseBody, Throwable error) {
super.onFailure(statusCode, headers, responseBody, error);
Toast.makeText(CommitDataActivity.this,""+responseBody,Toast.LENGTH_LONG).show();
}
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
super.onSuccess(statusCode, headers, responseBody);
}
});
}
使用第三方,会使得我们的代码更加的简洁,使用也更加方便