一:服务器端建立
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