jackson 2.x 解析 json 案例

1、官方参考

2、简介

Jackson 有两个主要分支,1.x 处于维护状态,只会发布 bug 修复版本。2.x 还在积极地开发当中。这两个版本的 Java 包名和 Maven artifact 不一样,所以它们不互相兼容,但是可以和平共存,项目可以同时依赖 1.x 和 2.x 而不会发生冲突。

Jackson 1.x(目前版本从 1.1~1.9)与 2.x 版本的依赖从包名可以看出来。1.x 的类库中,包命名以:org.codehaus.jackson.xxx 开头,而 2.x 类库中包命令:com.fastxml.jackson.xxx 开头。

3、主要模块

1)核心模块

核心模块是扩展模块构建的基础,到 2.7 版本为止,共有 3 个核心模块(依赖关系从上到下):

  • Streaming : jackson-core jar,定义了底层的 streaming API 和实现了 Json 特性。
  • Annotations : jackson-annotations jar,包含了标准的 Jackson 注解。
  • Databind : jackson-databind jar,实现了数据绑定和对象序列化,它依赖于 streaming 和 annotations 的包。

2)第三方数据类型模块

这些扩展是插件式的 Jackson 模块,用 ObjectMapper.registerModule() 注册,并且通过添加 serializers 和 deserializers 以便 Databind 包(ObjectMapper / ObjectReader / ObjectWriter)可以读写这些类型,来增加对各种常用的 Java 库的数据类型的支持。参考:https://github.com/FasterXML/jacksonThird-party datatype modules。

3)数据格式模块

Jackson 也有处理程序对 JAX-RS 标准实现者例如 Jersey, RESTeasy, CXF 等提供了数据格式支持。处理程序实现了 MessageBodyReader 和 MessageBodyWriter,目前支持的数据格式包括 JSON, Smile, XML, YAML 和 CBOR。

数据格式提供了除了 Json 之外的数据格式支持,它们绝大部分仅仅实现了 streaming API abstractions,以便数据绑定组件可以按照原来的方式使用。另一些(几乎不需要)提供了 databind 标准功能来处理例如 schemas。参考https://github.com/FasterXML/jacksonData format modules

4)jackon 的三个核心类库

maven 依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.4</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.4</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.4</version>
</dependency>

4、处理 Json

Jackson 提供了三种可选的 Json 处理方法:流式 API(Streaming API)、树模型(Tree Model)、数据绑定(Data Binding)。三种处理 Json 的方式的特性:

  • Streaming API:是效率最高的处理方式(开销低、读写速度快,但程序编写复杂度高)
  • Tree Model:是最灵活的处理方式
  • Data Binding:是最常用的处理方式

1)Data Binding

  • 主要使用 ObjectMapper 来操作 Json,默认情况下会使用 BeanSerializer 来序列化 POJO。
  • 如果是解析,那么如下的例子里的 TestJson 必须要有 setters,且 setters 必须是 public 修饰的,否则属性的值将会为 null。
  • 如果是生成,那么必须有 getters,且 getters 必须是 public 修饰的。
  • 如果属性不是 private 修饰,那么可以不用有 getters 和 setters。

要点:

1
2
3
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(jsonFile, Bean);
mapper.readValue(jsonFile, Bean.class 或 Collection<Bean>);

1)生成 json

city.java 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.myjackson.databinding;

public class City {
private Integer id;
private String cityName;
public City(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
}

province.java 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.myjackson.databinding;
import java.util.Date;
import java.util.List;

public class Province {
private Integer id;
private String name;
private Date birthDate;
private List<City> cities;
public Province(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<City> getCities() {
return cities;
}
public void setCities(List<City> cities) {
this.cities = cities;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
}

country.java 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.myjackson.databinding;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Country {

private Integer id;
private String countryName;
private Date establishTime;
private List<Province> provinces;
private String[] lakes;
private Map<String, String> forest = new HashMap<String, String>();
public Country(){

}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public Date getEstablishTime() {
return establishTime;
}
public void setEstablishTime(Date establishTime) {
this.establishTime = establishTime;
}
public List<Province> getProvinces() {
return provinces;
}
public void setProvinces(List<Province> provinces) {
this.provinces = provinces;
}
public String[] getLakes() {
return lakes;
}
public void setLakes(String[] lakes) {
this.lakes = lakes;
}
public Map<String, String> getForest() {
return forest;
}
public void setForest(Map<String, String> forest) {
this.forest = forest;
}

}

测试案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Test
public void Bean2JsonStr() throws ParseException, JsonGenerationException, JsonMappingException, IOException{
// 使用 ObjectMapper 转化对象为 Json
ObjectMapper mapper = new ObjectMapper();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
mapper.setDateFormat(dateFormat); //设置日期序列化格式
City city1 = new City();
city1.setId(1);
city1.setCityName("gz");
City city2 = new City();
city2.setId(2);
city2.setCityName("dg");

Province province = new Province();
province.setId(1);
province.setName("GD");
province.setBirthDate(new Date());
List<City> cities = new ArrayList<City>();
cities.add(city1);
cities.add(city2);
province.setCities(cities);

Country country = new Country();
country.setCountryName("China");
country.setId(1);
country.setEstablishTime(dateFormat.parse("1949-10-01"));
country.setLakes(new String[] { "Qinghai Lake", "Poyang Lake","Dongting Lake", "Taihu Lake" });
HashMap<String, String> forest = new HashMap<String, String>();
forest.put("no.1", "dxal");
forest.put("no.2", "xxal");
country.setForest(forest);
List<Province> provinces = new ArrayList<Province>();
provinces.add(province);
country.setProvinces(provinces);
mapper.configure(SerializationFeature.INDENT_OUTPUT, true); // 为了使JSON视觉上的可读性,在生产中不需如此,会增大Json的内容
mapper.setSerializationInclusion(Include.NON_EMPTY); // 配置mapper忽略空属性
mapper.writeValue(new File("country.json"), country); // 默认情况,Jackson使用Java属性字段名称作为 Json的属性名称,也可以使用Jackson annotations(注解)改变Json属性名称
}

运行得到 country.json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"id": 1,
"countryName": "China",
"establishTime": "1949-10-01",
"provinces": [
{
"id": 1,
"name": "GD",
"birthDate": "2017-02-04",
"cities": [
{
"id": 1,
"cityName": "gz"
},
{
"id": 2,
"cityName": "dg"
}
]
}
],
"lakes": ["Qinghai Lake", "Poyang Lake", "Dongting Lake", "Taihu Lake"],
"forest": {
"no.1": "dxal",
"no.2": "xxal"
}
}

2)解析 json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Test
public void JsonStr2Bean() throws JsonParseException, JsonMappingException, IOException{
ObjectMapper mapper = new ObjectMapper();
File jsonFile = new File("country.json");
//当反序列化 json 时,未知属性会引起的反序列化被打断,这里我们禁用未知属性打断反序列化功能,
//因为,例如 json 里有 10 个属性,而我们的 bean 中只定义了 2 个属性,其它 8 个属性将被忽略
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
Country country = mapper.readValue(jsonFile, Country.class);
System.out.println(country.getCountryName()+country.getEstablishTime());
List<Province> provinces = country.getProvinces();
for (Province province : provinces) {
System.out.println("province:"+province.getName() + "\n" + "birthDate:"+province.getBirthDate());
for (City city: province.getCities()) {
System.out.println(city.getId()+" "+city.getCityName());
}
}
}

输出结果:

1
2
3
4
5
ChinaSat Oct 01 08:00:00 CST 1949
province:GD
getBirthDate:Sat Feb 04 08:00:00 CST 2017
1 gz
2 dg

解析的时候如果碰到集合类,那么可以使用 TypeReference 类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Test
public void JsonStr2List() throws IOException{
City city1 = new City();
city1.setId(1);
city1.setCityName("gz");
City city2 = new City();
city2.setId(2);
city2.setCityName("dg");

List<City> cities = new ArrayList<City>();
cities.add(city1);
cities.add(city2);

ObjectMapper mapper = new ObjectMapper();
String listJsonStr = mapper.writeValueAsString(cities);
System.out.println(listJsonStr);
List<City> list = mapper.readValue(listJsonStr, new TypeReference<List<City>>(){} );

for (City city: list) {
System.out.println("id:"+city.getId()+" cityName:"+city.getCityName());
}
}

2)Streaming API

Jackson 提供了一套底层 API 来解析 Json 字符串,这个 API 为每个 Json 对象提供了符号。例如, ‘{’ 是解析器提供的第一个对象(writeStartObject()),键值对是解析器提供的另一个单独对象(writeString(key,value))。这些 API 很强大,但是需要大量的代码。大多数情况下,Tree Model 和 Data Binding 可以代替 Streaming API。

上面代码如果注释掉 city1.setId(1);这行,结果为:

1
2
3
[{"id":null,"cityName":"gz"},{"id":2,"cityName":"dg"}]
id:null cityName:gz
id:2 cityName:dg

但假如想让 id 为 null 的不输出,不为 null 的输出除了 mapper.setSerializationInclusion(Include.NON_EMPTY); // 配置 mapper 忽略空属性 这种方法外还可以在 ObjectMapper 中注册一个自定义的序列化 JsonSerializer 和反序列化
JsonDeSerializer:

CityJsonSerializer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.myjackson.databinding;

import java.io.IOException;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

public class CityJsonSerializer extends JsonSerializer<City>{

@Override
public void serialize(City city, JsonGenerator jsonGenerator, SerializerProvider arg2)
throws IOException, JsonProcessingException {
jsonGenerator.writeStartObject();
if ( city.getId()!=null) {
jsonGenerator.writeNumberField("id", city.getId());
}
jsonGenerator.writeStringField("cityName", city.getCityName());
jsonGenerator.writeEndObject();

}

}

CityJsonDeSerializer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.myjackson.databinding;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

public class CityJsonDeSerializer extends JsonDeserializer<List<City>>{

@Override
public List<City> deserialize(JsonParser parser,DeserializationContext deserializationcontext) throws IOException,
JsonProcessingException {
List<City> list = new ArrayList<City>();
// 开始解析数组,第一个JsonToken必须是JsonToken.START_ARRAY"["
if (!JsonToken.START_ARRAY.equals(parser.getCurrentToken())) {
System.out.println(parser.getCurrentToken());
return null;
}
// 解析符号直到字符串结尾
while (!parser.isClosed()) {
// 如果有必要的话,这个方法会沿着流前进直到足以确下一个JsonToken的类型
JsonToken token = parser.nextToken();
// 如果是最后一个JsonToken,那么就结束了
if (token == null)
break;
// 数组的每个元素都是对象,因此下一个JsonToken是JsonToken.START_OBJECT"{"
if (!JsonToken.START_OBJECT.equals(token)) {
break;
}
City city = null;
// 输出id字段的值
while (true) {
if (JsonToken.START_OBJECT.equals(token)) {
city = new City();
}
token = parser.nextToken();
if (token == null)
break;

if (JsonToken.FIELD_NAME.equals(token) ) {

if("id".equals(parser.getCurrentName())){
token = parser.nextToken();
city.setId(parser.getIntValue());
}else if("cityName".equals(parser.getCurrentName())){
token = parser.nextToken();
city.setCityName(parser.getText());
}

}
if(JsonToken.END_OBJECT.equals(token)){
list.add(city);
}

}

}
return list;
}
}

测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Test
public void StreamJsonStr2List() throws IOException{
City city1 = new City();
//city1.setId(1);
city1.setCityName("gz");
City city2 = new City();
city2.setId(2);
city2.setCityName("dg");

List<City> cities = new ArrayList<City>();
cities.add(city1);
cities.add(city2);

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(City.class, new CityJsonSerializer());
mapper.registerModule(module);
String listJsonStr = mapper.writeValueAsString(cities);

System.out.println(listJsonStr);

ObjectMapper mapper2 = new ObjectMapper();
SimpleModule module2 = new SimpleModule();
module2.addDeserializer(List.class, new CityJsonDeSerializer());
mapper2.registerModule(module2);
List<City> list = mapper2.readValue(listJsonStr, new TypeReference<List<City>>(){} );

for (City city: list) {
System.out.println("id:"+city.getId()+" cityName:"+city.getCityName());
}
}

也可以简单一点,使用注解,省去在 ObjectMapper 中注册 SimpleModule

1
2
3
4
5
6
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

@JsonSerialize(using=CityJsonSerializer.class)
public class City {
...
}

运行结果:

1
2
3
[{"cityName":"gz"},{"id":2,"cityName":"dg"}]
id:null cityName:gz
id:2 cityName:dg

3)Tree Mode

如果不想为 Json 结构写一个 class 的话,Tree Mode 是一个很好的选择。

生成 json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@Test
public void TreeMode2Json() throws IOException{

//创建一个节点工厂,为我们提供所有节点
JsonNodeFactory factory = new JsonNodeFactory(false);
//创建一个json factory来写tree modle为json
JsonFactory jsonFactory = new JsonFactory();
//创建一个json生成器
JsonGenerator generator = jsonFactory.createGenerator(new FileWriter(new File("country2.json")));
//注意,默认情况下对象映射器不会指定根节点,下面设根节点为country
ObjectMapper mapper = new ObjectMapper();
ObjectNode country = factory.objectNode();
country.put("id", 1);
country.put("countryName","China");
country.put("establishTime", "1949-10-01");

ArrayNode provinces = factory.arrayNode();
ObjectNode province = factory.objectNode();
ObjectNode city1 = factory.objectNode();
city1.put("id", 1);
city1.put("cityName", "gz");
ObjectNode city2 = factory.objectNode();
city2.put("id", 1);
city2.put("cityName", "dg");
ArrayNode cities = factory.arrayNode();
cities.add(city1).add(city2);
province.put("cities", cities);
provinces.add(province);
country.put("provinces",provinces);

ArrayNode lakes = factory.arrayNode();
lakes.add("QingHai Lake").add("Poyang Lake").add("Dongting Lake").add("Taihu Lake");
country.put("lakes",lakes);

ObjectNode forest = factory.objectNode();
forest.put("no.1","dxal");
forest.put("no.2", "xxal");
country.put("forest", forest);

mapper.setSerializationInclusion(Include.NON_EMPTY); // 配置mapper忽略空属性
mapper.writeTree(generator, country);
}

结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"id": 1,
"countryName": "China",
"establishTime": "1949-10-01",
"provinces": [
{
"cities": [
{ "id": 1, "cityName": "gz" },
{ "id": 1, "cityName": "dg" }
]
}
],
"lakes": ["QingHai Lake", "Poyang Lake", "Dongting Lake", "Taihu Lake"],
"forest": { "no.1": "dxal", "no.2": "xxal" }
}

读取 json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
public void TreeModeReadJson() throws IOException{
ObjectMapper mapper = new ObjectMapper();
// Jackson 提供一个树节点被称为"JsonNode",ObjectMapper 提供方法来读 json 作为树的 JsonNode 根节点
JsonNode node = mapper.readTree(new File("country2.json"));
// 看看根节点的类型
System.out.println("node JsonNodeType:"+node.getNodeType());
System.out.println("---------得到所有 node 节点的子节点名称----------------------");

Iterator<String> fieldNames = node.fieldNames();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
System.out.print(fieldName+" ");
}

System.out.println("\n---------------------------------------------------");
JsonNode lakes = node.get("lakes");
System.out.println("lakes:"+lakes+" JsonNodeType:"+lakes.getNodeType());

}

运行结果:

1
2
3
4
5
6
7
node JsonNodeType:OBJECT
---------得到所有 node 节点的子节点名称-------------------------
id countryName establishTime provinces lakes forest

---

lakes:["QingHai Lake","Poyang Lake","Dongting Lake","Taihu Lake"] JsonNodeType:ARRAY

5、结束

Stream API 方式是开销最低、效率最高,但编写代码复杂度也最高,在生成 Json 时,需要逐步编写符号和字段拼接 json,在解析 Json 时,需要根据 token 指向也查找 json 值,生成和解析 json 都不是很方便,代码可读性也很低。
Databinding 处理 Json 是最常用的 json 处理方式,生成 json 时,创建相关的 java 对象,并根据 json 内容结构把 java 对象组装起来,最后调用 writeValue 方法即可生成 json,
解析时,就更简单了,直接把 json 映射到相关的 java 对象,然后就可以遍历 java 对象来获取值了。

TreeModel 处理 Json,是以树型结构来生成和解析 json,生成 json 时,根据 json 内容结构,我们创建不同类型的节点对象,组装这些节点生成 json。解析 json 时,它不需要绑定 json 到 java bean,根据 json 结构,使用 path 或 get 方法轻松查找内容。

6、解析 Json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ParseJsonTest {

/**
* @param args
*/
public static void main(String[] args) {
String data = "{\"type\":2,\"range\":1,\"start\":1368417600,\"end\":1368547140,"
+ "\"cityName\":\"天津\",\"companyIds\":[\"12000001\"],\"companyNames\":[\"天津\"],"
+ "\"12000001\":{\"data\":[47947,48328,48573,48520],"
+ "\"timestamps\":[1368417600,1368417900,1368418200,1368418500]}}";
String data2 = parseJson(data);
System.out.println(data2);
}

public static String parseJson(String data) {
// 用来展现解析Json得到的值
StringBuffer buf = new StringBuffer();
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(data); // 读取Json
// rootNode.path("xx")返回的还是一个JsonNode对象,调用该JsonNode的相应方法,得到键对应的值
int type = rootNode.path("type").asInt();
int range = rootNode.path("range").asInt();
long start = rootNode.path("start").asLong();
long end = rootNode.path("end").asLong();
String cityName = rootNode.path("cityName").asText();

// 转换时间格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));

String str = "类型(type):" + type + "\r\n" + "范围(range):" + range
+ "\r\n" + "开始时间(start):"
+ sdf.format(new Date(start * 1000)) + "\r\n"
+ "结束时间(end):" + sdf.format(new Date(end * 1000)) + "\r\n"
+ "城市名称(cityName):" + cityName;
buf.append(str);
// 得到companyIds的JsonNode对象
JsonNode companyIds = rootNode.path("companyIds");
JsonNode companyNames = rootNode.path("companyNames");

// 遍历companyIds中的内容
for (int i = 0; i < companyIds.size(); i++) {
String companyId = companyIds.get(i).asText();
// 本例解析的Json字符串中companyIds与companyNames的长度是相同的,所有直接遍历companyNames
String companyName = companyNames.get(i).asText();
// companyId的值:12000001,对应Json串中的
// "12000001":{"data":[...],"timestamps":[....]}
JsonNode infoNode = rootNode.path(companyId);
// 得到"12000001":{"data":[...],"timestamps":[....]}中的data和timestamps的JsonNode对象
JsonNode dataNode = infoNode.path("data");
JsonNode timestampsNode = infoNode.path("timestamps");
// 遍历data和timestamps 本例中data.size与timestamps.size是相等的

buf.append("\r\n{\r\n 公司ID(companyId):" + companyId
+ "\r\n 公司名称(companyName):" + companyName + "\r\n"
+ " data:");
for (int j = 0; j < dataNode.size(); j++) {
long dataValue = dataNode.get(j).asLong();
buf.append(dataValue + ",");
}
buf.append("\r\n time:");
for (int k = 0; k < timestampsNode.size(); k++) {
long timeValue = timestampsNode.get(k).asLong();
buf.append(sdf.format(new Date(timeValue * 1000)) + ",");
}
buf.append("\r\n}\r\n");
}
return buf.toString();
}
}

测试结果:

1
2
3
4
5
6
7
8
9
10
11
类型(type):2
范围(range):1
开始时间(start):201305131200
结束时间(end):201305142359
城市名称(cityName):天津
{
公司ID(companyId):12000001
公司名称(companyName):天津
data:47947,48328,48573,48520,
time:201305131200,201305131205,201305131210,201305131215
}