JAVA学习笔记Day25——动态接口的实现
来源:互联网 发布:影响网络吞吐量的原因 编辑:程序博客网 时间:2024/06/05 16:51
动态接口的实现有很多好处,今天以HTTP协议解析json字符串为例。
基本知识
1、JAVA中我们有时候想要传递一个方法,在C/C++中有方法指针,而在JAVA中,我们可以使用的唯一方法就是接口。所以我们一个接口来传递其中的方法。
2、我们今天是想要从网上获取一个json字符串,然后再用Gson方式去解析得到想要的对象。选择使用动态接口的方式去解决是为了节省代码,不必要在不同的地址去获取json串时还需要去写HTTP协议那一套的连接下载。
2、下载具体步骤
1、首先我们需要建立json串对应的相关对象。在这里,我们需要为每个对象添加注解,因为在fastJson、Gson中不加注解容易混淆。
2、我们是解析这个地址的相关信息。http://www.tngou.net/api/top/list
// TnGou类package net.xiaohong.proxy;import com.google.gson.annotations.SerializedName;import java.util.List;public class TnGou { @SerializedName("status") private boolean status; @SerializedName("total") private int total; @SerializedName("tngou") private List<News> data;// 为了节省空间,大家需要自行解决getter、setter,嘿嘿 }
// News类package net.xiaohong.proxy;import com.google.gson.annotations.SerializedName;import java.util.Calendar;/** * Created HTTP_Work. * By XIAOHONG . * On 2016/8/18. */public class News { @SerializedName("count") private int count; @SerializedName("description") private String description; @SerializedName("fCount") private int fCount; @SerializedName("fromName") private String fromName; @SerializedName("fromURL") private String fromURL; @SerializedName("id") private int id; @SerializedName("img") private String img; @SerializedName("keyWords") private String keyWords; @SerializedName("rCount") private int rCount; // 毫秒值,做转换 @SerializedName("time") @JsonAdapter(CalendarAdapter.class) private Calendar time; @SerializedName("title") private String title; @SerializedName("topClass") private int topClass; // 为了节省空间,大家需要自行解决getter、setter,嘿嘿}
类型适配器,在gson解析中如果拿不到想要的类型,可以对其进行类型适配,比如时间
// 时间类型比配。会返回一个时间类package com.xiaohong.proxy;import com.google.gson.TypeAdapter;import com.google.gson.stream.JsonReader;import com.google.gson.stream.JsonWriter;import java.io.IOException;import java.util.Calendar;public class CalendarAdapter extends TypeAdapter<Calendar> {// 写Calendar ->json @Override public void write(JsonWriter jsonWriter, Calendar calendar) throws IOException { if (calendar == null) { jsonWriter.nullValue(); } else { jsonWriter.value(calendar.getTimeInMillis()); } }// 读,将json->Calendar @Override public Calendar read(JsonReader jsonReader) throws IOException { if (jsonReader.hasNext()) { long l = jsonReader.nextLong(); Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(l); return calendar; } return null; }}
要实现动态接口,需要把自己想要的方法定义在接口中。
package net.xiaohong.proxy;public interface HttpInter { @GET("http://www.tngou.net/api/top/list?page=%d&rows=%d&id=%d") TnGou getList(int page, int rows, int id);}
在这里,我使用到了注解,通过注解来获取想要的方式(GET、POST)
package net.xiaohong.proxy;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface GET { String value();}
往下需要一个工具类去实现动态接口的方式,我们需要将HttpInter 作为参数,通过这个接口拿到这里面的方法,进而,我们再去执行相关的下载操作。
// 动态接口实现类package net.xiaohong.proxy;import com.google.gson.Gson;import java.io.ByteArrayOutputStream;import java.io.InputStream;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.net.HttpURLConnection;import java.net.URL;public class Utils { public static<T> T getInstance(Class<T> type) { Object o = Proxy.newProxyInstance(type.getClassLoader(), new Class[]{type}, new MyHandler()); return (T) o; } private static class MyHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 拿到方法的注解类型,因为在这里我默认就让他使用GET了 GET get = method.getAnnotation(GET.class); // if (get != null) { String url = String.format(get.value(), args); Class<?> type = method.getReturnType(); HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setRequestMethod("GET"); int code = connection.getResponseCode(); if (code == 200) { int length; byte[] buffer = new byte[102400]; InputStream is = connection.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); while ((length = is.read(buffer)) != -1) { baos.write(buffer, 0, length); } Gson gson = new Gson(); return gson.fromJson(baos.toString("UTF-8"), type); } } return null; }}}
// 测试类package net.xiaohong.proxy;import java.util.List;public class HttpTest { public static void main(String[] args) { HttpInter instance = Utils.getInstance(HttpInter.class); TnGou list = instance.getList(1, 5, 0);// News show = instance.getShow(2); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); List<News> data = list.getData(); for (News news : data) { System.out.print(format.format(news.getTime().getTime()) + ": "); System.out.println(news.getTitle()); } }}
运行结果:
到这里整个项目就实现了。这样使用动态接口的好处:我们可以在对不同的地址获取不同的json进行解析成对象。集体方法:
1、我们需要在HttpInter接口中添加我们想要的方法:比如我们想要获取这样的数据:
@GET("http://www.tngou.net/api/top/show?id=%d")
News getShow(long id);
}
此时我们需要在News类中添加一个属性:
@SerializedName("message")
private String message;
测试类中:
News show = instance.getShow(2);
System.out.println(show.getMessage());
运行结果:
- JAVA学习笔记Day25——动态接口的实现
- JAVA学习笔记Day25——HTTP协议
- 传智播客-Java学习笔记day25
- [Java视频笔记]day25
- Java学习笔记——接口的多实现技术
- java学习day25
- java学习day25
- 多线程、工厂模式、GUI+JAVA学习笔记-DAY25
- java 正则表达式——day25
- 黑马程序员_Java基础_我的Day25学习笔记
- day25笔记
- Java学习笔记_22_Set接口的实现类
- 【Java学习笔记】Comparable接口的实现和使用
- 【Java学习笔记】Comparable接口的实现和使用
- JAVA学习笔记(三十八)- 创建实现Runnable接口的线程
- 【Java学习笔记】Comparable接口的实现和使用
- 【Java学习笔记】Comparable接口的实现和使用
- 【Java学习笔记】Comparable接口的实现和使用
- Function执行原理 & 闭包
- jQuery回车触发事件
- Unity不常用方法
- Angular—ng-class
- java基础-反射技术浅析
- JAVA学习笔记Day25——动态接口的实现
- 使用u盘装系统
- Android图像滤镜框架GPUImage从配置到应用
- HDU 1055(贪心)
- 引用Duktape
- mybatis是如何防止SQL注入的
- Unity API(五):鼠标事件
- Roman to Integer
- 设计模式-6.简单工厂模式、工厂模式、抽象工厂模式