Android 实现http通信(servlet做服务器端) HttpClient、HttpURLConnection实现登录验证
一,写好服务器端
在eclipse或其它javaee开发工具中新建一个web项目(我这里的项目名是:Android),建一个servlet(我这里的servlet名是:LoginServlet),模拟实现数据库,对安卓请求的数据判断,并返回(封装为json,需要json有解析json的jar包哦),servlet核心代码如下:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { number++; System.out.println("已经进入... ,第"+number+"次"); request.setCharacterEncoding("utf-8"); String name=""; String password = ""; name = request.getParameter("name"); password = request.getParameter("password"); String result = ""; //模拟数据库获取数据并判断 if ("yyc".equals(name)&&"123456".equals(password)) { result="success"; }else{ result = "error"; } JSONObject jsonObject = new JSONObject(); jsonObject.put("result", result); response.getWriter().print(jsonObject); }
写完了就可以发布在Tomcat服务器上(我们这里就写一个servlet就足够了),在浏览器中,访问试试,看不能访问,免得影响后续步骤的操作。测试链接,如:http://127.0.0.1:8080/Android/servlet/LoginServlet?name=yyc&password=123456
二、Android布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:id="@+id/nameEdit" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="点击输入用户名" android:inputType="text" /> <EditText android:id="@+id/passwordEdit" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="点击输入密码" android:inputType="numberPassword" /> <Button android:id="@+id/login" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="登录(HttpClient)" /> <Button android:id="@+id/login1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="登录(HttpURLConnection)" /> </LinearLayout>
从布局文件中可以看出写了两个输入框,一个输入用户名,一个输密码,两个按钮,一个用于测试HttpClient通信,一个用于测试HttpURLConnection通信。我们先来实现HttpClient吧。
三、用HttpClient实现登陆认证(不建议)
在这之前,先在Android模拟器的浏览器中,访问刚刚的地址,测试能不能访问,不要影响我们后面的程序。注意:这时不能通过localhost来访问了,通过ip,cmd输入ipconfig可以查看ip地址。
现在高版本的android要使用HttpClient的话,要在build.gradle(app)中的android标签中添加:useLibrary 'org.apache.http.legacy',由于我们要访问网络,我们需要设置网络权限:在AndroidManifest.xml中加入网络权限:<uses-permission android:name="android.permission.INTERNET"/>
在android studio中新建一个类:HttpUtilsHttpClient
public class HttpUtilsHttpClient { //1.创建HttpClient对象 private static HttpClient httpClient = new DefaultHttpClient(); public static String BASE_URL= "http://你的ip地址:8080/Android"; /** * GET方式 * @param url * @return */ public static String getRequest(String url){ String result = ""; //2.创建HttpGet对象 HttpGet httpGet= new HttpGet(url); try { //3.发送Get请求 HttpResponse response = httpClient.execute(httpGet); if (response.getStatusLine().getStatusCode() == 200){ //4.获取服务器返回的数据 HttpEntity entity = response.getEntity(); result = EntityUtils.toString(entity); } } catch (IOException e) { e.printStackTrace(); } return result ; } public static String postRequest(String url,Map<String,String> params){ String result = ""; HttpPost httpPost = new HttpPost(url); List<NameValuePair> parameters = new ArrayList<>(); for (Map.Entry<String,String> entry: params.entrySet()) { NameValuePair pair = new BasicNameValuePair(entry.getKey(),entry.getValue()); parameters.add(pair); } try { httpPost.setEntity(new UrlEncodedFormEntity(parameters,"utf-8")); HttpResponse response = httpClient.execute(httpPost); if (response.getStatusLine().getStatusCode() == 200){ //4.获取服务器返回的数据 HttpEntity entity = response.getEntity(); result = EntityUtils.toString(entity); } }catch (IOException e) { e.printStackTrace(); } return result; } }
这个类总共两个方法getRequest故名思意就是Get请求,postRequest就是post方式请求,由于我们要传参数(name和password),我们这里真正使用的是post请求。参数保存在一个map集合中。执行后返回String类型的参数,其实就是json字符串。
然后在MainActivity中调用PostRequest方法(设置url和参数),并对放回的String字符串(json)解析,做出相应的表现(Toast成功或者失败);
private void loginButtonHttpClientOption() { loginButtonHttpClient.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new Thread(new Runnable() { @Override public void run() { String url=HttpUtilsHttpClient.BASE_URL+"/servlet/LoginServlet"; Map<String ,String > params = new HashMap<String, String>(); String name=nameEdit.getText().toString(); String password=passwordEdit.getText().toString(); params.put("name",name); params.put("password",password); //请求,返回json String result = HttpUtilsHttpClient.postRequest(url, params); Message msg = new Message(); msg.what=0x11; Bundle data=new Bundle(); data.putString("result",result); msg.setData(data); hander.sendMessage(msg); } Handler hander = new Handler(){ @Override public void handleMessage(Message msg) { if (msg.what==0x11){ Bundle data = msg.getData(); String key = data.getString("result");//得到json返回的json数据 // Toast.makeText(MainActivity.this,key,Toast.LENGTH_LONG).show(); try { JSONObject json= new JSONObject(key); String result = (String) json.get("result"); if ("success".equals(result)){ Toast.makeText(MainActivity.this,"登录成功",Toast.LENGTH_LONG).show(); }else if("error".equals(result)){ Toast.makeText(MainActivity.this,"登录失败",Toast.LENGTH_LONG).show(); } } catch (JSONException e) { e.printStackTrace(); } } } }; }).start(); } }); }
loginButtonHttpClientOption这个方法主要就是一个按钮的点击事件监听,设置url、获取EditText中的值后封装在map中后,我们就可以请求http了(调用HttpUtilsHttpClient.postRequest(url, params);)。
而Handler的作用是一般情况下,在主线程中我们绑定了Handler,并在事件触发上面创建新的线程用于完成某些耗时的操作(我们这里用线程访问了网络),当子线程中的工作完成之后,会对Handler发送一个完成的信号,
而Handler接收到信号后,就进行主UI界面的更新操作(我们这里直接判断并Toast)。对Handler和线程不理解的话,可以去百度搜搜其它技术贴看看。
四、使用HttpURLConnection实现登录验证(建议)
安卓建议我们使用这种方式,我们也不用修改build文件了,但还是需要在AndroidManifest.xml文件中加入网络权限:<uses-permission android:name="android.permission.INTERNET"/>
新建类:HttpUtilsHttpURLConnection
public class HttpUtilsHttpURLConnection {
public static String BASE_URL= "http://你的ip地址:8080/Android";
/*
* urlStr:网址
* parms:提交数据
* return:网页源码
* */
public static String getContextByHttp(String urlStr,Map<String,String> parms){
StringBuilder sb = new StringBuilder();
try{
URL url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setReadTimeout(5000);
connection.setConnectTimeout(5000);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(true);
OutputStream outputStream = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream,"UTF-8"));
writer.write(getStringFromOutput(parms));
writer.flush();
writer.close();
outputStream.close();
if(connection.getResponseCode() == HttpURLConnection.HTTP_OK){
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String temp;
while((temp = reader.readLine()) != null){
sb.append(temp);
}
reader.close();
}else{
return "connection error:" + connection.getResponseCode();
}
connection.disconnect();
}catch (Exception e){
return e.toString();
}
return sb.toString();
}
/**
* 将map转换成key1=value1&key2=value2的形式
* @param map
* @return
* @throws UnsupportedEncodingException
*/
private static String getStringFromOutput(Map<String,String> map) throws UnsupportedEncodingException {
StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for(Map.Entry<String,String> entry:map.entrySet()){
if(isFirst)
isFirst = false;
else
sb.append("&");
sb.append(URLEncoder.encode(entry.getKey(),"UTF-8"));
sb.append("=");
sb.append(URLEncoder.encode(entry.getValue(),"UTF-8"));
}
return sb.toString();
}
}
这个和上面讲的那个HeepClient也没多大区别,有异曲同工之妙嘛。仔细店看看就懂了。
点击事件监听代码:
这和上面的那个点击事件也是一样的啦,没什么好说的。同样的是设置url、获取EditText中的值后封装在map中后,请求http。返回数据并解析。
private void loginButtonHttpURLConnectionOption() { loginButtonHttpURLConnection.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new Thread(new Runnable() { @Override public void run() { String url=HttpUtilsHttpURLConnection.BASE_URL+"/servlet/LoginServlet"; Map<String, String> params = new HashMap<String, String>(); String name=nameEdit.getText().toString(); String password=passwordEdit.getText().toString(); params.put("name",name); params.put("password",password); String result = HttpUtilsHttpURLConnection.getContextByHttp(url,params); Message msg = new Message(); msg.what=0x12; Bundle data=new Bundle(); data.putString("result",result); msg.setData(data); hander.sendMessage(msg); } Handler hander = new Handler(){ @Override public void handleMessage(Message msg) { if (msg.what==0x12){ Bundle data = msg.getData(); String key = data.getString("result");//得到json返回的json // Toast.makeText(MainActivity.this,key,Toast.LENGTH_LONG).show(); try { JSONObject json= new JSONObject(key); String result = (String) json.get("result"); if ("success".equals(result)){ Toast.makeText(MainActivity.this,"登录成功",Toast.LENGTH_LONG).show(); }else if("error".equals(result)){ Toast.makeText(MainActivity.this,"登录失败",Toast.LENGTH_LONG).show(); } } catch (JSONException e) { e.printStackTrace(); } } } }; }).start(); } }); }
效果图:
成功: 失败:
最后贴上MainActivity的所有代码:
1 package com.yyc.webservice; 2 3 import android.os.Handler; 4 import android.os.Message; 5 import android.support.v7.app.AppCompatActivity; 6 import android.os.Bundle; 7 import android.view.View; 8 import android.widget.Button; 9 import android.widget.EditText; 10 import android.widget.Toast; 11 12 import org.json.JSONException; 13 import org.json.JSONObject; 14 15 import java.util.HashMap; 16 import java.util.Map; 17 18 public class MainActivity extends AppCompatActivity { 19 20 private EditText nameEdit,passwordEdit; 21 private Button loginButtonHttpClient,loginButtonHttpURLConnection; 22 @Override 23 protected void onCreate(Bundle savedInstanceState) { 24 super.onCreate(savedInstanceState); 25 setContentView(R.layout.activity_main); 26 27 init(); 28 loginButtonHttpClientOption(); 29 loginButtonHttpURLConnectionOption(); 30 31 32 } 33 34 private void loginButtonHttpURLConnectionOption() { 35 loginButtonHttpURLConnection.setOnClickListener(new View.OnClickListener() { 36 @Override 37 public void onClick(View v) { 38 new Thread(new Runnable() { 39 @Override 40 public void run() { 41 String url=HttpUtilsHttpURLConnection.BASE_URL+"/servlet/LoginServlet"; 42 Map<String, String> params = new HashMap<String, String>(); 43 String name=nameEdit.getText().toString(); 44 String password=passwordEdit.getText().toString(); 45 params.put("name",name); 46 params.put("password",password); 47 48 String result = HttpUtilsHttpURLConnection.getContextByHttp(url,params); 49 50 Message msg = new Message(); 51 msg.what=0x12; 52 Bundle data=new Bundle(); 53 data.putString("result",result); 54 msg.setData(data); 55 56 57 hander.sendMessage(msg); 58 } 59 60 Handler hander = new Handler(){ 61 @Override 62 public void handleMessage(Message msg) { 63 if (msg.what==0x12){ 64 Bundle data = msg.getData(); 65 String key = data.getString("result");//得到json返回的json 66 // Toast.makeText(MainActivity.this,key,Toast.LENGTH_LONG).show(); 67 try { 68 JSONObject json= new JSONObject(key); 69 String result = (String) json.get("result"); 70 if ("success".equals(result)){ 71 Toast.makeText(MainActivity.this,"登录成功",Toast.LENGTH_LONG).show(); 72 }else if("error".equals(result)){ 73 Toast.makeText(MainActivity.this,"登录失败",Toast.LENGTH_LONG).show(); 74 } 75 } catch (JSONException e) { 76 e.printStackTrace(); 77 } 78 } 79 } 80 }; 81 }).start(); 82 } 83 }); 84 } 85 86 private void loginButtonHttpClientOption() { 87 loginButtonHttpClient.setOnClickListener(new View.OnClickListener() { 88 @Override 89 public void onClick(View v) { 90 new Thread(new Runnable() { 91 @Override 92 public void run() { 93 String url=HttpUtilsHttpClient.BASE_URL+"/servlet/LoginServlet"; 94 Map<String ,String > params = new HashMap<String, String>(); 95 String name=nameEdit.getText().toString(); 96 String password=passwordEdit.getText().toString(); 97 params.put("name",name); 98 params.put("password",password); 99 //请求,返回json 100 String result = HttpUtilsHttpClient.postRequest(url, params); 101 Message msg = new Message(); 102 msg.what=0x11; 103 Bundle data=new Bundle(); 104 data.putString("result",result); 105 msg.setData(data); 106 107 108 hander.sendMessage(msg); 109 } 110 111 Handler hander = new Handler(){ 112 @Override 113 public void handleMessage(Message msg) { 114 if (msg.what==0x11){ 115 Bundle data = msg.getData(); 116 String key = data.getString("result");//得到json返回的json 117 // Toast.makeText(MainActivity.this,key,Toast.LENGTH_LONG).show(); 118 try { 119 JSONObject json= new JSONObject(key); 120 String result = (String) json.get("result"); 121 if ("success".equals(result)){ 122 Toast.makeText(MainActivity.this,"登录成功",Toast.LENGTH_LONG).show(); 123 }else if("error".equals(result)){ 124 Toast.makeText(MainActivity.this,"登录失败",Toast.LENGTH_LONG).show(); 125 } 126 } catch (JSONException e) { 127 e.printStackTrace(); 128 } 129 } 130 } 131 }; 132 }).start(); 133 } 134 }); 135 } 136 137 private void init() { 138 nameEdit = (EditText) findViewById(R.id.nameEdit); 139 passwordEdit = (EditText) findViewById(R.id.passwordEdit); 140 loginButtonHttpClient = (Button) findViewById(R.id.login); 141 loginButtonHttpURLConnection= (Button) findViewById(R.id.login1); 142 } 143 }
有任何问题可以加小编微信一起讨论哦:java_squirrel