您的位置:首页 > 理论基础 > 计算机网络

Android使用Http访问并解析服务器XML数据

2017-08-21 13:10 609 查看

okhttp

使用前需添加okhttp开源库的依赖,添加方法可参考前面这篇文章

new Thread(() -> {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://127.0.0.1/a.xml")
.build();
try {
Response response = client.newCall(request).execute();
String responceData = response.body().string();
showResponce(responceData);
}
catch (IOException ioex) {
ioex.printStackTrace();
}

//            RequestBody requestBody = new FormBody.Builder()
//                    .add("username", "admin")
//                    .add("password", "123456")
//                    .build();
//            Request request1 = new Request.Builder()
//                    .url("http://www.baidu.com")
//                    .post(requestBody)
//                    .build();
//            try {
//                Response response = client.newCall(request1).execute();
//                String responceData = response.body().string();
//            }
//            catch (IOException ex) {
//                ex.printStackTrace();
//            }
}).start();


解析XML

假设有XML数据如下

<apps>
<app>
<id>1</id>
<name>Google Maps</name>
<version>1.0</version>
</app>
<app>
<id>2</id>
<name>Chrome</name>
<version>2.1</version>
</app>

</apps>


Pull

private void parseXMLWithPull(String responceData)
{
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance().newInstance();
XmlPullParser xmlparser = factory.newPullParser();
xmlparser.setInput(new StringReader(responceData));
int eventType = xmlparser.getEventType();
String id = "";
String name = "";
String version = "";
while (eventType != XmlPullParser.END_DOCUMENT) {
String nodeName = xmlparser.getName();
switch (eventType)
{
case XmlPullParser.START_TAG: {
if("id".equals(nodeName)) {
id = xmlparser.nextText();
}
else if("name".equals(nodeName)) {
name = xmlparser.nextText();
}
else if("version".equals(nodeName)) {
version = xmlparser.nextText();
}
break;
}
case XmlPullParser.END_TAG: {
if("app".equals(nodeName)) {
Log.d("MainActivity", "id is" + id);
Log.d("MainActivity", "name is" + name);
Log.d("MainActivity", "version is" + version);
}
break;
}
default:
break;
}
eventType = xmlparser.next();
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}


SAX

//创建一个类
public class MyXMLHandler extends DefaultHandler {

private String nodeName;
private  StringBuilder id;
private  StringBuilder name;
private StringBuilder version;

@Override
public void startDocument() throws SAXException {
id = new StringBuilder();
name = new StringBuilder();
version = new StringBuilder();
}                          //文本的起始

@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
nodeName = localName;
}                           //每个节点的起始

@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if("id".equals(nodeName)) {
id.append(ch, start, length);
}
else if("name".equals(nodeName)) {
name.append(ch, start, length);
}
else if("version".equals(nodeName)) {
version.append(ch, start, length);
}
}                          //每个节点文本内容的解析

@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if("app".equals(localName)) {
Log.d("Handler", "id is" + id.toString().trim());
Log.d("Handler", "name is" + name.toString().trim());
Log.d("Handler", "version is" + version.toString().trim());
id.setLength(0);
name.setLength(0);
version.setLength(0);
}
}                           //每个节点的结束

@Override
public void endDocument() throws SAXException {
super.endDocument();
}
}                              //文本的结束

//类的调用
private void parseXMLWithHandler(String responce)
{
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader xmlreader = factory.newSAXParser().getXMLReader();
MyXMLHandler handler = new MyXMLHandler();
xmlreader.setContentHandler(handler);
xmlreader.parse(new InputSource(new StringReader(responce)));
}
catch (Exception ex) {
ex.printStackTrace();
}
}


总结

其实,上面建立http连接的写法是有问题的。因为每次建立http连接都要重复以上代码,难免造成不必要的代码重复。我们想要的效果是:

String address = "...";
String responce = HttpUtil.sendRequestAddress(address);


因此我们想到的是把http协议处理的相关方法,包装到一个类中,然后在该sendRequestAddress方法中new一个Thread即可。但是这样就不能把想要的结果返回。因此,我们这里应用一个类okhttp.Callback进行回调。

public class HttpUtil {
public static void sendHttpRequest(final String address, Callback callback)
{
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(address)
.build();
client.newCall(request).enqueue(callback);
}
}


其中okhttp.Callback帮我们另外启动一个子线程处理服务器返回的数据,调用时,应用以下代码即可:

HttpUtil.sendHttpRequest("http://www.baidu.com",
new Callback() {
@Override
public void onFailure(Call call, IOException e) {
...
}

@Override
public void onResponse(Call call, Response response) throws IOException {
String responseData = response.body().string();
showResponce(responseData);
}
});


一个回调机制的简单例子

public interface HttpCallbackListener {
void onFinish(String responce);
void onError(Exception e);
}


public class HttpUtil {
public static void sendHttpRequest(final String add, HttpCallbackListener listener) {
new Thread(() -> {                        //线程进行处理,处理时间不确定
....
try {
if(listener != null) {
listener.onFinish(responce.body().string());     //调用HttpCallbackListener中的函数
}
}
catch(Exception e) {
if(listener != null) {
listener.onError(e);           //调用HttpCallbackListener中的函数
}
}
}).start();
}
}


public class testResponce {

public static showResponce(String rsponce) {
...
}

public static showError(Exception e) {
...
}
public static void main(String[] argv) {
try{
HttpUtil.sendHttpRequest(add, new HttpCallbackListener() {
@Override
void onFinish(String responce) {
showResponce(responce);                           //回调testResponce的函数
}

@Override
void onError(Exception e) {
showError(e);                                     ////回调testResponce的函数
}
});
}
catch(Exception e) {
...
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: