一:服務器端建立
1:下載Tomcat 以及 struts(框架:爲了解決文件上傳更簡潔),後面會提供兩個資源的下載鏈接。然後解壓下載好的Tomcat和struts
2:配置tomcat:打開Myeclipse,打開window->perferences查找tomcat,然後將地址映射到上面解壓的Tomcat包。不知道是不是我的電腦配置出現問題,導致我在perferences中沒有查找到tomcat屬性。所以我在創建WEB project中發現了配置Tomcat路徑的地方,可參考1-5圖片,完成tomcat配置。創建的WEB工程如6圖
3:引入strust包:
3.1:找到解壓後的struts2-blank.war包,將這個包在進行解壓,找到WEB-INF文件夾,將WEB-INF裏lib包內的架包拷貝到工程對應lib目錄下。
3.2:將WEB-INF\classes下的struts.xml拷貝到工程的src目錄下,裏面的代碼參考7圖
3.3:打開WEB-INF 中webxml文件,將以下代碼
<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文件
3.4:配置好之後,選擇run as ,將之前配置的Tomcat作爲service服務開啓。
4:新建一個包:com.imook.action,然後新建一個類UserAction,然後服務器端所有的代碼如下:
package com.imook.action;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Logger;
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 com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport{
private String username;
private String password;
public File mPhoto;
public String mPhotoFileName;
//上傳字符串到服務器
public String postString() throws IOException{
HttpServletRequest request = ServletActionContext.getRequest();
ServletInputStream is = request.getInputStream();
System.out.println("sessionId=" + request.getSession().getId());
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;
}
//重命名圖片以及username及password
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,"wwx.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);
}
HttpServletResponse response = ServletActionContext.getResponse();
PrintWriter writer = response.getWriter();
writer.write(dir);
writer.flush();
System.out.println("dir:"+dir);
fos.flush();
fos.close();
return null;
}
//登陸
public String login() throws IOException{
HttpServletRequest request = ServletActionContext.getRequest();
//userService.login(username,password);
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;
}
}
5:對應的struts代碼:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="login" class="com.imook.action.UserAction" method = "login">
</action>
<action name="postString" class="com.imook.action.UserAction" method = "postString">
</action>
<action name="postFile" class="com.imook.action.UserAction" method = "postFile">
</action>
<action name="uploadInfo" class="com.imook.action.UserAction" method = "uploadInfo">
</action>
</package>
<!-- Add packages here -->
</struts>
二:客戶端
客戶端就是創建一個Android 工程,具體的請參考代碼:
1:MainActivity代碼:
package nuro.nuro.okhttp;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
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.FormEncodingBuilder;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.MultipartBuilder;
import com.squareup.okhttp.OkHttpClient;
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 {
private TextView tv_result;
private ImageView iv_result;
OkHttpClient okHttpClient = new OkHttpClient();
private String mBaseUrl="http://192.168.1.113:8080/imook_okHttp/";
private String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
okHttpClient.setCookieHandler(new CookieManager(null, CookiePolicy.ACCEPT_ALL));//保證服務器端的sessionId保證一致,保證用戶登錄一致
tv_result = (TextView) findViewById(R.id.tv_result);
iv_result = (ImageView)findViewById(R.id.iv_result);
}
/*
封裝代碼步驟
* 1:拿到okHttpClient對象
* 2:構造Request
2.1構造requestBody
2.2包裝requestBody
3.call -> execute
* */
public void doPost(View view){
//1:拿到okHttpClient對象
FormEncodingBuilder requestBodyBuilder = new FormEncodingBuilder();
//2:構造Request
//2.1構造requestBody
RequestBody requestBody = requestBodyBuilder.add("username","wwx").add("password","930820").build();
Request.Builder builder = new Request.Builder();
Request request = builder.url(mBaseUrl + "login").post(requestBody).build();
executeRequest(request);
}
public void doPostString(View view){
//1:拿到okHttpClient對
//2:構造Request
//2.1構造requestBody
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain:charset=utf-8"), "{username:wwx,password:930820,sex:man,age:25}");
Request.Builder builder = new Request.Builder();
Request request = builder.url(mBaseUrl + "postString").post(requestBody).build();
executeRequest(request);
}
public void doPostFile(View view){
File file = new File(Environment.getExternalStorageDirectory(),"wwx.jpg");
Log.i(TAG,Environment.getExternalStorageState());
if (!file.exists()){
L.e(file.getAbsolutePath()+" not exist!");
return;
}
//mime type查看各個文件的MediaType
RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"),file);
Request.Builder builder = new Request.Builder();
Request request = builder.url(mBaseUrl + "postFile").post(requestBody).build();
executeRequest(request);
}
public void doUpload(View view){
File file = new File(Environment.getExternalStorageDirectory(),"ziji.png");
Log.i(TAG,Environment.getExternalStorageState());
if (!file.exists()){
L.e(file.getAbsolutePath()+" not exist!");
return;
}
MultipartBuilder multipartBuilder = new MultipartBuilder();
RequestBody requestBody = multipartBuilder.type(MultipartBuilder.FORM)//
.addFormDataPart("username", "wwx")//
.addFormDataPart("password", "930820")//
.addFormDataPart("mPhoto", "jizi.png", RequestBody.create(MediaType.parse("application/octet-stream"), file))
.build();
CountingRequestbody countingRequestbody = new CountingRequestbody(requestBody, new CountingRequestbody.Listner() {
@Override
public void onRequestProgress(long bytesWrited, long contentLength) {
L.e(bytesWrited + "/" + contentLength);
}
});
//mime type查看各個文件的MediaType
Request.Builder builder = new Request.Builder();
Request request = builder.url(mBaseUrl + "uploadInfo").post(countingRequestbody).build();
executeRequest(request);
}
public void doDownload(View view){
Request.Builder builder = new Request.Builder();
Request request = builder.get().url(mBaseUrl+"files/wwx.jpg").build();
Call call = okHttpClient.newCall(request);
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(), "wwx12306.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() {
tv_result.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 request = builder.get().url(mBaseUrl+"files/jizi.png").build();
Call call = okHttpClient.newCall(request);
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() {
iv_result.setImageBitmap(bitmap);
}
});
}
});
}
public void doGet(View view) throws IOException {
//1:拿到okHttpClient對象
//2:構造Request
Request.Builder builder = new Request.Builder();
Request request = builder.get().url(mBaseUrl+"login?username=wwx&password=654321").build();
executeRequest(request);
}
private void executeRequest(Request request) {
//3:將request封裝成call
Call call = okHttpClient.newCall(request);
//4:執行
//call.execute();//立即執行
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);//此時是子線程,不能直接設置UI控件更新的原因可能是爲了支持大文件的下載
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_result.setText(res);
}
});
}
});
}
}
2:xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
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"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="nuro.nuro.okhttp.MainActivity"
tools:showIn="@layout/activity_main">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get"
android:onClick="doGet"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="post"
android:onClick="doPost"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="post String"
android:onClick="doPostString"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="post File"
android:onClick="doPostFile"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Upload"
android:onClick="doUpload"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Download"
android:onClick="doDownload"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DownloadImage"
android:onClick="doDownloadImg"/>
<TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!" />
<ImageView
android:id="@+id/iv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"/>
</LinearLayout>
3:封裝的一個打印信息L代碼:
package nuro.nuro.okhttp;
/**
* Created by Administrator on 2017/8/1.
*/
public class L{
private static boolean debug = true;
private static String TAG = "imook_okhttp";
public static void e(String msg){
if (debug){
android.util.Log.e(TAG,msg);
}
}
}
4:在MainFest中記得添加相應的權限:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
三:總結:
這個例子介紹了服務器的簡單搭建,做到了Android客戶端上傳string(也可以是json格式),圖片、文件到服務器的指定目錄下,然後提供了從服務器上下載圖片文件的方法。
其中在:
1:客戶端上傳圖片到服務器中,因爲映射到服務器的地址不對,導致客戶端上傳的圖片,服務器一直沒有接收到。產生這個的原因是:沒有將Tomcat映射的路徑配置正確。正確的方式是要在新建web工程後配置Tomcat的路徑。
2:另外一個是比較大的圖片不能顯示,原因:代碼裏沒有增加壓縮圖片的步驟,部分圖片過大顯示不出來。
3:上傳以及下載的進度可以在進行完善,使用進度條來顯示。
各位:有不明白的或者有錯誤的地方,大家請指教。QQ:1143403680