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

被折叠的 条评论
为什么被折叠?



