题目分析
- 使用装饰器模式,继承自IO接口,来自定义一个输入输出流,以实现给某个类动态的添加功能
- 对于输入流,继承自FilterInputStream,可以从文件中读取并解析JSON字符串,也可以从URL中请求JSON。
- 对于输出流,继承自FilterOutputStream,可以把对象序列化为JSON字符串并写入文件
- 这里就是运用了装饰模式,给原本没有功能的IO接口动态的添加了可以解析JSON的功能
UML图
代码
JSON字符串对应的实体类
@lombok.Data
@AllArgsConstructor
@NoArgsConstructor
public class Data {
private String icon;
private int id;
private String link;
private String name;
private int order;
private int visible;
@Override
public String toString() {
return "Data{" +
"icon='" + icon + '\'' +
", id=" + id +
", link='" + link + '\'' +
", name='" + name + '\'' +
", order=" + order +
", visible=" + visible +
'}' + "\n";
}
}
@lombok.Data
@AllArgsConstructor
@NoArgsConstructor
public class Link {
private List<Data> data;
@JsonProperty("errorCode")
private int errorcode;
@JsonProperty("errorMsg")
private String errormsg;
@Override
public String toString() {
return "Link{" +
"data=" + data +
", errorcode=" + errorcode +
", errormsg='" + errormsg + '\'' +
'}';
}
}
自定义的装饰器流,可以多种方式解析JSON及序列化JSON对象
JSONInputStream
public class JSONInputStream extends FilterInputStream {
public JSONInputStream(InputStream in) {
super(in);
}
public Object read(Class cla) throws IOException {
return new ObjectMapper().readValue(in, cla);
}
public Object read(String url, Class cla) throws IOException {
String jsonStr = new OkHttpClient()
.newCall(new Request
.Builder()
.url(url)
.get()
.build())
.execute()
.body()
.string();
return new ObjectMapper().readValue(jsonStr, cla);
}
@Override
public int read() throws IOException {
return 0;
}
}
JSONOutputStream
public class JSONOutputStream extends FilterOutputStream {
public JSONOutputStream(@NotNull OutputStream out) {
super(out);
}
public void write(Object object) throws IOException {
new ObjectMapper().writeValue(out, object);
}
@Override
public void write(int b) throws IOException {
}
}
测试类
public class Main {
private static final String URL = "https://www.wanandroid.com/friend/json";
public static void main(String[] args) throws IOException {
JSONInputStream jsonInputStream = new JSONInputStream(new FileInputStream(new File("F://info.json")));
Link link = (Link) jsonInputStream.read(Link.class);
System.out.println(link);
JSONOutputStream jsonOutputStream = new JSONOutputStream(new FileOutputStream(new File("F://info.txt")));
jsonOutputStream.write(link);
}
}
总结:
JSON格式:
- 该模式的优缺点,特别从开闭原则论述
- 可以给一个现有的对象添加新的功能,同时又不改变其结构,相比于继承来说更加灵活
- 把职责分配给单一的类,如果想给某个类添加职责,直接去装饰就可以,这样就避免了某个类的功能太多
- 编程中遇到的问题及解决方法