JSON解析之实战演练-->解析购物网站数据
摘要:获取一段网络JSON数据,下载本地并解析,并将包含的图片信息保存到本地。
框架结构分析
测试包——com.bless2015.test
Test.java
工具包——com.bless2015.utils
DownLoadImage.java
ParseUilts.java
HttpUtils.java
**
-代码实现
**
- HttpUtils类
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.List;
import java.util.Map;
public class HttpUtils {
public static void getData(final String path, final CallBack callback){
//传入回调接口,开启线程
new Thread(new Runnable(){
public void run(){
try {
//获得网址并打开
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
//设置连接参数
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setDoInput(true);
conn.setDoOutput(true);
//如果连接正常,返回码为200,返回JSON数据的字节流
if (conn.getResponseCode() == 200) {
InputStream is = conn.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String json = br.readLine();
//将字节流json串传换成String类型,并传入解析方法,返回List集合,泛型为<Map<String,Object>>
List<Map<String, Object>> list = ParseUtils.parseJsonString(json);
//list写入回调函数
callback.load(list);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
//回调函数
public interface CallBack {
public void load(List<Map<String, Object>> list);
}
}
- ParseUtils类
接收JSON字符串,并返回List集合
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class ParseUtils {
public static List<Map<String, Object>> parseJsonString(String json) {
System.out.println("解析工具类");
//创建List和Map集合
List<Map<String, Object>> list =new ArrayList<Map<String, Object>>();
Map<String, Object> map;
try {
//创建JSON对象和数组
JSONObject obj = new JSONObject(json);
JSONArray arr = obj.getJSONArray("data");
for (int i = 0; i < arr.length(); i++) {
//每次循环new一个新的map,重新存放数据,将取到的数据按键值对形式存放到Map集合
map=new HashMap<String,Object>();
JSONObject obj1 = arr.getJSONObject(i);
map.put("id", obj1.getString("id"));
map.put("title", obj1.getString("title"));
map.put("source", obj1.getString("source"));
map.put("description", obj1.getString("description"));
map.put("create_time", obj1.getString("create_time"));
map.put("nickname", obj1.getString("nickname"));
map.put("thumb", obj1.getString("wap_thumb"));
//一次循环的数据取完,将map添加到list中。
list.add(map);
}
System.out.println("解析成功!");
} catch (JSONException e) {
e.printStackTrace();
}
//返回list
return list;
}
- DownLoadImage类
当解析到网址时,传入此类的方法,保存到本地。
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class DownLoadImage {
public static void getImage(final String path, final CallBackImage callback)
throws IOException {
System.out.println("进入下载图片工具类");
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setDoInput(true);
conn.setDoOutput(true);
System.out.println("参数设置成功");
if (conn.getResponseCode() == 200) {
InputStream is = conn.getInputStream();
//创建内存流,保存到内存流中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int a = 0;
byte b[] = new byte[1024];
System.out.println("循环取数据");
while ((a = is.read(b)) != -1) {
baos.write(b, 0, a);
baos.flush();
}
baos.close();
//将字节流传换成字节数组传入回调接口
callback.load(baos.toByteArray());
}
}
//创建回调接口
public interface CallBackImage {
public void load(byte b[]);
}
}
- 测试类
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import com.qianfeng.utils.DownLoadImage;
import com.qianfeng.utils.DownLoadImage.CallBackImage;
import com.qianfeng.utils.HttpUtils;
import com.qianfeng.utils.HttpUtils.CallBack;
public class Test {
public static void main(String[] args) {
String path = "http://sns.maimaicha.com/api?apikey=b4f4ee31a8b9acc866ef2afb754c33e6&format=json&method=news.getHeadlines";
//调用HttpUtils.getData()方法,传入地址和创建匿名接口
HttpUtils.getData(path, new CallBack() {
@Override
public void load(List<Map<String, Object>> list) {
System.out.println("开始打印");
for (Map<String, Object> map : list) {
System.out.println("ID为:" + map.get("id"));
System.out.println("标题为:" + map.get("title"));
System.out.println("资源为:" + map.get("source"));
System.out.println("描述为:" + map.get("description"));
System.out.println("创建时间为:" + map.get("Create_time"));
System.out.println("昵称为:" + map.get("nickname"));
//解析到网址
String pathName = (String) map.get("thumb");
System.out.println("获取文件地址成功");
//imageName需要传入内部类中,由于生命周期不同,需要声明final
final String imageName = pathName.substring(pathName.lastIndexOf("/") + 1);
System.out.println("文件名获取成功");
try {
DownLoadImage.getImage(pathName, new CallBackImage() {
@Override
public void load(byte[] b) {
try {
//获取回调接口中的字节数组,调用文件写入流
FileOutputStream fos = new FileOutputStream("c:/image" + imageName);
fos.write(b);
fos.flush();
fos.close();
System.out.println("图片下载完毕!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
}
经过此次对数据的解析,是我对JSON的理解更深一步,并且接触了fastjson和gson,但是不如原生JSON使用灵活。
首先,先要分析数据,对JSON字符串进行格式化,明确格式。
JSON分析详解,见下一篇博客分析。