JSON解析之Gson
1.Gson简介
Gson是一个将Java对象转为JSON表示的开源类库,由Google提供,并且也可以讲JSON字符串转为对应的Java对象。虽然有一些其他的开源项目也支持将Java对象转为JSON,可是有些需要把Java注解加到你的代码中,可是如果你不阅读源代码你是不清楚的,而且有些也不是完全支持泛型的。而GSON在设计的时候把这两点都考虑在内了。GSON的目的就是:
提供简单的toJson()和fromJson()方法将Java对象转为JSON, 反之亦然
允许已存在的无法改变的类转换成JSON或者是从JSON转为
大量的支持了Java泛型
允许为对象定制表示方式
支持任意复杂的对象
2.引入相关jar包
最新版本是2.3,这个相应的jar包可以从maven中央仓库获取,下载链接(http://search.maven.org/remotecontent?filepath=com/google/code/gson/gson/2.3/gson-2.3.jar),不过如果不是通过直接添加jar包的方式获取的话可以通过maven或者是gradle,如果是通过maven,需要在pom.xml文件中加上环境配置
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3</version>
</dependency>
如果是通过gradle那么只需要配置
'com.google.code.gson:gson:2.3'
3.具体的实现
a):将json转为Java对象
Google json提供了两种方式来实现,第一种就是用 com.google.gson.Gson类,创建一个这个类的实例然后通过使用方法fromJson(String json, Class<T> classOfT),classOfT 是JSON将要转为的java对象。第二种方式就是使用 com.google.gson.GsonBuilder 类,这个类允许设置一些特定的功能比如允许空序列化,创建一个GsonBuilder,然后设置完通过builder操作Gson类。
我们先来看下简单的GSON使用方法,操作的对象实体是Albums.java
public class Albums { private String title;
private String message;
private String[] errors = new String[]{};
private String total;
private int total_pages;
private int page;
private String limit; public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String[] getErrors() {
return errors;
}
public void setErrors(String[] errors) {
this.errors = errors;
}
public String getTotal() {
return total;
}
public void setTotal(String total) {
this.total = total;
}
public int getTotal_pages() {
return total_pages;
}
public void setTotal_pages(int total_pages) {
this.total_pages = total_pages;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public String getLimit() {
return limit;
}
public void setLimit(String limit) {
this.limit = limit;
} }
(需要注意的是errors在为实例化的时候已经赋值了为空值,这个后面有用
通过GSON操作JavaToJsonAndBack.java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder; public class JavaToJsonAndBack { /**
* @param args
*/
public static void main(String[] args) { GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create(); // TODO Auto-generated method stub
Albums albums = new Albums();
albums.setTitle("Free Music Archive - Albums");
albums.setMessage("");
albums.setTitle("11259");
albums.setTotal_pages(2252);
albums.setPage(1);
albums.setLimit("5");
System.out.println("Albums");
System.out.println(gson.toJson(albums)); } }
Albums
{"title":"11259","message":"","errors":[],"total_pages":2252,"page":1,"limit":"5"}
我们注意到的是errors属性打印出来为空但是出现了,现在我们做个小小的改动就是将pojo中Albums中的errors初始化值删掉然后再次运行main方法看打印出来的结果是什么
private String[] errors; Albums
{"title":"11259","message":"","total_pages":2252,"page":1,"limit":"5"}
我们却发现没有errors这个属性了这个是为什么呢,这个是因为我们在实例化的时候没有给errors赋初值,所以未能实现序列化所以没有值,那么我们有什么办法可以讲errors这个属性即使是空值也能够打印出来呢,方法是有的那就是通过GsonBuilder
来定制,我们设置即使为空也是序列化的.我们将JavaToJsonAndBack.java做个简单修改
import com.google.gson.Gson;
import com.google.gson.GsonBuilder; public class JavaToJsonAndBack { /**
* @param args
*/
public static void main(String[] args) { GsonBuilder builder = new GsonBuilder().serializeNulls();
Gson gson = builder.create(); // TODO Auto-generated method stub
Albums albums = new Albums();
albums.setTitle("Free Music Archive - Albums");
albums.setMessage("");
albums.setTitle("11259");
albums.setTotal_pages(2252);
albums.setPage(1);
albums.setLimit("5");
System.out.println("Albums");
System.out.println(gson.toJson(albums)); } }
打印出来的结果是
Albums
{"title":"11259","message":"","errors":null,"total":null,"total_pages":2252,"page":1,"limit":"5"}
可见errors属性出来了,打出来为空
这个还可以通过注解的方式实现@SerializedName
(
""
),还可以通过制定NamingStrategy
builder.setFieldNamingStrategy(new FieldNamingStrategy() { @Override
public String translateName(Field f) {
if (f.getName().equals("albumId"))
return "album_id";
else
return f.getName();
}
});
b):标记解析
通过a我们知道了如果将一个Java对象转为JSON的两种方式,下面介绍下如何解析JSON已经处理特殊的符号,尽管通过JSON构建Java对象看起来是一个很难完成的,但是如果你需要较高级别的去控制这个转化过程的话,它还是很强大的而且是个不错的选择。这个是具有我们通过JsonReader去读取JSON流,下面是一个举例。ParseTokenExample.java
import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.commons.io.IOUtils;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
public class ParseTokenExample{
public static void main(String[] args) throws MalformedURLException, IOException {
String url = "http://freemusicarchive.org/api/get/albums.json?api_key=60BLHNQCAOUFPIBZ&limit=5";
String json = IOUtils.toString(new URL(url));
//使用reader去读取json JsonReader reader = new JsonReader(new StringReader(json));
//调用处理对象的方法去处理完整的json对象
handleObject(reader);
}
/**
*处理对象,假设第一个标记是BEGIN_OBJECT,在对象内部即有可能是数组也有可能不是,我们需要处理这
*两种情况,需要注意peek()方法,它用于通常用于找出下个标记的类型
* @param reader
* @throws IOException
*/private static void handleObject(JsonReader reader) throws IOException {
reader.beginObject();
while (reader.hasNext()) {
JsonToken token = reader.peek();
if (token.equals(JsonToken.BEGIN_ARRAY))
handleArray(reader);
else if (token.equals(JsonToken.END_ARRAY)) {
reader.endObject();
return;
} else
handleNonArrayToken(reader, token);
}
}
/**
*处理json数组,第一个标记是 JsonToken_BEGIN_ARRAY,数组可能包含对象或者基本原始类型
*
* @param reader
* @throws IOException
*/
public static void handleArray(JsonReader reader) throws IOException {
reader.beginArray();
while (true) {
JsonToken token = reader.peek();
if (token.equals(JsonToken.END_ARRAY)) {
reader.endArray();
break;
} else if (token.equals(JsonToken.BEGIN_OBJECT)) {
handleObject(reader);
} else
handleNonArrayToken(reader, token);
}
}
/**
* 处理不是数组的符号标记
*
* @param reader
* @param token
* @throws IOException
*/
public static void handleNonArrayToken(JsonReader reader, JsonToken token) throws IOException {
if (token.equals(JsonToken.NAME))
System.out.println(reader.nextName());
else if (token.equals(JsonToken.STRING))
System.out.println(reader.nextString());
else if (token.equals(JsonToken.NUMBER))
System.out.println(reader.nextDouble());
else
reader.skipValue();
}
}c):将JSON对象转为java对象树
我们可以从一个json串来构建JsonElement(com.google.gson.JsonElement)树,然后这个树可以转为java对象,JsonElement 含有isJsonObjec()以及isJsonNull()方法等等,这些方法可以识别出JsonElement的类型。然后通过getAsJsonObject()和getAsJsonPrimitive()方法可以获取真正的java对象。举例说明:ParseTreeExample.java
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.commons.io.IOUtils;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class ParseTreeExample6 {
public static void main(String[] args) throws MalformedURLException, IOException {
String url = "http://freemusicarchive.org/api/get/albums.json?api_key=60BLHNQCAOUFPIBZ&limit=5";
String json = IOUtils.toString(new URL(url));
JsonParser parser = new JsonParser();
//JsonElement是根节点,它可能是一个对象数组为空或者java原始类型
JsonElement element = parser.parse(json);
// 使用isxxx方法来找出jsonelement的类型,在我们的例子中我们知道跟对象是Albums对象并且包含数组对象
if (element.isJsonObject()) {
JsonObject albums = element.getAsJsonObject();
System.out.println(albums.get("title").getAsString());
JsonArray datasets = albums.getAsJsonArray("dataset");
for (int i = 0; i < datasets.size(); i++) {
JsonObject dataset = datasets.get(i).getAsJsonObject();
System.out.println(dataset.get("album_title").getAsString());
}
}
}
}d):序列化List
Gson提供了com.google.gson.reflect.TypeToken这个类用于存储泛型类型,举例GenericTypesExample.java
import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class GenericTypesExample{
public static void main(String[] args) {
Animal<dog> animal = new Animal<Dog>();
Dog dog = new Dog("I am a dog");
animal.setAnimal(dog);
Gson gson = new Gson();
//定义一个类型
Type animalType = new TypeToken<Animal<Dog>>() {
}.getType();
// 我们首先将animal对象转为json然后从这个json读取回来,但是我们把json定义一个Animal类型
Animal animal1 = gson.fromJson(gson.toJson(animal, animalType), Animal.class);
System.out.println(animal1.get().getClass());
Animal animal2 = gson.fromJson(gson.toJson(animal), animalType);
System.out.println(animal2.get().getClass());
}
}
Animal.javapublic class Animal<T> { public T animal; public void setAnimal(T animal) {
this.animal = animal;
} public T get() {
return animal;
} }Dog.java
public class Dog {
private String name;
public Dog(String name) {
this.name = name;
}
public String getName() {
return name;
}
}e):序列化内部类
Gson能够序列化内部类和静态嵌套类,通过下面这个例子我们可以看到
1.序列化含有静态嵌套类
2.序列化含有非静态嵌套类
3.反序列化json到一个含有静态非静态内部类的类
4.序列化静态嵌套类
5.序列化非静态嵌套类
6.反序列化json到一个静态嵌套类
7.反序列化json到一个非静态嵌套类
举例:SerializeInnerClassExample.java
import java.lang.reflect.Modifier;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import AlbumsWithInnerClass.Dataset;
import AlbumsWithInnerClass.Dataset2;
public class SerializeInnerClassExample {
public static void main(String[] args) {
// 创建一个含有静态潜逃类和非静态嵌套类的Albums类
AlbumsWithInnerClass albums = new AlbumsWithInnerClass();
albums.setName("SerializeInnerClass");
//创建一个dataset.因为它不是一个非静态的嵌套类,所以我们需要一个闭合的类型
Dataset dataset = albums.new Dataset();
dataset.setAlbum_id("1");
dataset.setAlbum_name("albums1");
// 将datasets set到 albums中去
albums.setDatasetsInner(new Dataset[] { dataset });
// 静态的内部类能够被创建而不需要闭合的类型
Dataset2 dataset2 = new Dataset2();
dataset2.setAlbum_id("2");
dataset2.setAlbum_name("albums2");
albums.setDatasetsStatic(new Dataset2[] { dataset2 });
// 创建 GsonBuilder
GsonBuilder builder = new GsonBuilder();
builder.excludeFieldsWithModifiers(Modifier.PRIVATE);
Gson gson = builder.create();
String json = gson.toJson(albums);
System.out.println(json);
// 打印的结果为
// {"name":"SerializeInnerClass","datasetsInner":[{"album_name":"SerializeInnerClass_albums1","album_id":"1"}],
// "datasetsStatic":[{"album_name":"albums2","album_id":"2"}]}
Gson gson3 = new Gson();
AlbumsWithInnerClass parsedAlbums = gson3.fromJson(json, AlbumsWithInnerClass.class);
System.out.println(parsedAlbums.datasetsInner[0].album_name);
System.out.println(parsedAlbums.datasetsStatic[0].album_name);
Gson gson2 = new Gson();
String json2 = gson2.toJson(dataset);
System.out.println(json2);
//打印的结果为 {"album_name":"SerializeInnerClass_albums1","album_id":"1"}
String json3 = gson2.toJson(dataset2);
System.out.println(json3);
// 打印的结果为 {"album_name":"albums2","album_id":"2"}
// 从json字符串中创建一个内部类
Gson gson4 = new Gson();
Dataset parsedDataset = gson4.fromJson(json2, Dataset.class);
System.out.println(parsedDataset.getClass());
// 打印结果class com.studytrails.json.gson.AlbumsWithInnerClass$Dataset
System.out.println(parsedDataset.album_name);
// 打印结果 SerializeInnerClass_albums1
// 从json中创建一个嵌套的静态类
Dataset2 parsedStaticNestedClass = gson4.fromJson(json3, Dataset2.class);
System.out.println(parsedStaticNestedClass.getClass());
// 打印结果 class com.studytrails.json.gson.AlbumsWithInnerClass$Dataset2
System.out.println(parsedStaticNestedClass.album_name);
// 打印结果 albums2
}
}AlbumsWithInnerClass.java
public class AlbumsWithInnerClass {
public String name;
private String year;
public Dataset[] datasetsInner;
public Dataset2[] datasetsStatic; public void setDatasetsInner(Dataset[] datasetsInner) {
this.datasetsInner = datasetsInner;
} public void setDatasetsStatic(Dataset2[] datasetsStatic) {
this.datasetsStatic = datasetsStatic;
} public void setName(String name) {
this.name = name;
} public void setYear(String year) {
this.year = year;
} class Dataset {
public String album_name;
public String album_id; public void setAlbum_id(String album_id) {
this.album_id = album_id;
} public void setAlbum_name(String album_name) {
this.album_name = name + "_" + album_name;
}
} static class Dataset2 {
public String album_name;
public String album_id; public void setAlbum_id(String album_id) {
this.album_id = album_id;
} public void setAlbum_name(String album_name) {
this.album_name = album_name;
}
}
}f):自定义类型适配器
自定义类型适配器需要继承com.google.gson.TypeAdapter这个抽象类,实现方法有 public abstract T read(JsonReader in) throws IOException; and public abstract void write(JsonWriter out, T value) throws IOException;你定义的适配器能够处理空值,创建适配器实例后需要在GsonBuilder里面注册,然后通过GsonBuilder来创建Json对象,用于序列化和反序列化操作。举例:
DatasetTypeAdapterExample.java
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.commons.io.IOUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class DatasetTypeAdapterExample {
public static void main(String[] args) throws MalformedURLException, IOException {
String url = "http://freemusicarchive.org/api/get/albums.json?api_key=60BLHNQCAOUFPIBZ&limit=5";
String json = IOUtils.toString(new URL(url));
// 创建自定义内心适配器并且把它注册到 GsonBuilder
Gson gson = new GsonBuilder().registerTypeAdapter(Dataset.class, new DatasetTypeAdapter()).create();
Albums albums = gson.fromJson(json, Albums.class);
System.out.println(albums.getDataset()[1].getAlbum_title()); }
}
DatasetTypeAdapter.java
import java.io.IOException;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
public class DatasetTypeAdapter extends TypeAdapter<Dataset> {
@Override
public Dataset read(JsonReader reader) throws IOException {
JsonToken token = reader.peek();
Dataset dataset = new Dataset();
if (token.equals(JsonToken.BEGIN_OBJECT)) {
reader.beginObject();
while (!reader.peek().equals(JsonToken.END_OBJECT)) {
if (reader.peek().equals(JsonToken.NAME)) {
if (reader.nextName().equals("album_url"))
dataset.setAlbum_title(reader.nextString());
else
reader.skipValue();
}
}
reader.endObject();
}
return dataset;
}
@Override
public void write(JsonWriter out, Dataset value) throws IOException {
}
}Albums.java
public class Albums { private String title;
private Dataset[] dataset; public void setTitle(String title) {
this.title = title;
} public void setDataset(Dataset[] dataset) {
this.dataset = dataset;
} public String getTitle() {
return title;
} public Dataset[] getDataset() {
return dataset;
}
}g):自定义序列化器
创建一个自定义的序列化器需要实现com.studytrails.json.gson.JsonSerializer 接口,然后实现 public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context); 方法,src 是指源对象,Type 是指源对象的类型,举例:
DogSerializer.java
import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.reflect.TypeToken;
public class DogSerializer implements JsonSerializer<dog> {
@Override
public JsonElement serialize(Dog src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject object = new JsonObject();
String name = src.getName().replaceAll(" ", "_");
object.addProperty("name", name);
return object;
}
public static void main(String[] args) {
Animall<Dog> animal = new Animall<Dog>();
Dog dog = new Dog("I am a dog");
animal.setAnimal(dog); Gson gson = new GsonBuilder().registerTypeAdapter(Dog.class, new DogSerializer()).setPrettyPrinting().create(); Type animalType = new TypeToken<Animal<Dog>>() {
}.getType();
System.out.println(gson.toJson(animal, animalType));
}
}Animal.java
public class Animal<t> { public T animal; public void setAnimal(T animal) {
this.animal = animal;
} public T get() {
return animal;
} }Dog.java
public class Dog {
private String name; public Dog(String name) {
this.name = name;
} public String getName() {
return name;
} }h):自定义反序列化器
创建一个反序列化器需要实现的方法有 public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException;举例:
DogDeserialiser.java
import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
public class DogDeserialiser implements JsonDeserializer<Dog> {
@Override
public Dog deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String name = json.getAsJsonObject().get("name").getAsString();
name = name.replace(" ", "_");
Dog dog = new Dog(name);
return dog;
}
public static void main(String[] args) {
String json = "{\"animal\":{\"name\":\"I am a dog\"}}";
Gson gson = new GsonBuilder().registerTypeAdapter(Dog.class, new DogDeserialiser()).create();
Type animalType = new TypeToken<Animal<Dog>>() {
}.getType();
Animal<Dog> animal = gson.fromJson(json, animalType);
System.out.println(animal.get().getName());
}
}
i):GSON扩展策略
在缺省的情况下,GSON试着将java对象中的所有属性映射到json中相一致的属性中。但是在一些特殊的情况下我们尝试去控制这个操作。这个是有一些方法实现的。
1.通过自定义注解的方式并且忽略被注解的域。
2.通过集成ExclusionStrategy 接口的方式自定义来实现,需要实现的方法有public boolean shouldSkipField(FieldAttributes f); and public boolean shouldSkipClass(Class clazz);
3.通过使用@Expose 注解,然后在GsonBuilder上面使用excludeFieldsWithoutExposeAnnotation(),这个方法,除非使用 @Expose 这个注解,否 则我们忽略所有的域。
举例:ExclusionExample.java
import java.awt.Color;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class ExclusionExample {
public static void main(String[] args) {
Cat cat = new Cat();
cat.setName("Cat");
cat.setAge(1);
cat.setColor(Color.BLACK);
cat.setCountry("US"); Gson gson = new GsonBuilder().serializeNulls().setExclusionStrategies(new CustomExclusionStrategy(Color.class))
.excludeFieldsWithoutExposeAnnotation().create();
System.out.println(gson.toJson(cat));
// 打印结果 {"name":"Cat","lazy":null}
}
}Cat.java
import java.awt.Color;
import com.google.gson.annotations.Expose;
public class Cat {
@Expose
private String name;
private int age;
private Color color;
@Expose
@Country
private String country;
@Expose
private Boolean lazy = null;
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setColor(Color color) {
this.color = color;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public Color getColor() {
return color;
}
public void setCountry(String country) {
this.country = country;
}
public String getCountry() {
return country;
}
public void setLazy(Boolean lazy) {
this.lazy = lazy;
}
public Boolean getLazy() {
return lazy;
}
}CustomExclusionStrategy.java
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
public class CustomExclusionStrategy implements ExclusionStrategy {
private Class classToExclude;
public CustomExclusionStrategy(Class classToExclude) {
this.classToExclude = classToExclude;
}
@Override
public boolean shouldSkipField(FieldAttributes f) {
if (f.getAnnotation(Country.class) == null)
return false;
return true;
} @Override
public boolean shouldSkipClass(Class<?> clazz) {
if (clazz.equals(classToExclude))
return true;
return false;
}
}4.结束
Gson功能的强大可见一斑,而且很是简介,毕竟是大牌厂商的产品,果然是不一样,当然还有很多功能有待挖掘,最好的是阅读源码,这样可以收获更大。
JSON解析之Gson的更多相关文章
- Android JSON解析库Gson和Fast-json的使用对比和图书列表小案例
Android JSON解析库Gson和Fast-json的使用对比和图书列表小案例 继上篇json解析,我用了原生的json解析,但是在有些情况下我们不得不承认,一些优秀的json解析框架确实十分的 ...
- json解析jackson ,Gson,等知识总结
相关资料链接: Java构造和解析json数据的两种方法详解 java解析json Android网络之数据分析---使用Google Gson 解析Json数据 使用jackson在java中处理j ...
- Json解析与Gson解析
本文主要介绍json最原始的解析与google提供的gson工具类解析 ①json解析 /** * 普通的json解析 * @param s * @throws JSONException */ pr ...
- 关于浮点数的json解析
近期在工作中遇到个问题 通过post请求从其他系统(好像是C#写的)获得json字符串 {"geometry":{"rings":[[[40426489.331 ...
- Android总结之json解析(FastJson Gson 对比)
前言: 最近为了统一项目中使用的框架,发现项目中用到了两种json解析框架,他们就是当今非常主流的json解析框架:google的Gson 和阿里巴巴的FastJson,为了废除其中一个所以来个性能和 ...
- android json解析详细介绍之gson
废话不多说,什么json是轻量级数据交换标准:自己百度去深入了解:这里有三种json解析工具.本人只用过其中两种: 1.Google Json利器之Gson 评价:简单,方便. 2.阿里巴巴 ...
- android JSON解析之JSONObject与GSON
1.写在前面 JSON数据是android网络开发中常见的数据格式,JSON最常见的传输方法是使用HTTP协议,关于android开发中HTTP协议的使用方法可参考我的另一篇随笔android网络编程 ...
- Android JSON 解析库的使用 - Gson 和 fast-json
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族 ...
- JSON数据解析及gson.jar包
从服务器端接收数据的时候,那些数据必须以浏览器能够理解的格式来发送. 服务器端的编程语言只能以如下 3 种格式返回数据: HTML XML JSON JSON一种简单的数据格式,比xml更轻巧. JS ...
随机推荐
- Android 设计模式Template Method模式
自定义模板方法模式:定义的算法的骨架中的方法,虽然某些步骤推迟到子类中,下模板方法允许子类不能改变在的情况下,该算法的结构.算法重新定义某些步骤. 设计原则:不要给我们打电话.我会打电话给你.(像猎头 ...
- ViewPager实现页面切换
先贴效果图(每个开关Tab债券.尾随页变化.效果图蓝条添加的用户体验) watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzIxMDYyMA==/fo ...
- NSIS:简单按钮美化插件SkinButton,支持透明PNG图片。
原文 NSIS:简单按钮美化插件SkinButton,支持透明PNG图片. 征得作者贾可的同意,特发布按钮美化插件SkinButton. 插件说明: 使用GDI+库写的一个简单按钮美化插件,支持透明P ...
- avalonjs1.5 入门教程
迷你MVVM框架 avalonjs1.5 入门教程 avalon经过几年以后,已成为国内一个举足轻重的框架.它提供了多种不同的版本,满足不同人群的需要.比如avalon.js支持IE6等老旧浏览器,让 ...
- leetcode 名单 Insertion Sort List
Insertion Sort List Total Accepted: 24444 Total Submissions: 96639My Submissions Sort a linked list ...
- 每天收获一点点------Hadoop之HDFS基础入门
一.HDFS出现的背景 随着社会的进步,需要处理数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是却不方便管理和维护—>因此,迫切需要一种系统来管理多 ...
- Java多线程的~~~synchronized加入参数,以实现独立片段
有时候,我们不希望在整个方法的前面加上synchronized这个keyword.这将使整个方法调用变得缓慢,我们只是重点 代码的地方添加这个synchronized这个keyword,然后这样就能加 ...
- Mac OS X中报:java.io.UnixFileSystem.createFileExclusively(Native Method)的简单原因
这个博客太简单了!想到可能有其它朋友也遇到这个问题,就记录一下. 今天把一个之前在Windows上的Java项目放到Mac OS X上执行,本来认为应该非常easy的事情,结果还是报: Excepti ...
- iframe参数
iframe参数: <iframe src="test.jsp" width="100″ height="50″ frameborder="no ...
- 大数据系列修炼-Scala课程01
简介 由于本人刚毕业,也是从事软件开发相关的工作.想再学习一下关于大数据.移动互联网.云计算相关的技术.为我的未来打好基础.并且从零开始学习大数据相关的知识,脚踏实地的走好每一步,听行业前辈说毕业生刚 ...