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) {
...
}
}
}