一、OkHttp 简介
1.1 OKhttp的优势:
(1)允许连接到同一个主机地址的所有请求,提高请求效率
(2)共享Socket,减少对服务器的请求次数
(3)通过连接池,减少了请求延迟
(4)缓存响应数据来减少重复的网络请求
(5)减少了对数据流量的消耗
(6)自动处理GZip压缩
1.2 OKhttp的功能:
(1)get,post请求[3]
(2)文件的上传下载[3]
(3)加载图片(内部会图片大小自动压缩)[3]
(4)支持请求回调,直接返回对象、对象集合[3]
(5)支持session的保持[3]
二、客户端
2.1 打开AndroidStudio ,新建工程sample
2.2 打开
build.gradle(Module:sample),添加以下语句:compile ‘com.squareup.okhttp:okhttp:2.6.0’。然后点击“Sync Now”。详细代码如下:
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.example.sample"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
task clean(type:Delete){
delete rootProject.buildDir
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.2.0'
compile 'com.squareup.okhttp:okhttp:2.6.0'
testCompile 'junit:junit:4.12'
}
2.3 打开AndroidManifest.xml,添加权限
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
2.4 配置布局文件activity_main.xml,添加相应的按钮以及TextView、ImageView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
android:layout_width="match_parent" android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.sample.MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doGet"
android:text="Get"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doPost"
android:text="Post"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doPostString"
android:text="Post String"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doPostFile"
android:text="Post File"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doUpload"
android:text="Upload"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doDownload"
android:text="Download"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doDownloadImg"
android:text="Download Img"/>
<TextView
android:id="@+id/id_tv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!" />
<ImageView
android:id="@+id/id_iv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
2.5 L.java:调试窗口显示信息
package com.example.sample;
import android.util.Log;
/**
* Created by rxzero on 17-4-4.
*/
public class L {
private static final String TAG="Imooc_okhttp";
private static boolean debug=true;
public static void e(String msg){
if(debug)
Log.e(TAG,msg);
}
}
2.6 封装ContingRequestBody.java
package com.example.sample;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.RequestBody;
import java.io.IOException;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;
/**
* Created by rxzero on 17-4-20.
*/
public class CountingRequestBody extends RequestBody{
protected RequestBody delegate;
private Listener listener;
private ContingSink contingSink;
public CountingRequestBody (RequestBody delegate,Listener listener) {
this.delegate=delegate;
this.listener=listener;
}
@Override
public MediaType contentType() {
return delegate.contentType();
}
@Override
public long contentLength() {
try {
return delegate.contentLength();
} catch (IOException e) {
return -1;
}
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
contingSink=new ContingSink(sink);
BufferedSink bufferedSink= Okio.buffer(contingSink);
delegate.writeTo(bufferedSink);
bufferedSink.flush();//刷新
}
protected final class ContingSink extends ForwardingSink{
private long bytesWritten;
public ContingSink(Sink delegate) {
super(delegate);
}
@Override
public void write(Buffer source, long byteCount) throws IOException {
super.write(source, byteCount);
bytesWritten+=byteCount;
listener.onRequestProgress(bytesWritten,contentLength());
}
}
public static interface Listener{
void onRequestProgress(long byteWrited,long contentLength);
}
}
2.7 MainActivity.java
package com.example.sample;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.MultipartBuilder;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.CookieManager;
import java.net.CookiePolicy;
public class MainActivity extends AppCompatActivity {
OkHttpClient okHttpClient=new OkHttpClient();//拿到okhttpClient对象
private TextView mTvResult;
private ImageView mIvResult;
private String mBaseUrl="http://139.199.209.189:8080/Imooc_http/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
okHttpClient.setCookieHandler(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
mTvResult= (TextView) findViewById(R.id.id_tv_result);
mIvResult= (ImageView) findViewById(R.id.id_iv_result);
}
public void doDownload(View view){
Request.Builder builder=new Request.Builder();//构造Request
final Request request=builder
.get()
.url(mBaseUrl+"files/hyman.jpg")
.build();
Call call=okHttpClient.newCall(request);//将Request封装为Call
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
L.e("onFailure"+e.getMessage());
e.printStackTrace();
}
@Override
public void onResponse(Response response) throws IOException {
L.e("onResponse:");
final long total=response.body().contentLength();//文件总长度
long sum=0L;
InputStream is = response.body().byteStream();
int len=0;
File file=new File(Environment.getExternalStorageDirectory(),"hyman123.jpg");
byte[] buf=new byte[128];
FileOutputStream fos=new FileOutputStream(file);
while((len=is.read(buf))!=-1){
fos.write(buf,0,len);
sum+=len;
L.e(sum+"/"+total);
final long finalSum=sum;
runOnUiThread(new Runnable() {
@Override
public void run() {
mTvResult.setText(finalSum+"/"+total);
}
});
}
fos.flush();
fos.close();
is.close();
L.e("download success!");
}
});
}
public void doDownloadImg(View view){
Request.Builder builder=new Request.Builder();//构造Request
final Request request=builder
.get()
.url(mBaseUrl+"files/hyman.jpg")
.build();
Call call=okHttpClient.newCall(request);//将Request封装为Call
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
L.e("onFailure"+e.getMessage());
e.printStackTrace();
}
@Override
public void onResponse(Response response) throws IOException {
L.e("onResponse:");
InputStream is = response.body().byteStream();
final Bitmap bitmap=BitmapFactory.decodeStream(is);
runOnUiThread(new Runnable() {
@Override
public void run() {
mIvResult.setImageBitmap(bitmap);
}
});
}
});
}
public void doUpload(View view){
File file = new File(Environment.getExternalStorageDirectory(),"banner2.jpg");
if(!file.exists()){
L.e(file.getAbsolutePath()+"no exist!");
return;
}
MultipartBuilder multipartBuilder=new MultipartBuilder();
RequestBody requestBody=multipartBuilder.type(multipartBuilder.FORM)
.addFormDataPart("username","hyman").addFormDataPart("password","321")
.addFormDataPart("mPhoto","hyman.jpg",RequestBody.create(MediaType.parse("application/octet-stream"),file))
.build();
CountingRequestBody countingRequestBody=new CountingRequestBody(requestBody, new CountingRequestBody.Listener() {
@Override
public void onRequestProgress(long bytesWritten, long contentLength) {
L.e(bytesWritten+"/"+contentLength);
}
});
Request.Builder builder=new Request.Builder();
Request request=builder.url(mBaseUrl+"uploadInfo").post(countingRequestBody).build();
executeRequest(request);
}
public void doPost(View view){
FormEncodingBuilder requestBodyBuilder=new FormEncodingBuilder();
RequestBody requestBody=requestBodyBuilder.add("username","hyman").add("password","5678").build();
Request.Builder builder=new Request.Builder();//构造Request
Request request=builder.url(mBaseUrl+"login").post(requestBody).build();
executeRequest(request);
}
public void doPostString(View view){
RequestBody requestBody=RequestBody.create(MediaType.parse("text/plain;chaset=utf-8"),"{username:hyman,password:123}");
Request.Builder builder=new Request.Builder();//构造Request
Request request=builder.url(mBaseUrl+"postString").post(requestBody).build();
executeRequest(request);
}
public void doPostFile(View view){
File file=new File(Environment.getExternalStorageDirectory(),"banner2.jpg");
if(!file.exists()){
L.e(file.getAbsolutePath()+"not exit!");
return;
}
RequestBody requestBody=RequestBody.create(MediaType.parse("application/octet-stream"),file);
Request.Builder builder=new Request.Builder();//构造Request
Request request=builder.url(mBaseUrl+"postFile").post(requestBody).build();
executeRequest(request);
}
public void doGet(View view){
Request.Builder builder=new Request.Builder();//构造Request
final Request request=builder
.get()
.url(mBaseUrl+"login?username=hyman&password=1234")
.build();
executeRequest(request);
}
private void executeRequest(Request request) {
Call call=okHttpClient.newCall(request);//将Request封装为Call
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
L.e("onFailure"+e.getMessage());
e.printStackTrace();
}
@Override
public void onResponse(Response response) throws IOException {
L.e("onResponse:");
final String res=response.body().string();
L.e(res);
runOnUiThread(new Runnable() {
@Override
public void run() {
mTvResult.setText(res);
}
});
}
});
}
}
三、服务器
3.1 下载struts-2.2.32,搭建开发环境,新建工Myeclipse程Imooc_http,将struts-2.2.32下apps/WEB-INF/lib下的所有文件复制到WEB-INF/lib
将apps/WEB-INF/classes/struts文件放在工程src目录下
将apps/WEB-INF/web文件里以下代码放在工程WEB-INF/web.xml文件下
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
完成后的web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Imooc_http</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
项目工程目录:
3.2
新建UserAction.java
package com.imoov.action;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import org.omg.PortableServer.Servant;
import org.omg.PortableServer.ServantActivator;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport{
private String username;
private String password;
public File mPhoto;
public String mPhotoFileName;
public String uploadInfo() throws IOException {
System.out.println(username+","+password);
if(mPhoto==null){
System.out.println(mPhotoFileName+"is null.");
}
String dir=ServletActionContext.getServletContext().getRealPath("files");
File file=new File(dir,mPhotoFileName);
FileUtils.copyFile(mPhoto, file);
return null;
}
public String postFile() throws IOException {
HttpServletRequest request=ServletActionContext.getRequest();
ServletInputStream is = request.getInputStream();
System.out.println("sessionId="+request.getSession().getId());
String dir = ServletActionContext.getServletContext().getRealPath("files");
File file=new File(dir,"banner2.jpg");
FileOutputStream fos=new FileOutputStream(file);
int len=0;
byte[] buf=new byte[1024];
while((len=is.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.flush();
fos.close();
return null;
}
public String postString() throws IOException{
HttpServletRequest request=ServletActionContext.getRequest();
System.out.println("sessionId="+request.getSession().getId());
ServletInputStream is=request.getInputStream();
StringBuilder sb = new StringBuilder();
int len=0;
byte[] buf=new byte[1024];
while((len=is.read(buf))!=-1){
sb.append(new String(buf,0,len));
}
System.out.println(sb.toString());
return null;
}
public String login() throws IOException {
HttpServletRequest request=ServletActionContext.getRequest();
System.out.println("sessionId="+request.getSession().getId());
System.out.println(username+","+password);
HttpServletResponse response=ServletActionContext.getResponse();
PrintWriter writer=response.getWriter();
writer.write("login success!");
writer.flush();
return null;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}