热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

AndroidWebService(基于SOAP协议)

packagecom.nenglong.wsclient;importjava.io.IOException;importorg.ksoap2.SoapEnvelope;import

package com.nenglong.wsclient;

import java.io.IOException;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.StrictMode;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

/**
* @author huanglong Android 平台调用WebService(手机号码归属地查询)
*/
public class MainActivity extends Activity {
private TextView tv_result;
private EditText et_phone;
private Button btn_query;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}

private void initView() {
tv_result = (TextView) findViewById(R.id.result_text);
et_phOne= (EditText) findViewById(R.id.et);
btn_query = (Button) findViewById(R.id.btn_query);
btn_query.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String phOne= et_phone.getText().toString().trim();
if ("".equals(phone) || phone.length() <7) {
et_phone.setText("您输入的手机号码有误");
et_phone.requestFocus();
tv_result.setText("");
return;
}
getRemoteInfo(phone);
}
});
}

/**
* 查询号码段归属地的方法
*
* @param phone
* 手机号码段
*/
public void getRemoteInfo(final String phone) {
new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
// 命名空间
String nameSpace = "http://WebXml.com.cn/";
// 调用方法的名称
String methodName = "getMobileCodeInfo";
// EndPoint
String endPoint = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx";
// SOAP Action
String soapAction = "http://WebXml.com.cn/getMobileCodeInfo";
// 指定WebService的命名空间和调用方法
SoapObject soapObject = new SoapObject(nameSpace, methodName);
// 设置需要调用WebService接口的两个参数mobileCode UserId
soapObject.addProperty("mobileCode", phone);
soapObject.addProperty("userId", "");
// 生成调用WebService方法调用的soap信息,并且指定Soap版本
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER10);
envelope.bodyOut = soapObject;
// 是否调用DotNet开发的WebService
envelope.dotNet = true;
envelope.setOutputSoapObject(soapObject);
HttpTransportSE transport = new HttpTransportSE(endPoint);
try {
transport.call(soapAction, envelope);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 获取返回的数据
SoapObject object = (SoapObject) envelope.bodyIn;
// 获取返回的结果
String result = object.getProperty(0).toString();
Message message = handler.obtainMessage();
message.obj = result;
handler.sendMessage(message);
}
}).start();
}
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
// 将WebService得到的结果返回给TextView
tv_result.setText(msg.obj.toString());
};
};
}

         webService:基于SOAP协议的远程调用标准,通过webService可以将不用的操作系统平台,不同的计算机语言,不同的技术整合到一起。

        调用webService需要导入jar包:ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar包,这个包在网上可以下载,至于导入的方法 ,右键项目,选择最后一项properties-->Java build path-->Libraies-->Add external Jars   选择相应的路径下的jar文件就OK了,然后记得在Order and Export 里面将选择的jar文件勾选上。

      调用webService的步骤分为7个:

1. 实例化soapObject对象,指定Soap的命名空间(从相关文档中可以查看WSDL命名空间以及调用方法)

View Code 

//命名空间
private static final String serviceNameSpace="http://WebXml.com.cn/";
//调用方法(获得支持的城市)
private static final String getSupportCity="getSupportCity";

//实例化SoapObject对象
SoapObject request=new SoapObject(serviceNameSpace, getSupportCity);

2.假设方法有参数的话,添加调用的方法的参数

request.addProperties("参数名称","参数值");

3.设置SOAP请求信息(参数部分为SOAP版本号,与自己要调用的SOAP版本必须一致,也就是你导入到工程中的jar相对应的版本)

//获得序列化的Envelope
SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut=request;
4.注册Enelope

(new  MarshalBase64()).register(envelope);

5.构建传输对象,并指定WDSL文档中的URL

//请求URL
private static final String serviceURL="http://www.webxml.com.cn/webservices/weatherwebservice.asmx";
//Android传输对象
AndroidHttpTransport transport=new AndroidHttpTransport(serviceURL);
transport.debug=true;

6.调用webService(其中参数为1:命名空间+方法名称,envelope对象);

transport.call(serviceNameSpace+getWeatherbyCityName, envelope);

7.解析返回数据:

View Code 

if(envelope.getResponse()!=null){
return parse(envelope.bodyIn.toString());
}

/**************
* 解析XML
* @param str
* @return
*/
private static List parse(String str){
String temp;
List list=new ArrayList();
if(str!=null && str.length()>0){
int start=str.indexOf("string");
int end=str.lastIndexOf(";");
temp=str.substring(start, end-3);
String []test=temp.split(";");

for(int i=0;i if(i==0){
temp=test[i].substring(7);
}else{
temp=test[i].substring(8);
}
int index=temp.indexOf(",");
list.add(temp.substring(0, index));
}
}
return list;
}

这样就成功了,这里有个地址是提供Webservice天气预报服务的,我们这里只提供了获取城市列表:

View Code 

//命名空间
private static final String serviceNameSpace="http://WebXml.com.cn/";
//请求URL
private static final String serviceURL="http://www.webxml.com.cn/webservices/weatherwebservice.asmx";
//调用方法(获得支持的城市)
private static final String getSupportCity="getSupportCity";
//调用城市的方法(需要带参数)
private static final String getWeatherbyCityName="getWeatherbyCityName";
//调用省或者直辖市的方法(获得支持的省份或直辖市)
private static final String getSupportProvince="getSupportProvince";
在浏览器中输入WSDL  serverUrl 就可以看到一些可供调用的方法:

我们选择国内外主要城市或者省份的调用方法:getSurpportPrivence(),然后调用之后你会发现返回给我们的是XML文档

View Code 


-
直辖市
特别行政区
黑龙江
吉林
辽宁
内蒙古
河北
河南
山东
山西
江苏
安徽
陕西
宁夏
甘肃
青海
湖北
湖南
浙江
江西
福建
贵州
四川
广东
广西
云南
海南
新疆
西藏
台湾
亚洲
欧洲
非洲
北美洲
南美洲
大洋洲

View Code public class WebServiceHelper {       //WSDL文档中的命名空间    private static final String targetNameSpace="http://WebXml.com.cn/";    //WSDL文档中的URL    private static final String WSDL="http://webservice.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl";           //需要调用的方法名(获得本天气预报Web Services支持的洲、国内外省份和城市信息)    private static final String getSupportProvince="getSupportProvince";    //需要调用的方法名(获得本天气预报Web Services支持的城市信息,根据省份查询城市集合:带参数)    private static final String getSupportCity="getSupportCity";    //根据城市或地区名称查询获得未来三天内天气情况、现在的天气实况、天气和生活指数    private static final String getWeatherbyCityName="getWeatherbyCityName";    /********     * 获得州,国内外省份和城市信息     * @return     */    public  List getProvince(){        List provinces=new ArrayList();        String str="";        SoapObject soapObject=new SoapObject(targetNameSpace,getSupportProvince);        //request.addProperty("参数", "参数值");调用的方法参数与参数值(根据具体需要可选可不选)                SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);        envelope.dotNet=true;        envelope.setOutputSoapObject(soapObject);//envelope.bodyOut=request;                        AndroidHttpTransport httpTranstation=new AndroidHttpTransport(WSDL);        //或者HttpTransportSE httpTranstation=new HttpTransportSE(WSDL);        try {                        httpTranstation.call(targetNameSpace+getSupportProvince, envelope);            SoapObject result=(SoapObject)envelope.getResponse();            //下面对结果进行解析,结构类似json对象            //str=(String) result.getProperty(6).toString();                        int count=result.getPropertyCount();            for(int index=0;index getCitys(String province){        List citys=new ArrayList();        SoapObject soapObject=new SoapObject(targetNameSpace,getSupportCity);        soapObject.addProperty("byProvinceName", province);        SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);        envelope.dotNet=true;        envelope.setOutputSoapObject(soapObject);                AndroidHttpTransport httpTransport=new AndroidHttpTransport(WSDL);        try {            httpTransport.call(targetNameSpace+getSupportCity, envelope);            SoapObject result=(SoapObject)envelope.getResponse();            int count=result.getPropertyCount();            for(int index=0;index> list=new ArrayList>();                        Map map=new HashMap();                //城市名        bean.setCityName(soapObject.getProperty(1).toString());        //城市简介        bean.setCityDescription(soapObject.getProperty(soapObject.getPropertyCount()-1).toString());        //天气实况+建议        bean.setLiveWeather(soapObject.getProperty(10).toString()+"\n"+soapObject.getProperty(11).toString());                //其他数据        //日期,        String date=soapObject.getProperty(6).toString();        //---------------------------------------------------        String weatherToday="今天:" + date.split(" ")[0];          weatherToday+="\n天气:"+ date.split(" ")[1];         weatherToday+="\n气温:"+soapObject.getProperty(5).toString();        weatherToday+="\n风力:"+soapObject.getProperty(7).toString();        weatherToday+="\n";                List icOns=new ArrayList();            icons.add(parseIcon(soapObject.getProperty(8).toString()));              icons.add(parseIcon(soapObject.getProperty(9).toString()));                 map.put("weatherDay", weatherToday);        map.put("icons",icons);        list.add(map);                                //-------------------------------------------------        map=new HashMap();         date=soapObject.getProperty(13).toString();        String weatherTomorrow="明天:" + date.split(" ")[0];          weatherTomorrow+="\n天气:"+ date.split(" ")[1];         weatherTomorrow+="\n气温:"+soapObject.getProperty(12).toString();        weatherTomorrow+="\n风力:"+soapObject.getProperty(14).toString();        weatherTomorrow+="\n";                icOns=new ArrayList();                 icons.add(parseIcon(soapObject.getProperty(15).toString()));              icons.add(parseIcon(soapObject.getProperty(16).toString()));                map.put("weatherDay", weatherTomorrow);        map.put("icons",icons);        list.add(map);        //--------------------------------------------------------------        map=new HashMap();                 date=soapObject.getProperty(18).toString();        String weatherAfterTomorrow="后天:" + date.split(" ")[0];          weatherAfterTomorrow+="\n天气:"+ date.split(" ")[1];         weatherAfterTomorrow+="\n气温:"+soapObject.getProperty(17).toString();        weatherAfterTomorrow+="\n风力:"+soapObject.getProperty(19).toString();        weatherAfterTomorrow+="\n";                icOns=new ArrayList();        icons.add(parseIcon(soapObject.getProperty(20).toString()));              icons.add(parseIcon(soapObject.getProperty(21).toString()));                map.put("weatherDay", weatherAfterTomorrow);        map.put("icons",icons);        list.add(map);         //--------------------------------------------------------------                bean.setList(list);        return bean;    }         //解析图标字符串     private int parseIcon(String data){        // 0.gif,返回名称0,         int resID=32;         String result=data.substring(0, data.length()-4).trim();          // String []icon=data.split(".");          // String result=icon[0].trim();          //   Log.e("this is the icon", result.trim());                     if(!result.equals("nothing")){               resID=Integer.parseInt(result.trim());           }         return resID;         //return ("a_"+data).split(".")[0];      } }
以及帮助类:

View Code 

public class WebServiceUtil {

//命名空间
private static final String serviceNameSpace="http://WebXml.com.cn/";
//请求URL
private static final String serviceURL="http://www.webxml.com.cn/webservices/weatherwebservice.asmx";
//调用方法(获得支持的城市)
private static final String getSupportCity="getSupportCity";
//调用城市的方法(需要带参数)
private static final String getWeatherbyCityName="getWeatherbyCityName";
//调用省或者直辖市的方法(获得支持的省份或直辖市)
private static final String getSupportProvince="getSupportProvince";

/*************
* @return城市列表
*************/
public static List getCityList(){
//实例化SoapObject对象
SoapObject request=new SoapObject(serviceNameSpace, getSupportCity);
//获得序列化的Envelope
SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut=request;
(new MarshalBase64()).register(envelope);
//Android传输对象
AndroidHttpTransport transport=new AndroidHttpTransport(serviceURL);
transport.debug=true;

//调用
try {
transport.call(serviceNameSpace+getWeatherbyCityName, envelope);
if(envelope.getResponse()!=null){
return parse(envelope.bodyIn.toString());
}

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


return null;
}


public static List getProviceList(){
//实例化SoapObject对象
SoapObject request=new SoapObject(serviceNameSpace, getSupportProvince);
//获得序列化的Envelope
SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut=request;
(new MarshalBase64()).register(envelope);
//Android传输对象
AndroidHttpTransport transport=new AndroidHttpTransport(serviceURL);
transport.debug=true;

//调用
try {
transport.call(serviceNameSpace+getWeatherbyCityName, envelope);
if(envelope.getResponse()!=null){
return null;
}

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


return null;
}

/*************
* @param cityName
* @return
*************/
public static String getWeather(String cityName){

return "";
}

/**************
* 解析XML
* @param str
* @return
*/
private static List parse(String str){
String temp;
List list=new ArrayList();
if(str!=null && str.length()>0){
int start=str.indexOf("string");
int end=str.lastIndexOf(";");
temp=str.substring(start, end-3);
String []test=temp.split(";");

for(int i=0;i if(i==0){
temp=test[i].substring(7);
}else{
temp=test[i].substring(8);
}
int index=temp.indexOf(",");
list.add(temp.substring(0, index));
}
}
return list;
}

/*********
* 获取天气
* @param soapObject
*/
private void parseWeather(SoapObject soapObject){
//String date=soapObject.getProperty(6);
}
}

以上就是显示天气预报的全部代码

转载自:http://www.cnblogs.com/zhangdongzi/archive/2011/04/19/2020688.html

还可以调用免费的WebService显示手机号码的归属地,但是每天免费的次数是有限的,同样是调用WebService

但是调用WebService的时候,因为是网络操作,在Android 4.0.3以上的版本貌似会出现异常,后经过google发现是在

新版的Android系统里面,因为对网络的访问限制的更加严格,所以会报NetWorkOnMainThreadException 说的是对

于网络的访问不能放在主线程,这样的解决方案有两种,一种是开辟新的现成访问网络,call webService放在子线程中运行

还有一个解决方案是使用StricMode进行优化,strictMode有很多不同的策略进行优化,当开发者违背某个规则的时候,每个策略都

有不用的方法去提示用户。

显示号码归属地的代码:


package com.nenglong.wsclient;
import java.io.IOException;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.StrictMode;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

/**
* @author huanglong Android 平台调用WebService(手机号码归属地查询)
*/
public class MainActivity extends Activity {
private TextView tv_result;
private EditText et_phone;
private Button btn_query;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}

private void initView() {
tv_result = (TextView) findViewById(R.id.result_text);
et_phOne= (EditText) findViewById(R.id.et);
btn_query = (Button) findViewById(R.id.btn_query);
btn_query.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String phOne= et_phone.getText().toString().trim();
if ("".equals(phone) || phone.length() <7) {
et_phone.setText("您输入的手机号码有误");
et_phone.requestFocus();
tv_result.setText("");
return;
}
getRemoteInfo(phone);
}
});
}

/**
* 查询号码段归属地的方法
*
* @param phone
* 手机号码段
*/
public void getRemoteInfo(final String phone) {
new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
// 命名空间
String nameSpace = "http://WebXml.com.cn/";
// 调用方法的名称
String methodName = "getMobileCodeInfo";
// EndPoint
String endPoint = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx";
// SOAP Action
String soapAction = "http://WebXml.com.cn/getMobileCodeInfo";
// 指定WebService的命名空间和调用方法
SoapObject soapObject = new SoapObject(nameSpace, methodName);
// 设置需要调用WebService接口的两个参数mobileCode UserId
soapObject.addProperty("mobileCode", phone);
soapObject.addProperty("userId", "");
// 生成调用WebService方法调用的soap信息,并且指定Soap版本
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER10);
envelope.bodyOut = soapObject;
// 是否调用DotNet开发的WebService
envelope.dotNet = true;
envelope.setOutputSoapObject(soapObject);
HttpTransportSE transport = new HttpTransportSE(endPoint);
try {
transport.call(soapAction, envelope);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 获取返回的数据
SoapObject object = (SoapObject) envelope.bodyIn;
// 获取返回的结果
String result = object.getProperty(0).toString();
Message message = handler.obtainMessage();
message.obj = result;
handler.sendMessage(message);
}
}).start();
}
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
// 将WebService得到的结果返回给TextView
tv_result.setText(msg.obj.toString());
};
};
}







推荐阅读
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 深入理解CSS中的margin属性及其应用场景
    本文主要介绍了CSS中的margin属性及其应用场景,包括垂直外边距合并、padding的使用时机、行内替换元素与费替换元素的区别、margin的基线、盒子的物理大小、显示大小、逻辑大小等知识点。通过深入理解这些概念,读者可以更好地掌握margin的用法和原理。同时,文中提供了一些相关的文档和规范供读者参考。 ... [详细]
author-avatar
卖火柴的冰枫_939
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有