標籤:pretty 數組 androi cti parser name cat line set
官方文檔:http://square.github.io/retrofit/
下列操作,是在Retrofit環境配置好的情況下進行的。
tjstudy:寫在前面,開發環境
app環境:
android studio 2.1.1
minSdkVersion 14
targetSdkVersion 23
javaweb server 環境:
MyEclipse 10
jdk 1.6
一 、最基本的標記
@GET @POST 標記:網路訪問方式的最基本標記
指定訪問方式,一般會寫入訪問地址,如果是擷取的資料,還可以進行排序。
建議:base_url,最好以/結尾 @GET @POST裡面的地址不以/開頭。
@GET("users/list ")@POST("users/list?dort=asc")
二 、POST 和GET方式,通用retorfit 標記
POST GET 通用:@Path @Query @QueryMap @Header
兩者通用的標記:主要是指使用使用@POST 和@GET方式都能夠接收到資料資訊,顯示效果差不多,實際開發中,根據要求使用的網路方式來進行選擇。
下面示範的效果大多為@GET,POST方式直接將GET 換成POST 查看了即可。
1 、 @Path:指定訪問路徑
@GET("{name}/UploadParam")Observable<ResponseBody> test(@Path("name")String name);
動態傳入的String 會取代{name}作為新的訪問地址
這個時候訪問的地址就是,base_url+name+/UploadParam
2 、@Query :提交參數—-不是表單提交,只是普通提交
@GET("servlet/UploadParam")Observable<ResponseBody> testQuery(@Query("name") String name);
伺服器結果:
3 、@QueryMap:是@Query的集合形式,能夠攜帶更多的參數
@GET("group/{id}/users")Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
只需要將要攜帶的參數都put到Map集合裡面,傳進來就可以了。
4 、@Header :在網路訪問中添加Header資訊
@Headers({ "appkey:tjstudy _ 2016 10 23"})@GET("servlet/HeaderTest")Observable<ResponseBody> testHeader(@Query("name") String name);
伺服器結果:
@Header 也可以直接放到實際請求參數中,效果和上面一致
@GET("servlet/HeaderTest")Observable<ResponseBody> testHeader(@Header(“appkey”) String appkey,@Query("name") String name);
三、必須POST方式(@body @FormUrlEncoded @Multipart)
使用GET方式 + 上面的任意標記 都會報錯。並且這三個標記不能混合使用,否則會報錯。
1、@Body:上傳一個對象
@POST("servlet/TestBody")Observable<ResponseBody> testBody( @Body User user);
伺服器結果:
是否可以上傳兩個對象?
在上述代碼中添加了另一個User,直接報錯…..貌似只能上傳一個對象
2、@FormUrlEncoded:表單提交 和@Field 配對,訪問過程中,參數中至少有一個@Field
@FormUrlEncoded@POST("servlet/TestFormUrlEncodes")Observable<ResponseBody> testFormUrlEncoded( @Field("param1") String first, @Field("param2") String last);
伺服器結果:
注:@FormUrlEncoded 標記的方法中,至少要有一個參數是@Field 標記的參數,否則會報錯。人家是配對的,別拆散他們。其他的參數可以是其他的標記,例如:@Query (雖然沒必要,但是至少這種情況不會報錯)。
3、@Multipart:檔案等上傳 和@Part 配對 訪問過程中,參數中至少有一個@Part
RequestBody 可以封裝什麼樣的類型,@Multipart就能將這樣類型的資料上傳到伺服器。RequestBody可以封裝文本,圖片檔案,音頻檔案等。
這裡列舉的是圖片檔案
伺服器怎麼接收檔案,這裡使用fileupload 來接收(需要引入fileupload相關包commons-fileupload-1.3和commons-io-1.2 可在代碼中找到)。主要代碼:
PrintWriter pw = response.getWriter(); // 建立檔案項目工廠對象 DiskFileItemFactory factory = new DiskFileItemFactory(); // 設定檔案上傳路徑 File uploadDir = new File(this.getServletContext().getRealPath( "/upload/"));// 設定檔案上傳的路徑為項目名/upload/ System.out.println("檔案上傳的路徑=" + uploadDir); if (!uploadDir.exists()) {// 如果改檔案夾不存在就建立 uploadDir.mkdirs(); } // 擷取系統預設的臨時檔案儲存路徑,該路徑為Tomcat根目錄下的temp檔案夾 String temp = System.getProperty("java.io.tmpdir"); // 設定緩衝區大小為 5M factory.setSizeThreshold(1024 * 1024 * 5); // 設定臨時檔案夾為temp factory.setRepository(new File(temp)); // 用工廠執行個體化上傳組件,ServletFileUpload 用來解析檔案上傳請求 ServletFileUpload servletFileUpload = new ServletFileUpload(factory); try { List<FileItem> list = servletFileUpload.parseRequest(request); System.out.println("檔案的個數=" + list); for (FileItem fileItem : list) { if(fileItem==null){ System.out.println("擷取到的檔案是空的"); break; } File file = new File(uploadDir, fileItem.getFieldName()+".png"); if (!file.exists()) {// 檔案不存在才建立 fileItem.write(file);// 儲存檔案 System.out.println("檔案名稱:" + file.getName()); } } pw.write("{\"message\":\"上傳成功\"}"); System.out.println("{\"message\":\"上傳成功\"}"); } catch (Exception e) { pw.write("{\"message\":\"上傳失敗\"}"); System.out.println("{\"message\":\"上傳失敗\"}"); }
1)、@Mutipart + RequestBody上傳單檔案
File imageFile = new File(Environment.getExternalStorageDirectory().getPath(),"123.png");RequestBody imageRequestBody = RequestBody.create(MediaType.parse("image/png"), imageFile);
@Multipart@POST("servlet/TestMultipart")Observable<ResponseBody> testSingleMultipart( @Part("photo") RequestBody image);
伺服器結果:
2)、@Mutipart + RequestBody上傳單檔案 和參數
由於這裡上傳的檔案和接收的路徑都是一樣的,在新操作之前,需要先把已經上傳的檔案刪除。
@Multipart@POST("servlet/TestSingleMultipartParam")Observable<ResponseBody> testSingleMultipartParam( @Part("photo") RequestBody image, @Query("des") String des);
不能使用@FormUrlEncoded提交參數,使用會報錯。
伺服器結果:
3)、@Mutipart + RequestBody上傳多檔案和參數
@Multipart@POST("servlet/TestMultipartMoreFile")Observable<ResponseBody> testMoreMultipartParam( @Part("photo1") RequestBody image1, @Part("photo2") RequestBody image2, @Query("des") String des);
源檔案只是一張圖片
伺服器結果:
4)、@PartMap 上傳檔案和參數
@Multipart@POST("servlet/TestPostMultipartBodyPart")Observable<ResponseBody> testMultipartBodyMap( @Query("des") String des, @PartMap Map<String, RequestBody> images);
伺服器結果:
5)、@Multipart 檔案上傳的另外一種方式——MultipartBody.Part
注意:MultipartBody是okhttp3的一個方法,在okhttp2裡面不存在。這裡使用的是Retrofit2 所以內建的是Okhttp3。
它和RequestBody的關係:
File file = new File(Environment.getExternalStorageDirectory() .getAbsolutePath() + "123.png");RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), file);//參數1 數組名,參數2 檔案名稱。MultipartBody.Part photo1part = MultipartBody.Part.createFormData("pic1", "pic2", requestBody1);
MultipartBody.part 其實就是對RequestBody的封裝
@Multipart@POST("servlet/TestPostMultipartBodyPart")Observable<ResponseBody> testMultipartBody( @Part("photo1") RequestBody image1, @Part MultipartBody.Part image2, @Query("des")String des);
這裡使用的是兩種上傳方式
伺服器結果:
疑惑:明明直接使用ResponseBody 就能完成檔案上傳,為什麼還要使用MultipartBody.part? 根據目前接觸的網路訪問操作,疑惑未解決。
//todo 為什麼呢?
另外:怎麼下載檔案?操作比較簡單
下載檔案主要是對流的操作,伺服器將流寫入到ResponseBody裡面返回到用戶端就好了。用戶端擷取到流,然後進行操作。
四、完整demo
app
demo:
http://download.csdn.net/detail/u012391876/9662557
【網路】app(retorfit2+RxJava)+javaweb(伺服器) retrofit2官方文檔實踐