利用反射机制,封装 SAX解释类,从而解释网络xml文件
个人觉得,在android应用开发领域中,与服务器交互是必不可少的。一般都是以解释xml为主要。其实获取网络上的xml和获取本地xml原理一样,只是获取网络xml 多了一层http协议,只要大家懂得怎样发送请求和怎样获取网络数据,就能很好地做出一个网络交互应用!纯属个人见解,有说得不对的地方,多多提出。。
好了,切入正题,以下是利用java的反射机制,来封装 SAX解释类,从而解释网络xml文件,假如网络访问地址,http://localhost:8080/MyJsp.jsp 会返回一个xml文件.
首先;创建一个javabean类,这个类中的成员属性必须与xml标签一致。如果返回的xml文件如下:
然后创建一个实体类,特别注意:成员变量与标签一致。如下
再后,编写封装类:
import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.URL; import java.sql.Date; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * 封闭类 * 利用 SAX 解析xml文件 * * @author Administrator * */ public class SAXParserContentHandler extends DefaultHandler { private Object javaBean = null; // 标签名称 private String tag; List<Object> list = null; /** * 用 SAX 解析xml文件 * * @param strUrl * 网络xml地址 * @param javaBean * 实体类对象 * @return List 返回实体类的一个list集合 * @throws Exception */ public List<Object> parseReadXml(String strUrl, Object javaBean) throws Exception { this.javaBean = javaBean; // 要从网络上获取xml,要定义一个URL类对象 URL url = new URL(strUrl); // 打开连接,。会返回HttpsURLConnection 对象 HttpURLConnection httpsURLConnection = (HttpURLConnection) url .openConnection(); // 现在是使用HTTP协议请求服务器的数据 // 所以要设置请求方式 httpsURLConnection.setRequestMethod("GET"); // 设置 超时时间 为5秒 httpsURLConnection.setConnectTimeout(5 * 1000); // 通过输入流获取网络xml内容 // 取得输入流 InputStream inputStream = httpsURLConnection.getInputStream(); SAXParserFactory parserFactory = SAXParserFactory.newInstance(); // 取得SAXParser 实例 SAXParser parser = parserFactory.newSAXParser(); parser.parse(inputStream, this); return list; } @Override public void characters(char[] ch, int start, int length) throws SAXException { if (null != tag && !"".equals(tag)) { if (javaBean != null) { String data = new String(ch, start, length); Field[] fields = javaBean.getClass().getDeclaredFields(); for (int i = 0; i < fields.length; i++) { if (tag.equals(fields.getName())) { // System.out.println(fields.getName()+" --- fields.getName(); -- "+fields.getType()); setAttribute(javaBean, fields.getName(), data, new Class[] { fields.getType() }); } } } } } @Override public void endDocument() throws SAXException { } @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println(" endElement " + localName); if (null != localName && !"".equals(localName)) { String bean = updateSmall(javaBean.getClass().getSimpleName()); if (bean.equals(localName) && bean != null) { list.add(javaBean); } } tag = null; } @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub list = new ArrayList<Object>(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println(" startElement " + localName); tag = qName; // 取得实体类简单名称,把首字母变为小 写 String bean = updateSmall(javaBean.getClass().getSimpleName()); // System.out.println("bean -- "+bean); // 取得实体类的 全限 名称 String clazz = javaBean.getClass().getName(); // System.out.println("clazz -- "+clazz); if (bean.equals(qName)) { try { javaBean = Class.forName(clazz).newInstance(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } Field[] fields = javaBean.getClass().getDeclaredFields(); for (int i = 0; i < attributes.getLength(); i++) { System.out.println(attributes.getQName(i)+" -- attributes -- "+attributes.getValue(i)); for (int j = 0; j < fields.length; j++) { if (attributes.getQName(i).equals(fields[j].getName())) { setAttribute(javaBean, attributes.getQName(i), attributes.getValue(i), new Class[] { fields[j].getType() }); System.out.println(fields[j].getName()+" --- fields.getName(); -- "+fields[j].getType().getName()); } } } } } /** * * @param object * 类 * @param setName * 方法名 * @param setValue * 方法设置 * @param obj * 属性类型 * @throws Exception */ public void setAttribute(Object object, String setName, String setValue, Class[] obj) { Method method; try { method = object.getClass().getMethod("set" + updateStr(setName), obj[0]); if (obj[0].equals(Integer.class) || obj[0].equals(int.class)) { method.invoke(object, new Integer(setValue)); } if (obj[0].equals(Float.class) || obj[0].equals(float.class)) { method.invoke(object, new Float(setValue)); } if (obj[0].equals(Short.class) || obj[0].equals(short.class)) { method.invoke(object, new Short(setValue)); } if (obj[0].equals(Byte.class) || obj[0].equals(byte.class)) { method.invoke(object, new Byte(setValue)); } if (obj[0].equals(Double.class)|| obj[0].equals(double.class)) { method.invoke(object, new Double(setValue)); } if (obj[0].equals(Date.class)) { method.invoke(object, new Date(new Long(setValue))); } if (obj[0].equals(java.util.Date.class)) { method.invoke(object, new java.util.Date(setValue)); } if (obj[0].equals(Long.class)|| obj[0].equals(long.class)) { method.invoke(object, new Long(setValue)); } if (obj[0].equals(Boolean.class)|| obj[0].equals(boolean.class)) { method.invoke(object, new Boolean(setValue)); } if (obj[0].equals(String.class)) { method.invoke(object, setValue); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 把字符串的首字母改为大写 * * @param str * : * @return String */ public String updateStr(String str) { char c = (char) (str.charAt(0) - 32); String s = str.substring(1, str.length()); return c + s; } /** * 把字符串的首字母改为小写 * * @param str * : * @return String */ public String updateSmall(String str) { char c = (char) (str.charAt(0) + 32); String s = str.substring(1, str.length()); return c + s; } }
以上的封装类已经有详细注释,最后就是怎样得到想要的数据。
1:实例化 实体类
2:实例化封装类
3:把实例化类加入到contentHandler.parseReadXml方法中,如下
SAXParserContentHandler contentHandler = new SAXParserContentHandler(); Video video =new Video(); List<Object> list = contentHandler.parseReadXml("http://0029.freejsp.net/0105/MyJsp.jsp",video); for (Object object : list) { video = (Video)object; System.out.println(video); }
最后,遍历list集合,就可以得到你想要的数据.个人觉得,这样方便很多,不用再一个一个标签去比较,省下了很多时间。
欢迎Andriod开发热爱着加入群交流,共同进步。西安群252746034北京群111059554深圳群252742753