Okhttp是一個處理網絡請求的開源項目,是安卓端最火熱的輕量級框架。
接下來我們就來實現一下這個用Okhttp搭建一個android客戶端訪問java服務端的項目。
網上有很多這樣的例子,但都是隻有android客戶端的,這篇文章把服務端代碼也貼一下,這樣有許多同學就可以完全在自己的機器上面部署環境來開發測試了。
首先新建一個anroid studio項目,在依賴庫裏面增加對okhttp庫的引用
compile 'com.squareup.okhttp:okhttp:2.7.5'
然後在AndroidManifest.xml裏面增加權限
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
新建一個Activity,然後在佈局文件裏面增加一個Button,點擊這個Button的時候我們去向服務器發送一個GET請求。關鍵代碼如下:
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String url = "http://192.168.23.1:7111/web02/base";
OkHttpClient client = new OkHttpClient();
final Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
String error = e.getMessage();
}
@Override
public void onResponse(Response response) throws IOException {
if(response.isSuccessful()){
String json = response.body().toString();
InputStream is = response.body().byteStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int readed = 0;
byte buf[] = new byte[1024];
while ((readed = is.read(buf, 0, buf.length)) != -1) {
bos.write(buf, 0, readed);
}
byte[] result = bos.toByteArray();
Log.d("result","result:"+ new String(result));
is.close();
bos.close();
buf=null;
}
}
});
}
});
這裏的url只是我本地測試的url,有的同學會問,我自己本地的url是多少呢?
如果是用同一臺機器上的tomcat部署服務端的,怎麼在自己的機器上部署能讓自己的手機客戶端訪問到。
在用myeclipse發佈一個程序到tomcat上後,用ipconfig命令測試下自己機器的ip。
找到無線局域網的IPV4地址,這裏是192.168.23.1。 端口號如果不知道的,可以去tomcat下面的server.xml裏面查看部署的端口號是多少。我這裏已經查看過了,是7111。
注意,要讓你的手機和你的筆記本保持在一個局域網裏面,你的手機可以訪問這個地址,進而訪問你筆記本上部署的tomcat服務。
所以在客戶端程序代碼裏面url裏面地址配置成http://192.168.23.1:7111/項目名/具體方法名(servlet)";比方說上面的例子,我是寫成String url =
http://192.168.23.1:7111/web02/base;
好了。
客戶端完成後,接下來是服務端的編寫。
服務端很簡單,寫一個簡單的Servlet去接受數據。
package com.example.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*/
public class BaseServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet");
handleRequest(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("dopost");
handleRequest(req,resp);
}
private void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws IOException {
req.setCharacterEncoding("UTF-8"); // 設置字符集
resp.setCharacterEncoding("UTF-8");
resp.setHeader("Cache-Control", "no-store");
PrintWriter out = resp.getWriter(); // 準備輸出
out.println("<html>");
out.println("<head><title>WEB開發</title></head>");
out.println("<body>");
out.println("<h1>Hello World</h1>");
out.println("</body>");
out.println("</html>");
out.close();// 關閉輸出
}
}
BaseServlet當中重寫了 doGet方法和doPost方法,在這裏我把兩種請求方式都做了統一處理。要注意的是,要刪掉原來servlet裏面的super.doGet()方法和super.doPost(),否則在OkHttp的 response.isSuccessful())裏面會返回失敗。爲什麼會這樣呢?我們找到Response類的源代碼
/**
* Returns true if the code is in [200..300), which means the request was
* successfully received, understood, and accepted.
*/
public boolean isSuccessful() {
return code >= 200 && code < 300;
}
哦,其實就是判斷這個code是否等於200.因爲servlet默認的super.doGet()方法裏面返回的code是405,所以這裏面如果保留super.doGet()會出錯。
OK,最後在配置文件web.xml裏面配置剛纔寫的Servelt
<servlet>
<servlet-name>base</servlet-name>
<servlet-class>com.example.servlet.BaseServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>base</servlet-name>
<url-pattern>/base</url-pattern>
</servlet-mapping>
最後測試一下,控制檯打印返回的xml信息,說明連接成功。