Json解析是用来接收网络端信息的重要手段,要吃透,基础扎实。
Json语句:类似map的键值对,[{ “key:“”value“ }]例如[{"name:""方世玉","age:""18"}]
这里只介绍当inputStream流入android端时,如何去解析。
首先,这里需要介绍一下HTTP请求,上篇文章里,简单说明了一下什么事HTTP,这里就以HTTPURLConnection使用POST为实例,介绍如何从android
发出请求,并如何解析从web端带来的json.
public static Competitor getInformation(String use, String pwd) throws Exception { // TODO Auto-generated method stub //寝室ip:192.168 //机房ip:192.168 String path = "http://192.168.X。XX:8080/Teenis_game/AndroidLogin?format=json"; URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(5000); conn.setRequestMethod("POST"); String entity ="&&Username="+use+"&&Password="+pwd; conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//内容类型 conn.setRequestProperty("Content-Length",String.valueOf(entity.getBytes().length)); OutputStream ouStream=conn.getOutputStream();//通过输出流对象,传实体(字节)数据 ouStream.write(entity.getBytes()); if(conn.getResponseCode()==200){ InputStream inStream = conn.getInputStream(); return parseJSON(inStream); /* byte[] data=StreamTool.read(inStream); System.out.println("&&&&&&&&"+data); System.out.println("&&&&&&&&"+data.length); System.out.println("&&&&&&&&"+data.toString()); String result = new String(data,"utf-8");//这里的的utf-8是指的传输过来的data的编码方式,并不是你改变的编码方式,这里只是按照data原来的编码方式进行解码而已 //这里曾出现问题,每次复习请看这里 /* * 出现问题:将byte数组按照utf-8格式解码后,出现虽然解码正确但是有很多?在后面 * 解决办法:将StreamTool里的buffer数组长度改为1; * 这里知道了一个汉字按照utf-8解码时,只占一个byte, */ /* System.out.println("**********"+result); if(result.equals("成功")){ boolean flag = true; return flag; }*/ } return null; } private static Competitor parseJSON(InputStream inStrean) throws Exception{ byte[] data = StreamTool.read(inStrean); String json = new String (data, "UTF-8"); //System.out.println("*******json="+json); Competitor c = null; JSONObject Jsonobject=null; JSONArray jsonarray = new JSONArray(json); for (int i=0;i<jsonarray.length();i++){ Jsonobject = jsonarray.getJSONObject(i); c= new Competitor(); c.setId(Integer.parseInt(Jsonobject.getString("id"))); c.setUsername(Jsonobject.getString("username")); c.setPassword(Jsonobject.getString("password")); c.setRelname(Jsonobject.getString("relname")); c.setMatchage(Integer.parseInt(Jsonobject.getString("Matchage"))); java.sql.Date date=java.sql.Date.valueOf(Jsonobject.getString("borth")); c.setBorth(date); c.setAdress(Jsonobject.getString("adress")); c.setSex(Jsonobject.getString("sex")); } return c; }
这是我做工程里的代码,直接拿了过来,里面也有很多注释,相信能够初步理解json的用法。
这里对一些重要的步骤,作进一步解释:
首先是path路径问题,因为我们android模拟器的系统和电脑的系统会在localhost上冲突,所以我们只能通过局域网ip去访问我们的Tomact的web。
查询ip:cmd————>ipconfig
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//内容类型
这个是定义我们传输内容的类型,稍后会写文章介绍传输内容为Object对象时,应该如何设置。InputStream inStream = conn.getInputStream();
实际上,当语句执行到这里事,android端才与web建立联系,并将内容发送出去。
byte[] data = StreamTool.read(inStrean);
这里用到了我抽象出来的一个读取inputStream的工具类,:
public class StreamTool { public static byte[] read(InputStream inStream) throws Exception { // TODO Auto-generated method stub ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len =0; while((len=inStream.read(buffer))!= -1){ outStream.write(buffer, 0, len); } inStream.close(); return outStream.toByteArray(); }; }
这个工具类里有个缓存数组,这里的大小是自己定义的。outStream.write(buffer, 0, len);
这里容易出现错误,一定是从o读到len的结束,而不是buffer.size();虽然这样写逻辑上是没有错误的,但是因为你的buffer长度是1024kb,
所以当接收的信息小于1024时。就会有错误。当把数据读完之后,发现仍有内存没有读,于是,就会多出许多占位符。
所以这里一定注意,将读取长度,定义为len而不是buffer.size();
json解析其实很容易理解,核心的东西都是我们经常用到的主要就是应用,在实际运行中观察有什么差异。
Jsonobject.getString("username")
这个就是json去解析字符串,当然是符合json语法的字符串。
其中获取的语法有两种,这里的getString(),当键值对里的value为空时,是会出现错误的。
但是optString(),当value为空时,并不会出错,会自动为该key附一个特定的值,这里用法的取舍就在于工程的需求了。
到这如果你觉得就结束的话,你会发现大错特错,这只是初步的JSON解析。以后会陆陆续续的完善。