zoukankan      html  css  js  c++  java
  • Rxjava+Retrofit2+Okhttp3多文件上传(服务器端代码+客户端代码)

    所有代码亲测可用,如有问题,欢迎指正。

    首先在ApiService接口文件中新建文件上传接口 

    public interface ApiService {
      static final String BASE_URL=" http://192.168.3.102:8080/";
      /**
         * 上传多头像
         */
        @Multipart
        @POST("wzly/uploadImg") 
      Observable<String> uploadMemberIcon(@Part List<MultipartBody.Part> partList); 
    }

    我使用ServiceFactory.java封装了Retrofit2和OkHttp

    package com.wzly.iscan.tools.api;
    
    import android.util.Log;
    
    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    import java.io.IOException;
    import java.lang.reflect.Field;
    import java.util.Locale;
    import java.util.concurrent.TimeUnit;
    
    import okhttp3.FormBody;
    import okhttp3.Interceptor;
    import okhttp3.MultipartBody;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.Response;
    import retrofit2.Retrofit;
    import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
    import retrofit2.converter.gson.GsonConverterFactory;
    
    
    /**
     * Created by admin on 2016/11/15.
     * 单例模式:每次实例化出来的都是统一个实例。
     */
    
    public class ServiceFactory {
        private final Gson mGsonDateFormat;
    
        public ServiceFactory() {
            mGsonDateFormat = new GsonBuilder()
                    .setDateFormat("yyyy-MM-dd hh:mm:ss")
                    .create();
        }
    
        private static class SingletonHolder {
            private static final ServiceFactory INSTANCE = new ServiceFactory();
        }
    
        public static ServiceFactory getInstance() {
            return SingletonHolder.INSTANCE;
        }
    
        /**
         * create a service
         *
         * @param serviceClass
         * @param <S>
         * @return
         */
        public <S> S createService(Class<S> serviceClass) {
            String baseUrl = "";
            try {
                Field field1 = serviceClass.getField("BASE_URL");
                baseUrl = (String) field1.get(serviceClass);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.getMessage();
                e.printStackTrace();
            }
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .client(getOkHttpClient())
                    .addConverterFactory(GsonConverterFactory.create(mGsonDateFormat))
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();
            return retrofit.create(serviceClass);
        }
    
        private final static long DEFAULT_TIMEOUT = 10;
    
        private OkHttpClient getOkHttpClient() {
            //定制OkHttp
            OkHttpClient.Builder httpClientBuilder = new OkHttpClient
                    .Builder();
            //设置超时时间
            httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
            httpClientBuilder.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
            httpClientBuilder.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
    
            httpClientBuilder.addInterceptor(new RequestInterceptor());
            httpClientBuilder.addInterceptor(new LogInterceptor());
            
            return httpClientBuilder.build();
        }
    
        /**
         * 日志拦截器
         */
        private class LogInterceptor implements Interceptor {
            @Override
            public okhttp3.Response intercept(Chain chain) throws IOException {
                long t1 = System.nanoTime();
                okhttp3.Response response = chain.proceed(chain.request());
                long t2 = System.nanoTime();
                Log.v("zcb", String.format(Locale.getDefault(), "Received response for %s in %.1fms%n%s",
                        response.request().url(), (t2 - t1) / 1e6d, response.headers()));
                okhttp3.MediaType mediaType1 = response.body().contentType();
                String content = response.body().string();
                Log.i("zcb", "response body:" + content);
                return response.newBuilder()
                        .body(okhttp3.ResponseBody.create(mediaType1, content))
                        .build();
            }
        }
    
        /**
         * 请求拦截器,修改请求header
         */
        private class RequestInterceptor implements Interceptor{
    
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request()
                        .newBuilder()
                        .build();
                Log.v("zcb", "request:" + request.toString());
                Log.v("zcb", "request headers:" + request.headers().toString());
    
    
                return chain.proceed(request);
            }
        }
    
    }
    View Code

    此外也用HttpResultSubscriber.java封装了Subscriber,代码如下:

    package com.wzly.iscan.tools.api;
    
    
    import retrofit2.adapter.rxjava.HttpException;
    import rx.Subscriber;
    
    /**
     * Created by zcb
     * Date:2016/7/27
     * Time:21:27
     */
    public abstract class HttpResultSubscriber<T> extends Subscriber<T> {
        
    
    
        @Override
        public void onCompleted() {
    
        }
    
        @Override
        public void onNext(T t) {
                onSuccess(t);
        }
    
        @Override
        public void onError(Throwable e) {
            e.printStackTrace();
            //在这里做全局的错误处理
            if (e instanceof HttpException) {
                // ToastUtils.getInstance().showToast(e.getMessage());
            }
            _onError(e);
        }
    
        public abstract void onSuccess(T t);
    
        public abstract void _onError(Throwable e);
    }
    View Code

    接下来是多文件上传的关键代码:

        public void uploadAvatarImg(String urlpath,String fileName,String sign) {
    
            List<String> imgList=new ArrayList<String>();
            imgList.add(urlpath);
    
            MultipartBody.Builder builder=new MultipartBody.Builder()
                    .setType(MultipartBody.FORM) //表单类型
                    .addFormDataPart("imgfile","avatar.jpg")
                    .addFormDataPart("sign",APPConfig.serverSign);
            //多张图
            for (int i=0;i<imgList.size();i++){
                File file=new File(imgList.get(i));
                RequestBody requestBody=RequestBody.create(MediaType.parse("multipart/form-data"),file);
                builder.addFormDataPart("imgfile"+i,file.getName(),requestBody);//"imgfile"+i 后台接收图片流的参数名
            }
    
            List<MultipartBody.Part> parts=builder.build().parts();
    
            Observable observable=ServiceFactory.getInstance().createService(ApiService.class).uploadMemberIcon(parts);
    
            observable.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new HttpResultSubscriber<UploadImgResult>() {
                        @Override
                        public void onSuccess(UploadImgResult uploadImgResult) {
                            int error_code=uploadImgResult.error_code;
                            String msg=uploadImgResult.msg;
                            String path=uploadImgResult.imgPath;
                            Log.i("zcb","code:"+error_code+"msg:"+msg+"path:"+path);
                            registerView.onUploadAvatarImgResult(msg,error_code,path);
                        }
    
                        @Override
                        public void _onError(Throwable e) {
    
                        }
                    });
        }
    View Code

    最后是后台服务器端测试文件上传用的servlet代码UploadImg.java,

    服务端环境tomcat8.5  jdk1.8 

    查看代码
    package wzly;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.Date;
    import java.util.Iterator;
    import java.util.List;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.fileupload.DiskFileUpload;
    import org.apache.commons.fileupload.FileItem;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    /**
     * Servlet implementation class UploadImg
     */
    @WebServlet("/UploadImg")
    public class UploadImg extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
    
        public UploadImg() {   
        }
        private String fileName="";
        private boolean success=false;
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.getWriter().append("you are using get method    Served at: ").append(request.getContextPath());
        }
    
        //服务器servlet代码
        protected void doPost(HttpServletRequest request, HttpServletResponse response)  
                   throws ServletException, IOException {  
            
                    System.out.println("开始接受文件");
                   String temp=request.getSession().getServletContext().getRealPath("/")+"temp";   //临时目录
                   System.out.println("temp="+temp);
                   String loadpath=request.getSession().getServletContext().getRealPath("/")+"Image"; //上传文件存放目录
                   System.out.println("loadpath="+loadpath);
                   DiskFileUpload fu =new DiskFileUpload();
                   fu.setSizeMax(5*1024*1024);   // 设置允许用户上传文件大小,单位:字节
                   fu.setSizeThreshold(4096);   // 设置最多只允许在内存中存储的数据,单位:字节
                   fu.setRepositoryPath(temp); // 设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录
                  
                   //开始读取上传信息
                   int index=0;
                   List fileItems =null;
                                try {
                                      fileItems = fu.parseRequest(request);
                                      System.out.println("fileItems="+fileItems);
                                     } catch (Exception e) {
                                           e.printStackTrace();
                                    }
                   Iterator iter = fileItems.iterator(); // 依次处理每个上传的文件
                    while (iter.hasNext())
                               {
                                   FileItem item = (FileItem)iter.next();// 忽略其他不是文件域的所有表单信息
                    if (!item.isFormField())
                                   {
                        fileName = item.getName();//获取上传文件名,包括路径
                        fileName=fileName.substring(fileName.lastIndexOf("\")+1);//从全路径中提取文件名
                    long size = item.getSize();
                           if((fileName==null||fileName.equals("")) && size==0)
                                 continue;
                           int point = fileName.indexOf(".");
                           fileName=(new Date()).getTime()+fileName.substring(point,fileName.length());
                           index++;
                           File fNew=new File(loadpath, fileName);
                           try {
                                       item.write(fNew);
                                       success=true;
                                } catch (Exception e) {
                                       // TODO Auto-generated catch block
                                    success=false;
                                       e.printStackTrace();
                                 }
                       }
                       else//取出不是文件域的所有表单信息
                       {    String fieldName=item.getFieldName();
                           String fieldvalue = item.getString();
                    //如果包含中文应写为:(转为UTF-8编码)
                           System.out.println(fieldName);
                           System.out.println(fieldvalue);
    //                       String fieldvalue = new String(item.getString().getBytes(),"UTF-8");
                       }
                   }
       
                    JSONObject json=new JSONObject();
                    try {
                    if(success){
                        String imgPath="image/"+fileName.substring(0, fileName.length());
                       
                        json.put("error_code", 1);
                        json.put("msg", "upload success");
                        json.put("imgPath", imgPath);
                        
                    }else{
                        json.put("error_code", 0);
                        json.put("msg", "upload fail");
                        json.put("imgPath", "");
                    }
                   } catch (JSONException e) {
                            e.printStackTrace();
                        }
                   
                    response.getWriter().append(json.toString());
    //               response.sendRedirect("result.jsp?imgPath="+ json.toString());
            }
        
    
    }
  • 相关阅读:
    JAVA学习笔记(十二)
    JAVA学习笔记(十)
    JAVA学习笔记(九)
    JAVA学习笔记(八)
    JAVA学习笔记(七)
    JAVA学习笔记(六)
    JAVA学习笔记(五)
    20180313 mysql
    20180306 事件监听的方法 添加事件监听和取消事件监听 轮播图
    20180302DOM通过节点关系获取元素 表单元素 下拉列表 网页换肤 操作表格 问候
  • 原文地址:https://www.cnblogs.com/zhang-cb/p/6225062.html
Copyright © 2011-2022 走看看