Android--Retrofit

本文详细介绍了Retrofit在Android开发中的使用,包括GET和POST请求,参数传递,文件上传,以及如何处理Body注解的请求。同时,提供了服务端相关代码,帮助理解请求的完整流程。

Retrofit的使用

在github搜索retrofit点进去,里面有官网的链接,链接有个Gradle的依赖。嗯,在工程里导入依赖…如果有看Okhttp的依赖那部分,这里应该懂得怎么搞。

在这里插入图片描述

get请求,不带参:


   private static final String PATH = "http://192.168.137.1:8080";

    public void getRequest(View view){
        Retrofit retrofit=new Retrofit.Builder()
                .baseUrl(PATH)
                .build();
        API api=retrofit.create(API.class);
        Call<ResponseBody> task = api.getJson();

        task.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                Log.e(TAG, "onResponse");
                if(response.code()== HttpURLConnection.HTTP_OK){
                    try {
                        Log.e(TAG, response.body().string());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Log.e(TAG, "onFailure");
            }
        });
    }

新建一个接口类:

GET里面参数是服务器的对应工程

public interface API {
    @GET("/cookie_war_exploded/ShopInfoServlet")
    Call<ResponseBody> getJson();
}


当熟悉过后,可以将一些代码写进工具类里面,比如我这里写一点点,配合下面的带参get方法

public class RetrofitManager {
    private static final String PATH = "http://192.168.137.1:8080";


    private static Retrofit retrofit=new Retrofit.Builder()
            .baseUrl(PATH)
            //这里很重点,这一行是转换器,需要去依赖com.squareup.retrofit2:converter-gson,这个再retrofit的官网可以看到。后面还需要添加个版本号。
            //如果没有转换器,就是解析不了json数据,就会报错。
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    public  static Retrofit getRetrofit(){
        return retrofit;
    }
}

然后接下来写一个get带参的,然后数据库返回json数据

 //get方式带参数
    public void getRequestTwo(View view){

        Retrofit retrofit= RetrofitManager.getRetrofit();
        API api=retrofit.create(API.class);
        //注意,这里的泛型是指UesrBean,如果要接收任意数据则用ResponseBody。
        Call<UserBean> task = api.getWithParams("Tom",12);
        task.enqueue(new Callback<UserBean>() {
            @Override
            public void onResponse(Call<UserBean> call, Response<UserBean> response) {
                Log.e(TAG, "onResponse"+response.code());
                if((response.code())== HttpURLConnection.HTTP_OK){
                    try {
                        Log.e(TAG, ""+response.body());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onFailure(Call<UserBean> call, Throwable t) {
                Log.e(TAG, "onFailure");
            }
        });
    }

注解:

public interface API {
    @GET("/untitled2_war_exploded/getServlet")
    Call<UserBean>  getWithParams(@Query("name")String name,@Query("age")int age);
}

服务端代码也写上吧,毕竟我个那个转换器折腾了这么久

public class GetServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	//得到客户端发来的参数
        String name = request.getParameter("name");
        String ageString = request.getParameter("age");
        System.out.println(name);
        System.out.println(ageString);
		//强转成int类型
        int age=Integer.parseInt(ageString);
        //封装成类
        UserBean userBean=new UserBean(name, age);
        //将类变成json字符串
        String s=new Gson().toJson(userBean);
        System.out.println(s);

        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(s);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

Post注解的使用(直接上带参的吧):

 @POST("/untitled2_war_exploded/getServlet")
    Call<UserBean> postParams(@Query("name")String name,@Query("age")int age);

其实和get带参的没什么差别

  public void postParams(View view){
        API api=RetrofitManager.getRetrofit().create(API.class);
        Call<UserBean> task = api.postParams("Sam", 17);
        task.enqueue(new Callback<UserBean>() {
            @Override
            public void onResponse(Call<UserBean> call, Response<UserBean> response) {
                Log.e(TAG, "onResponse" + response.code());
                if ((response.code()) == HttpURLConnection.HTTP_OK) {
                    try {
                        Log.e(TAG, "" + response.body());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            @Override
            public void onFailure(Call<UserBean> call, Throwable t) {
                Log.e(TAG, "onFailure");
            }
        });
    }

接下来就是Url注解,使用的方式也就是参数什么都卸载url里面,看下例子就明白了

注解:

    @POST
    Call<UserBean> postUrl(@Url String url);

    public void postParamsUrl(View view){
        API api=RetrofitManager.getRetrofit().create(API.class);
        String url="/untitled2_war_exploded/getServlet?name=Tom&age=18";
        Call<UserBean> task = api.postUrl(url);
        task.enqueue(new Callback<UserBean>() {
            @Override
            public void onResponse(Call<UserBean> call, Response<UserBean> response) {
                Log.e(TAG, "onResponse" + response.code());
                if ((response.code()) == HttpURLConnection.HTTP_OK) {
                    try {
                        Log.e(TAG, "" + response.body());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            @Override
            public void onFailure(Call<UserBean> call, Throwable t) {
                Log.e(TAG, "onFailure");
            }
        });

    }

Body注解的使用:
注解:

   @POST("/untitled2_war_exploded/getServlet")
    Call<UserBean> getBody(@Body UserBean userBean);

方法:

    public void useBody(View view){
        UserBean userBean=new UserBean("Lisa",52);
        API api=RetrofitManager.getRetrofit().create(API.class);
        Call<UserBean> task = api.getBody(userBean);
        task.enqueue(new Callback<UserBean>() {
            public void onResponse(Call<UserBean> call, Response<UserBean> response) {
                Log.e(TAG, "onResponse" + response.code());
                if ((response.code()) == HttpURLConnection.HTTP_OK) {
                    try {
                        Log.e(TAG, "" + response.body());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            @Override
            public void onFailure(Call<UserBean> call, Throwable t) {
                Log.e(TAG, "onFailure");
            }
        });
    }

服务端:
这里为什么要有服务端代码呢,主要是因为,Body注解是上传一个类的json字符串。也就是得不到里面的参数名称。我之前试了一下,服务端会报错500。所以当返回500时就要注意了,大概率是以为你请求的参数,服务器没有对应的解析代码。

@WebServlet("/getServlet")
public class GetServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        StringBuffer json=new StringBuffer();
        BufferedReader reader=request.getReader();
        String len;
        while((len=reader.readLine())!=null){
            json.append(len);
        }
        System.out.println(json);

        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(String.valueOf(json));
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

文件的上传:

文件的话,在文件管理里面找到对应的工程,直接在files目录下创建一个txt文件,再复制地址就可以了

  public void postFile(View view){
        API api=RetrofitManager.getRetrofit().create(API.class);
        File file=new File("/data/data/com.example.myretrofit/files/123.txt");
        RequestBody body=RequestBody.create(MediaType.parse("text/plain"),file);
        MultipartBody.Part part=MultipartBody.Part.createFormData("file", file.getName(), body);
        Call<ResponseBody> task = api.postFile(part);
        task.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                Log.e(TAG, "onResponse" + response.code());
                if ((response.code()) == HttpURLConnection.HTTP_OK) {
                    try {
                        Log.e(TAG, "" + response.body());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Log.e(TAG, "onFailure");
            }
        });
    }

注解:


    @Multipart
    @POST("/upload_war_exploded/upload")
    Call<ResponseBody> postFile(@Part MultipartBody.Part part);

服务端代码:


@WebServlet("/upload")
public class Upload extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("文件上传过来了");

        //1,先判断上传的数据是否是多段的数据。(只有这个方法返回true时,才是文件上传)
        if(ServletFileUpload.isMultipartContent(request)) {
            //创建FileItemFactory工厂实现类
            FileItemFactory fileitemFactory=new DiskFileItemFactory();
            //创建用于解析上传数据的工具类ServletFileUpload类
            ServletFileUpload servletFileUpload = new ServletFileUpload(fileitemFactory);
            //解析上传的数据,得到每一个表单项FileItem
            try {
                List<FileItem> list = servletFileUpload.parseRequest(request);

                for(FileItem fileItem:list){

                    if(fileItem.isFormField()){
                        //普通表单项
                        System.out.println("表单项属性值:"+fileItem.getFieldName());
                        System.out.println("表单项Value值"+fileItem.getString("UTF-8"));
                    }else {
                        //上传的文件
                        System.out.println("表单项属性值:"+fileItem.getFieldName());
                        System.out.println("上传文件名:"+fileItem.getName());
                        fileItem.write(new File("d:\\"+fileItem.getName()));
                    }
                }

            } catch (Exception e) {
                System.out.println(e.toString());
                e.printStackTrace();
            }
        }

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}


上传多文件:

注解:

    @Multipart
    @POST("/upload_war_exploded/upload")
    Call<ResponseBody> postFiles(@Part List<MultipartBody.Part> parts);

方法:由于有重复的一些代码,所以打包成一个方法,慢慢理解

    public MultipartBody.Part getMultipartBody(String path){
        File file=new File(path);
        RequestBody body=RequestBody.create(MediaType.parse("text/plain"), file);
        MultipartBody.Part part=MultipartBody.Part.createFormData("file", file.getName(), body);
        return part;
    }

    public void postFiles(View view){
        List<MultipartBody.Part> parts=new ArrayList<>();


        MultipartBody.Part part1=getMultipartBody("/data/data/com.example.myretrofit/files/123.txt");
        parts.add(part1);
        MultipartBody.Part part2=getMultipartBody("/data/data/com.example.myretrofit/files/456.txt");
        parts.add(part2);
        Call<ResponseBody> task = api.postFiles(parts);
        task.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                Log.e(TAG, "onResponse" + response.code());
                if ((response.code()) == HttpURLConnection.HTTP_OK) {
                    try {
                        Log.e(TAG, "" + response.body());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Log.e(TAG, "onFailure");
            }
        });

上传文件并携带信息:

方法:

    //上传文件并携带信息
    public void postFileWithParams(View view){
        MultipartBody.Part part=getMultipartBody("/data/data/com.example.myretrofit/files/123.txt");
        Map<String, String> data=new HashMap<>();
        //这里填写中文会报错,不会运行。不知道为什么,估计是编码问题吧
        data.put("asd", "asd");
        Call<ResponseBody> task = api.postFileWithParams(part, data);
        task.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                Log.e(TAG, "onResponse" + response.code());
                if ((response.code()) == HttpURLConnection.HTTP_OK) {
                    try {
                        Log.e(TAG, "" + response.body());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Log.e(TAG, "onFailure");
            }
        });
    }

编码:

    @Multipart
    @POST("/upload_war_exploded/upload")
    Call<ResponseBody> postFileWithParams(@Part MultipartBody.Part part, @PartMap Map<String,String> data);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值