Maison > Applet WeChat > Développement WeChat > le corps du texte

Explication détaillée de la méthode d'accès préliminaire de WeChat jsapi et java développée par WeChat

高洛峰
Libérer: 2017-03-26 14:08:42
original
2241 Les gens l'ont consulté

Nom du paramètre

http://www.php.cn/wiki/835.html" target="_blank">width="346" valign="top" style="word-break:break-all">  描述
appId 应用ID 登录微信公众号管理平台可查询
timestamp  必填,生成签名的时间戳 
nonceStr 必填,生成签名的随机串 
signature 必填,签名,见附录1 

Les paramètres du tableau ci-dessus ont été expliqués très clairement dans le chapitre précédent. La raison pour laquelle nous créons un tableau est que si nous voulons réussir. Accédez à WeChatjsapiCes quatre paramètres sont des identifiants, ce qui équivaut à une porte qui doit avoir quatre clés pour s'ouvrir. L'une d'elles est indispensable. .

Le cas suivant utilise la page de saut créée par le servlet de Java. SpringMVC n'est pas utilisé. Vous pouvez remplacer le chemin demandé par le chemin du contrôleur.

Code WxJsAPIServlet :

45 CHF其中参数就是请求的servlet地址并跳转到调用微信jsapi的jsp界面。

package com.test;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Map;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.test.util.JsapiTicketUtil;

import com.test.util .Sign;

public class WxJsAPIServlet extends HttpServlet {

/**

     * Constructeur de l'objet.

     */

    public WxJsAPIServlet( ) {

        super();

    }

/**

     * Destruction de la servlet. 

     */

    public void destroy() {

        super.destroy(); // Mette juste "destroy" chaîne dans log

        // Mettez votre code ici

    }

    /**

     * La méthode doGet de la servlet. 

     *

     * Cette méthode est appelée lorsque un formulaire a sa valeur de balise la méthode est égale à obtenir.

     * 

     * @param demander la requête envoyer par le client au serveur

     * @param response la réponse envoie par le serveur au client

     * @throws ServletException si une erreur s'est produite

     * @throws IOException si une erreur s'est produite

     */

    public void doGet(HttpServletRequest request, HttpServletResponse response)

            lance ServletException, IOException {

        System.out.println("wxJSAPI= ========= ==========");

        String jsapi_ticket =JsapiTicketUtil.getJSApiTicket();;

        Map map = Sign.sign(jsapi_ticket, "http://www.vxzsk.com/weChat/wxJsAPIServlet");

        String timestamp = map.get("timestamp");

        String nonceStr = map.get("nonceStr");

        String signature = map.get("signature");

        String appId = "应用Id";

        request .setAttribute("appId", appId);

        request.setAttribute("timestamp", timestamp);

        request.setAttribute("signature", signature);

request.setAttribute("nonceStr", nonceStr);

        request.getRequestDispatcher("jsapi/jsapi.jsp").forward(request, response);

    }

    /**

     * La méthode doPost de la servlet. 

     *

     * Cette méthode est appelée quand un formulaire a sa valeur de balise method est égale à post.

     * 

     * @param demande la requête envoyée par le client au serveur

     * /

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            lance ServletException, IOException {

       this.doGet(request, response);

       }

/**

     * Initialisation de la servlet. 

     *

     * @throws ServletException si une erreur se produit

     */

    public void init() lance ServletException {

        // Mettez votre code ici

    }

}

第44行是生成 jsapi_ticket的工具类,在下面有贴出工具类的代码。
第49行appId替换成你自己的应用id,如果不知道应用id 可登陆微信公众平台管理中心查询。

servlet对应的web.

xml

代码

    Ceci est la description de mon composant J2EE

    This is the description of my J2EE component

    display-name>This is the display name of my J2EE component

    WxJsAPIServlet

    com.test.WxJsAPIServlet

  

    WxJsAPIServlet

    /wxJsAPIServlet

  

    affichage

- name>Il s'agit du nom d'affichage de mon composant J2EE
    WxJsAPIServlet    com. test.WxJsAPIServlet  
    WxJsAPIServlet> ;    /wxJsAPIServlet  生成签名算法类Sign代码 :
Classe d'outils JsapiTicketUtil code qui génère les paramètres jsapi_ticket

package com.test.util;

/***

*Base de connaissances en forme de V www.vxzsk.com

*/

import java.util.UUID;

importer java.util.Map;

importer java.util.HashMap;

importer java.util.Formatter;

importer java.security.MessageDigest ;

import java.security.NoSuchAlgorithmException;

import java.io.UnsupportedEncodingException;  

  public class Sign {

    public statique Map sign(String jsapi_ticket, String url) {

        Carte ret = new HashMap();

        String nonce_str = create_nonce_str();

        String timestamp = create_timestamp();

        String string1 ;

        String signature = "";

        //注意这里参数名必须全部小写,且必须有序

        string1 = "jsapi_ticket=" + jsapi_ticket +

"&noncestr=" + nonce_str +

                  "×tamp=" + timestamp +

                 "&url=" + url;

        System.out.print ln(chaîne1);

        essayer

        {

            MessageDigest crypt = MessageDigest.getInstance("SHA-1");

             crypt.réinitialiser ();

            crypt.update(string1.getBytes("UTF-8"));

            signature = byteToHex(crypt.digest() );

        }

        catch (NoSuchAlgorithmException e)

        {

            e.printStackTrace();

        }

        catch (UnsupportedEncodingException e)

        {

            e.printStackTrace();

         }

        ret.put(" "url", url);

        ret.put("jsapi_ticket", jsapi_ticket);

        ret.put("nonceStr", nonce_str);

        ret.put("timestamp", timestamp) ;

        ret.put("signature", signature);

        return ret;

    }

    chaîne statique privée byteToHex (final byte[] hash) {

        Formatter formatter = new Formatter();

        pour (octet b : hash)

        {

            formatter.format("%02x", b);

        }

String result = formatter.toString();

formatter.close();

return result;

}

private static String create_nonce_str () {

return UUID.randomUUID().toString();

}

private static String create_timestamp() {

return Long.toStr ing (System.currentTimeMillis() / 1000);

}

public static void main(String[] args) {

String jsapi_ticket = JsapiTicketUtil .getJSApiTicket();

                   // Notez que l'URL doit être obtenue dynamiquement et ne peut pas être codée en dur. /url est une

action

ou une adresse de contrôleur que vous avez demandée, et la méthode passe directement à l'adresse jsp utilisant jsapi Map ret = sign(jsapi_ticket, url);

pour (entrée Map.Entry : ret.entrySet()) {

System.out.println(entry.getKey() + ", " + Entry.getValue());

}

};

}

package com.test.util;

import java.io.BufferedReader;

import java.io.IOException;

importer java.io.InputStreamReader;

importer java.net.MalformedURLException;

importer java.net.URL;

importer java.net.URLConnection;

import net.sf.json.JSONObject;

import com.test.weixin.TestAcessToken;

classe publique JsapiTicketUtil {

    /***

* Simuler la demande d'obtention

* @param url

* @param charset

* @param timeout

* @return

*/

     public static String sendGet(String url, String charset, int timeout)

      {

        String result = "";

        essayer

        {

         URL u = new URL(url);

          essayer

          {

            URLConnection conn = u.openConnection();

            conn.connect();

            conn.setConnectTimeout(timeout);

            BufferedReader dans = new BufferedReader(new InputStreamReader (conn.getInputStream (), charset));

            String line="";

           while ((line = in.readLine()) != null)

            {

             result = result + line;

            }

             in.close();

          } catch (IOException e) {

            retourner le résultat ;

          }

         }

        catch (M alformedURLException e)

        {

          retourner le résultat;

         }

        retourner le résultat ;

       }

     public static String getAccessToken(){

            String appid="你公众号基本设置里的应用id";//应用ID

            String appSecret="你公众号基本设置里的应用密钥";//(应用密钥)

            String url ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+appSecret+"";

            String backData=TestAcessToken.sendGet(url, "utf-8", 10000);

            String accessToken = (String) JSONObject.fromObject(backData).get("access_token");  

            return accessToken ;

     }

    public static String getJSApiTicket(){ 

//Obtenir le jeton

String acess_token= JsapiTicketUtil.getAccessToken();

String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/ getticket?access_token="+acess_token+"&type=jsapi";

String backData=TestAcessToken.sendGet(urlStr, "utf-8", 10000);

String ticket = (String) JSONObject .fromObject(backData).get("ticket");

billet aller-retour

}

public static void main(String[] args) {

String jsapiTicket = JsapiTicketUtil.getJSApiTicket();

System.out.println("Le ticket pour appeler WeChat jsapi est : "+jsapiTicket);

}

>

Il existe une méthode pour obtenir access_token dans le code ci-dessus, veuillez modifier vos propres paramètres

code jsapi.jsp

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request .getServerPort()+chemin+"/";

%>

HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

  head>

    ">

    

微信jsapi测试-V型知识库

    viewport" content="width=320.1,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">

   < ;script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js">  

  

  

  

;/ h3>

  

     

timestamp:${ timestamp}

  

     

nonceStr:${ nonceStr}

  

     

signature:${ signature}

  

     

appId:${ appId}

  

    onclick="uploadImg();"/>  

    获取当前位置" onclick="getLocation();"/>  

  

  

  wx.config({  

    debug : true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。  

    appId : '${appId}', // 必填,公众号的唯一标识  

    horodatage : '${ horodatage}' , // 必填,生成签名的时间戳  

    nonceStr: '${ nonceStr}', // 必填,生成签名的随机串  

    sign nature : '${ signature}' ,// 必填,签名,见附录1  

    jsApiList : ['chooseImage','getLocation','openLocation'] // 必填,需要使用的JS接口列,所有JS接口列表见附录2  

});  

wx.ready(function(){  

    alert("ready");  

});  

wx.error(function (res) {

  alert("调用微信jsapi返回的状态:"+res.errMsg);

});

function uploadImg() {  

    wx.checkJsApi({  

        jsApiList : ['chooseImage','openLocation','getLocation'], // 需要检测的JS接口列表,所有JS接口列表见附录2,  

        succès : fonction(res) {  

             // 以键值对的形式返回,可用的api值true,不可用为faux  

                                                                                                                                     .chooseImage ({

Nombre

 : 1, // Par défaut 9

SizeType : ['Original', 'Compressed'], // Cela peut être spécifié si l'image originale ou le graphique compressé, la valeur par défaut est les deux

sourceType: ['album', 'camera'], // Vous pouvez spécifier si la source est l'album ou l'appareil photo, la valeur par défaut est les deux

success: function (res ) {

var localIds = res.localIds; // Renvoie la liste d'identifiants locaux de la photo sélectionnée, localId peut être affiché comme l'attribut src

de la balise

img

Image alert(localIds); }

}); 🎜> }  

});  

}

function getLocation() {

var latitude = ""

var longitude; = "";

wx.getLocation({

type : 'gcj02', // La valeur par défaut est les coordonnées GPS de wgs84. Si vous souhaitez renvoyer les coordonnées de Mars directement pour openLocation, vous pouvez passer dans 'gcj02'

success: function (res) {

            latitude = res.latitude; // Latitude, nombre à virgule flottante, la plage est 90 ~ -90                                                                                                                                                                                  La latitude, qui est le nombre à virgule flottante, la plage est de 90 à -90.

var speed = res.speed; // Vitesse en mètres par seconde

var précision = res.accuracy; // Précision de la position

wx .openLocation( {

                                                                                                                                  latitude, // Latitude, nombre à virgule flottante, plage comprise entre 90 et -90

nom : 'Votre emplacement actuel', // Nom de l'emplacement

adresse : ' currentLocation', // Détails de l'adresse

échelle : 26, //

Carte

Niveau de zoom, valeur de mise en forme, allant de 1 à 28. La valeur par défaut est maximale

.

Infourl : '' // hyperlien , vous pouvez cliquer pour sauter

}) en bas de l'interface de position > }); 🎜>

Scénario de test : ouvrez le compte officiel WeChat, cliquez sur le menu pour répondre avec l'adresse du servlet de la demande, accédez à l'adresse du lien de l'interface jsapi.jsp, puis l'interface apparaîtra jusqu'à appeler WeChat jsapi avec succès Ou des informations sur la fenêtre ayant échoué, le code suivant est donc nécessaire :

WeChatServlet est un servlet connecté à WeChat. Les étudiants qui ne sont pas sûrs peuvent apprendre notre tutoriel de développement WeChat.

package com.test;

import java.io.IOException;

import java.io.PrintWriter;

importer java.util.Date;

importer java.util.Map;

importer javax.servlet.ServletException;

importer javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.test.message.resp.TextMessage;

import com.test.util.MessageUtil;

/**

* Classe de traitement des requêtes de base

* Il y a weixinTest dans la méthode doGet. Il s'agit du jeton défini par vous-même dans la plateforme de gestion publique. Chacun le remplace selon son propre jeton

.

*/

classe publique WeChatServlet étend HttpServlet {

    privée statique finale long serialVersionUID = 1508798736675904038L;

    /**

* Confirmez que la demande provient du serveur WeChat

*/

    public void doGet(HttpServletRequest request, HttpServletResponse response) lance ServletException, IOException {

        System.out.println(" V型知识库原创www.vxzsk.com");

        // 微信加密签名

        S tring signature = request.getParameter("signature");

        Système. out.println("微信加密签名signature:-----------------------"+signature);

        // 时间戳

        String timestamp = request.getParameter("timestamp");

        System.out.println("时间戳timestamp:----------------- ------"+timestamp);

        // 随机数

        String nonce = request.getParameter("nonce");

        System.out.println ("随机数nonce:-----------------------"+nonce);

        // 随机字符串

        String echostr = request.getParameter("echostr");

        System.out.println("随机字符串echostr:------------- ----------"+echostr);

        //System.out.println("token------------------- ----:"+token);

        PrintWriter out = response.getWriter();

        // 通过检验signature对请求进行校验,若校验成功则原样返回echostr ,表示接入成功,否则接入失败

        if (SignUtil.checkSignature("weixinTest",  signature, timestamp, nonce)) {

            out.print(echostr);

    }

    /**

* Traitement des messages envoyés depuis le serveur WeChat

* Il y a un lien de téléchargement pour l'exemple de code source en haut de l'article

*/

    public void doPost(HttpServletRequest request, HttpServletResponse response) lance ServletException, IOException { 

        System.out .println("V型知识库原创www.vxzsk.com");

        System.out.println("微信服务器发来消息------------");

        // 将请求、响应的编码均设置为UTF-8(防止中文乱码)

        request.setCharacterEncoding("UTF-8" );

         réponse. setCharacterEncoding("UTF-8");

String respMessage = null;

try{

//analyse de la requête XML

Map requestMap = MessageUtil.parse Xml(request);/ / Recevez le format XML envoyé depuis WeChat 🎜>

String toUserName = requestMap.get("ToUserName");

//Type de message

String msgType = requestMap.get("MsgType ");

//Heure de création du message

String createTime = requestMap.get("CreateTime");

//Contenu publié par le serveur WeChat

String weixinContent = requestMap. get ("Content");

System.out.println("Contenu du message texte envoyé par les utilisateurs du compte public : "+weixinContent);

//Suivant nous utilisons le chapitre précédent Classe d'outils auto-encapsulées

if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {//Type de texte réponse de l'utilisateur "hh" WeChat répond automatiquement à ce message

/ /Répondre avec un message texte de saut de ligne > textMessage. setCreateTime(new Date().getTime());

textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);

textMessage.setFuncFlag(0);

//Répondre à l'utilisateur La chaîne de nouvelle ligne n représente une nouvelle ligne

                        StringBuffer   buffer   =   new   StringBuffer();                                                                              utiliser ' s '     en utilisant ‐ à ‐ ‐n‐ représente un saut de ligne

buffer.append("Bienvenue").append("n");

buffer.append("Interface de test WeChat jsapi").append("nn");

buffer.append("Ce message peut être affiché en répondant avec le mot 'hh'");

>

else

{

buffer.append("Bonjour, je suis une base de connaissances en forme de V");

}

textMessage. setContent(buffer.toString());

respMessage = MessageUtil.textMessageToXml(textMessage);//Convertir au format XML

}

//Message de réponse de réponse

PrintWriter out = réponse.getWriter();

out.print(respMessage); out.close();

}catch(Exception e) {

e.printStackTrace();

}

}

}

Classe d'outils MessageUtil

package com.test.util;

import java.io.InputStream;

import java.io.Writer;

importer java.util.HashMap;

importer java.util.List;

importer java.util.Map;

importer javax.servlet.http. HttpServletRequest;

import org.dom4j.Document;

import org.dom4j.Element;

import org.dom4j.io.SAXReader;

importer com.test.message.resp.Article;

importer com.test.message.resp.MusicMessage;

importer com.test.message.resp.NewsMessage;

importer com.test.message.resp.TextMessage;

importer com.thoughtworks.xstream.XStream;

importer com.thoughtworks.xstream.core.util.QuickWriter ;

importer com.thoughtworks.xstream.io.HierarchicalStreamWriter;

importer com.thoughtworks.xstream.io.xml.PrettyPrintWriter;

importer com.thoughtworks.xstream. io.xml.XppDriver;

/**

*Classe d'outil de message

*/

classe publique MessageUtil {

    /**

*Type de message de retour : texte

*/

public static final String RESP_MESSAGE_TYPE_TEXT = "text";

    /**

*Type de message de retour : Musique

*/

    public static-final String RESP_MESSAGE_TYPE_MUSIC = "music";

    /**

*Type de message de retour : graphique

*/

    public static final String RESP_MESSAGE_TYPE_NEWS = "actualités";

    /**

*Type de message de demande : texte

*/

    public static final String REQ_MESSAGE_TYPE_TEXT = "text";

    /**

* Type de message de demande : Photo

*/

    public static final String REQ_MESSAGE_TYPE_IMAGE = "image";

    /**

*Type de message de demande : lien

*/

public static final String REQ_MESSAGE_TYPE_LINK = "lien";

    /**

* Type de message de demande : localisation géographique

*/

    public static final String REQ_MESSAGE_TYPE_LOCATION = "emplacement";

    /**

* Type de message de demande : Audio

*/

    public static final String REQ_MESSAGE_TYPE_VOICE = "voice";

    /**

* Type de message de demande : push

*/

    public static final String REQ_MESSAGE_TYPE_EVENT = "événement";

    /**

*Type d'événement : s'abonner

*/

    public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";

    /**

*Type d'événement : désabonnement (désabonnement)

*/

public static final String EVENT_TYPE_UNSUBSCRIBE = "désabonnement";

    /**

* Type d'événement : CLIC ( Menu personnalisé événement de clic)

*/

    public static-final String EVENT_TYPE_CLICK = "CLICK";

    /**

     * 解析微信发来的请求(XML)

     * 

     * @param request

     * @return

     * @lancements Exception

*/

@SuppressWarnings("unchecked")

public static Map parseXml (requête HttpServletRequest) lève une exception {

// Analysera Le résultat est stocké dans HashMap

Map map = new HashMap();

// Récupère le flux d'entrée de la requête

InputStream inputStream = request.getInputStream();

//Lire le flux d'entrée

Lecteur SAXReader = new SAXReader();

Document document = reader.read(inputStream) ;

// Récupère l'élément racine XML

Element root = document.getRootElement();

// Récupère tous les nœuds enfants de l'élément racine

List elementList = root.elements();

// Parcourez tous les nœuds enfants

pour (Element e : elementList) {

map.put( e.getName( ), e.getText());

}

// Libérer les ressources

inputStream.close();

inputStream = null;

return map;

}

/**

* Objet message texte converti en XML

* @param textMessage Objet message texte

* @return xml

*/

public static String textMessageToXml(TextMessage textMessage) {

xstream .alias("xml", textMessage.getClass());

return xstream.toXML(textMessage);

}

/**

* Objet message musical converti en XML

* @param musicMessage Objet message musical

* @return xml

*/

public static String musicMessageToXml(MusicMessage musicMessage) {

xstream.alias("xml", musicMessage.getClass());

return xstream.toXML( musicMessage);

}

/**

* Convertir un objet de message graphique en XML

* @param newsMessage Objet de message graphique

* @return xml

*/

public static String newsMessageToXml(NewsMessage newsMessage) {

xstream.alias(" xml", newsMessage .getClass());

xstream.alias("item", new Article().getClass());

return xstream.toXML(newsMessage);

}

/**

* Étendre xstream pour prendre en charge les blocs CDATA

* @date

*/

privé statique XStream xstream = new XStream(new XppDriver() {

public HierarchicalStreamWriter createWriter(Writer out ) {

renvoie le nouveau PrettyPrintWriter(out) {

                // 对所有xml节点的转换都增加CDATA标记

                boolean cdata = true;

                @SuppressWarnings("unchecked")

                public void startNode(String nom, Class clazz) {

                    super.startNode(name, clazz);

                }

                 protected voidwrite Text(QuickWriter écrivain, String text) {

                    if (cdata) {

                       writer.write("

                        writer.write(text);

                        writer.write(" ]]>");

                     } else {

                       writer.write(text);

                    }

                >

            } ;

        }

    });

}

TextMessage代码

package com.test.message.resp;

public class TextMessage extends BaseMessage {

    // 回复的消息内容

    private String Content;

    public String getContent() {

        return Content;

    }

    public void setContent(String content) {

        Content = content;

    }

}

package com.test.message.resp;
classe publique TextMessage étend BaseMessage {    // 回复的消息内容    chaîne privée de contenu ;    chaîne publique getContent() {        return Content ;    }    public void setContent(String content) {         Content = content;    }}BaseMessage代码

package com.test.message.resp;

/**

 * 消息基类(公众帐号 -> 普通用户)

 */

public class BaseMessage {

    // 接收方帐号(收到的OpenID)

    private String ToUserName;

    // 开发者微信号

    private String FromUserName;

    // 消息创建时间 (整型)

    private long CreateTime;

    // 消息类型(text/music/news)

    private String MsgType;

    // 位0x0001被标志时,星标刚收到的消息

    private int FuncFlag;

    public String getToUserName() {

        return ToUserName;

    }

    public void setToUserName(String toUserName) {

        ToUserName = toUserName;

    }

    public String getFromUserName() {

        return FromUserName;

    }

    public void setFromUserName(String fromUserName) {

        FromUserName = fromUserName;

    }

    public long getCreateTime() {

        return CreateTime;

    }

    public void setCreateTime(long createTime) {

        CreateTime = createTime;

    }

    public String getMsgType() {

        return MsgType;

    }

    public void setMsgType(String msgType) {

        MsgType = msgType;

    }

    public int getFuncFlag() {

        return FuncFlag;

    }

    public void setFuncFlag(int funcFlag) {

        FuncFlag = funcFlag;

    }

}

L'effet est le suivant :

Explication détaillée de la méthode daccès préliminaire de WeChat jsapi et java développée par WeChat

Explication détaillée de la méthode daccès préliminaire de WeChat jsapi et java développée par WeChat

Explication détaillée de la méthode daccès préliminaire de WeChat jsapi et java développée par WeChat

Explication détaillée de la méthode daccès préliminaire de WeChat jsapi et java développée par WeChat

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!