Java企业微信开发_09_素材管理之下载微信临时素材到本地服务器

一、本节要点

1.获取临时素材接口

请求方式:GET(HTTPS)

请求地址:https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID

2.获取临时素材接口的返回结果

企业微信官方开发文档中说明的返回结果如下:

若你以为这就是返回结果,然后跟之前一样,先访问接口,从http连接的输入流中的获取回结果的文本内容,你会发现你接收到的结果是一堆乱码。

这是为何?

以图片为例,此处千万要注意,微信返回的结果是一个文件流形式的图片,当我们从http连接的输入流中的获取回结果的文本内容,也就是获取图片的文本内容时,当然就是一堆乱码了。

这就好比你用记事本打开一张图片,然后发现内容是一片乱码。这再正常不过。所以我们接受图片的时候不能只接收文本数据,而是要接收流。

千万得注意:获取临时素材时,微信返回的结果是一个流形式的临时素材。

我们需要做的就是调用接口,获取http连接的输入流中数据,再将输入流中的数据写入到输出流,再通过输出流生成一张图片。这张图片就是微信返回的临时素材了。

3.下载文件时的文件路径

request.getSession().getServletContext().getRealPath("").replaceAll("\\\\", "/")

将获取路径:%TOMCAT_HOME%/webapp/工程名。若不是这个路径就请参考:Eclipse中的Web项目自动部署到Tomcat

String savePath=request.getSession().getServletContext().getRealPath("").replaceAll("\\\\", "/")+"/img/";

将获取路径:%TOMCAT_HOME%/webapp/工程名/img/

即从微信服务器下载的图片都保存在这个路径下。

二、代码实现

这里承接上一节。在上一节中我们完成了JSSDK的配置,并且用图片上传接口将图片上传到了微信服务器。这一节我们需要做的就是在图片上传到微信服务器后,根据微信服务器返回的serverId(即mediaId)来调用获取临时素材的接口,进行临时素材的下载,并保存到本地指定的路径下。

2.1 UploadExpenseAccaoutServlet

package com.ray.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ray.service.TempMaterialService;
import com.ray.util.WeiXinParamesUtil;
import com.ray.util.WeiXinUtil;

/**
 * Servlet implementation class UploadExpenseAccaoutServlet
 */
@WebServlet("/UploadExpenseAccaoutServlet")
public class UploadExpenseAccaoutServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public UploadExpenseAccaoutServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub

    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub

        String mediaId=request.getParameter("serverId");
        System.out.println("serverId:"+mediaId);

        String accessToken= WeiXinUtil.getAccessToken(WeiXinParamesUtil.corpId, WeiXinParamesUtil.contactsSecret).getToken();
        System.out.println("accessToken:"+accessToken);

        //String savePath=System.getProperty("user.dir").replaceAll("\\\\", "/")+"/WebContent/img/"+mediaId+".png";
        String savePath=request.getSession().getServletContext().getRealPath("").replaceAll("\\\\", "/")+"/img/";
        System.out.println("savePath:"+savePath);

        //2.调用业务类,获取临时素材
        TempMaterialService tms=new TempMaterialService();
        tms.getTempMaterial(accessToken, mediaId,savePath);

        PrintWriter out = response.getWriter();
        out.print("HHHHHHHHHH");
        out.close();
        out = null;
    }

}

在此servlet中

(1)接收serverId

(2)调用临时素材业务类的方法TempMaterialService.getTempMaterial(accessToken, mediaId,savePath),获取临时素材。

2.2 临时素材业务类—TempMaterialService

package com.ray.service;

import java.io.File;
import java.io.UnsupportedEncodingException;

import com.ray.util.WeiXinUtil;

import net.sf.json.JSONObject;

/**@desc  : 临时素材业务类
 *
 * @author: shirayner
 * @date  : 2017-8-18 下午2:07:25
 */
public class TempMaterialService {

    //上传临时素材url
    public String uploadTempMaterial_url="https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";

    //获取临时素材url
    public String getTempMaterial_url="https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";

    /**
     * @desc :上传临时素材
     *
     * @param accessToken   接口访问凭证
     * @param type   媒体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file)
     * @param fileUrl  本地文件的url。例如 "D/1.img"。
     * @return JSONObject   上传成功后,微信服务器返回的参数,有type、media_id    、created_at
     */
    public JSONObject uploadTempMaterial(String accessToken,String type,String fileUrl){
        //1.创建本地文件
        File file=new File(fileUrl);

        //2.拼接请求url
        uploadTempMaterial_url = uploadTempMaterial_url.replace("ACCESS_TOKEN", accessToken)
                .replace("TYPE", type);

        //3.调用接口,发送请求,上传文件到微信服务器
        String result=WeiXinUtil.httpRequest(uploadTempMaterial_url, file);

        //4.json字符串转对象:解析返回值,json反序列化
        result = result.replaceAll("[\\\\]", "");
        System.out.println("result:" + result);
        JSONObject resultJSON = JSONObject.fromObject(result);

        //5.返回参数判断
        if (resultJSON != null) {
            if (resultJSON.get("media_id") != null) {
                System.out.println("上传" + type + "临时素材成功:"+resultJSON.get("media_id"));
                return resultJSON;
            } else {
                System.out.println("上传" + type + "临时素材成功失败");
            }
        }
        return null;
    }

    /** 2.获取临时素材
     *
     * @param accessToken
     * @param mediaId
     * @return
     * @throws UnsupportedEncodingException
     */
    public void getTempMaterial(String accessToken,String mediaId,String savePath) throws UnsupportedEncodingException{

        //String savePath=System.getProperty("user.dir").replaceAll("\\\\", "/")+"/WebContent/img/"+mediaId+".png";
        //System.out.println("service savePath:"+savePath);

        //1.拼接请求url
        getTempMaterial_url=getTempMaterial_url.replace("ACCESS_TOKEN", accessToken)
                .replace("MEDIA_ID", mediaId);

        savePath=savePath+mediaId;
        //2.调用接口,发送请求,获取临时素材
        File file=null;
        try {
            file = WeiXinUtil.getFile(getTempMaterial_url,savePath);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("file:"+file.getName());

    }

}

在此类的获取临时素材方法中:

(1)拼接微信获取临时素材的接口url

(2)调用WeiXinUtil.getFile(getTempMaterial_url,savePath),向微信发起https请求,并将接收到的图片下载到savePath指定的路径下

2.3 微信工具类—WeiXinUtil

package com.ray.util;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ray.pojo.AccessToken;

import net.sf.json.JSONException;
import net.sf.json.JSONObject;

public class WeiXinUtil {

    private static Logger log = LoggerFactory.getLogger(WeiXinUtil.class);
    //微信的请求url
    //获取access_token的接口地址(GET) 限200(次/天)
    public final static String access_token_url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpId}&corpsecret={corpsecret}";
    //获取jsapi_ticket的接口地址(GET) 限200(次/天)
    public final static String jsapi_ticket_url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESSTOKEN";  

    /**
     * 1.发起https请求并获取结果
     *
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式(GET、POST)
     * @param outputStr 提交的数据
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
     */
    public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        try {
            // 创建SSLContext对象,并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();  

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);  

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式(GET/POST)
            httpUrlConn.setRequestMethod(requestMethod);  

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();  

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式,防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }  

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            jsonObject = JSONObject.fromObject(buffer.toString());
        } catch (ConnectException ce) {
            log.error("Weixin server connection timed out.");
        } catch (Exception e) {
            log.error("https request error:{}", e);
        }
        return jsonObject;
    }  

   /**
     * 2.发送https请求之获取临时素材
     * @param requestUrl
     * @param savePath  文件的保存路径,此时还缺一个扩展名
     * @return
     * @throws Exception
     */
    public static File getFile(String requestUrl,String savePath) throws Exception {
        //String path=System.getProperty("user.dir")+"/img//1.png";

            // 创建SSLContext对象,并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();  

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);  

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式(GET/POST)
            httpUrlConn.setRequestMethod("GET");  

            httpUrlConn.connect();  

            //获取文件扩展名
            String ext=getExt(httpUrlConn.getContentType());
            savePath=savePath+ext;
            System.out.println("savePath"+savePath);
            //下载文件到f文件
            File file = new File(savePath);

            // 获取微信返回的输入流
            InputStream in = httpUrlConn.getInputStream(); 

            //输出流,将微信返回的输入流内容写到文件中
            FileOutputStream out = new FileOutputStream(file);

            int length=100*1024;
            byte[] byteBuffer = new byte[length]; //存储文件内容

            int byteread =0;
            int bytesum=0;

            while (( byteread=in.read(byteBuffer)) != -1) {
                bytesum += byteread; //字节数 文件大小
                out.write(byteBuffer,0,byteread);  

            }
            System.out.println("bytesum: "+bytesum);

            in.close();
            // 释放资源
            out.close();
            in = null;
            out=null;

            httpUrlConn.disconnect();  

            return file;
    }  

    /**
     * @desc :2.微信上传素材的请求方法
     *
     * @param requestUrl  微信上传临时素材的接口url
     * @param file    要上传的文件
     * @return String  上传成功后,微信服务器返回的消息
     */
    public static String httpRequest(String requestUrl, File file) {
        StringBuffer buffer = new StringBuffer();  

        try{
            //1.建立连接
            URL url = new URL(requestUrl);
            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();  //打开链接

            //1.1输入输出设置
            httpUrlConn.setDoInput(true);
            httpUrlConn.setDoOutput(true);
            httpUrlConn.setUseCaches(false); // post方式不能使用缓存
            //1.2设置请求头信息
            httpUrlConn.setRequestProperty("Connection", "Keep-Alive");
            httpUrlConn.setRequestProperty("Charset", "UTF-8");
            //1.3设置边界
            String BOUNDARY = "----------" + System.currentTimeMillis();
            httpUrlConn.setRequestProperty("Content-Type","multipart/form-data; boundary="+ BOUNDARY);

            // 请求正文信息
            // 第一部分:
            //2.将文件头输出到微信服务器
            StringBuilder sb = new StringBuilder();
            sb.append("--"); // 必须多两道线
            sb.append(BOUNDARY);
            sb.append("\r\n");
            sb.append("Content-Disposition: form-data;name=\"media\";filelength=\"" + file.length()
            + "\";filename=\""+ file.getName() + "\"\r\n");
            sb.append("Content-Type:application/octet-stream\r\n\r\n");
            byte[] head = sb.toString().getBytes("utf-8");
            // 获得输出流
            OutputStream outputStream = new DataOutputStream(httpUrlConn.getOutputStream());
            // 将表头写入输出流中:输出表头
            outputStream.write(head);

            //3.将文件正文部分输出到微信服务器
            // 把文件以流文件的方式 写入到微信服务器中
            DataInputStream in = new DataInputStream(new FileInputStream(file));
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in.read(bufferOut)) != -1) {
                outputStream.write(bufferOut, 0, bytes);
            }
            in.close();
            //4.将结尾部分输出到微信服务器
            byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
            outputStream.write(foot);
            outputStream.flush();
            outputStream.close();

            //5.将微信服务器返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }  

            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();  

        } catch (IOException e) {
            System.out.println("发送POST请求出现异常!" + e);
            e.printStackTrace();
        }
        return buffer.toString();
    }

    /**
     * 2.发起http请求获取返回结果
     *
     * @param requestUrl 请求地址
     * @return
     */
    public static String httpRequest(String requestUrl) {
        StringBuffer buffer = new StringBuffer();
        try {
            URL url = new URL(requestUrl);
            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();  

            httpUrlConn.setDoOutput(false);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);  

            httpUrlConn.setRequestMethod("GET");
            httpUrlConn.connect();  

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            //InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);  

            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();  

        } catch (Exception e) {
        }
        return buffer.toString();
    }  

    /**
     * 3.获取access_token
     *
     * @param appid 凭证
     * @param appsecret 密钥
     * @return
     */
    public static AccessToken getAccessToken(String appid, String appsecret) {
        AccessToken accessToken = null;  

        String requestUrl = access_token_url.replace("{corpId}", appid).replace("{corpsecret}", appsecret);
        JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
        // 如果请求成功
        if (null != jsonObject) {
            try {
                accessToken = new AccessToken();
                accessToken.setToken(jsonObject.getString("access_token"));
                accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
            } catch (JSONException e) {
                accessToken = null;
                // 获取token失败
                log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
            }
        }
        return accessToken;
    }  

    /**
     * 4. 获取JsapiTicket
     * @param accessToken
     * @return
     */
    public static String getJsapiTicket(String accessToken){

        String requestUrl = jsapi_ticket_url.replace("ACCESSTOKEN", accessToken);
        JSONObject jsonObject = httpRequest(requestUrl, "GET", null);  

        String  jsapi_ticket="";
        // 如果请求成功
        if (null != jsonObject) {
            try {
                jsapi_ticket=jsonObject.getString("ticket");  

            } catch (JSONException e) {  

                // 获取token失败
                log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
            }
        }
        return jsapi_ticket;
    }

    /**
     * 3.获取企业微信的JSSDK配置信息
     * @param request
     * @return
     */
    public static Map<String, Object> getWxConfig(HttpServletRequest request) {
        Map<String, Object> ret = new HashMap<String, Object>();
        //1.准备好参与签名的字段

        String nonceStr = UUID.randomUUID().toString(); // 必填,生成签名的随机串
        //System.out.println("nonceStr:"+nonceStr);
        String accessToken=WeiXinUtil.getAccessToken(WeiXinParamesUtil.corpId, WeiXinParamesUtil.agentSecret).getToken();
        String jsapi_ticket =getJsapiTicket(accessToken);// 必填,生成签名的H5应用调用企业微信JS接口的临时票据
        //System.out.println("jsapi_ticket:"+jsapi_ticket);
        String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填,生成签名的时间戳
        //System.out.println("timestamp:"+timestamp);
        String url=request.getRequestURL().toString();
        //System.out.println("url:"+url);

        //2.字典序           ,注意这里参数名必须全部小写,且必须有序
        String sign = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr+ "&timestamp=" + timestamp + "&url=" + url;

        //3.sha1签名
        String signature = "";
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(sign.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
            //System.out.println("signature:"+signature);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        ret.put("appId", WeiXinParamesUtil.corpId);
        ret.put("timestamp", timestamp);
        ret.put("nonceStr", nonceStr);
        ret.put("signature", signature);
        return ret;
    }

    /**
     * 方法名:byteToHex</br>
     * 详述:字符串加密辅助方法 </br>
     * 开发人员:souvc  </br>
     * 创建时间:2016-1-5  </br>
     * @param hash
     * @return 说明返回值含义
     * @throws 说明发生此异常的条件
     */
    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;

    }

    private static String getExt(String contentType){
        if("image/jpeg".equals(contentType)){
            return ".jpg";
        }else if("image/png".equals(contentType)){
            return ".png";
        }else if("image/gif".equals(contentType)){
            return ".gif";
        }

        return null;
    }
}

获取临时素材的方法为:WeiXinUtil.getFile(String requestUrl,String savePath)

在此方法中:

(1)发起https请求,获取输入流

(2)从输入流中获取文件类型,与savePath一起组成图片最终的路径(或者说是文件名A)

(3)根据文件名A创建输出流

(4)将输入流中的数据写入到输出流中,这样图片就保存到了文件A中。

(5)返回文件A

时间: 2024-10-05 06:17:40

Java企业微信开发_09_素材管理之下载微信临时素材到本地服务器的相关文章

Spring MVC、Mybatis、Hibernate、Bootstrap、HTML5、jQuery、Spring Security安全权限、Lucene全文检索、Ehcache分布式缓存 、高性能、高并发【Java企业通用开发平台框架】

功能特点: 1.适配所有设备(PC.平板.手机等),兼容所有浏览器(Chrome.Firefox.Opera.Safari.IE6~IE11等),适用所有项目(MIS管理信息系统.OA办公系统.ERP企业资源规划系统.CRM客户关系管理系统.网站.管理后台等). 2.快速开发,敏捷的数据持久层解决方案. 2.1.事务自动处理. 2.2.O/R Mapping基于注解,零配置XML,便于维护,学习成本低. 2.3.接口和实现分离,不需写数据持久层代码,只需写接口,自动生成添加.修改.删除.排序.分

微信开发学习总结(二)——微信开发入门

上一篇<微信开发学习总结(一)——微信开发环境搭建>我们已经完成了微信开发的准备工作,准备工作完成之后,就要开始步入正题了. 一.微信公众平台的基本原理 在开始做之前,先简单介绍了微信公众平台的基本原理. 微信服务器就相当于一个转发服务器,终端(手机.Pad等)发起请求至微信服务器,微信服务器然后将请求转发给我们的应用服务器.应用服务器处理完毕后,将响应数据回发给微信服务器,微信服务器再将具体响应信息回复到微信App终端. 通信协议为:HTTP 数据传输格式为:XML 具体的流程如下图所示:

Java企业微信开发_09_身份验证之移动端网页授权(有完整项目源码)

注: 源码已上传github: https://github.com/shirayner/WeiXin_QiYe_Demo 一.本节要点 1.1 授权回调域(可信域名) 在开始使用网页授权之前,需要先设置一下授权回调域.这里瞬间想到之前做JSSDK的时候,也设置过一个域名.二者本质上都是设置可信域名. 当用户授权完毕之后,请求将重定向到此域名(或者子域名)下的执行者(jsp页面或者servlet等).如何设置授权回调域,请见第二节. 1.2 获取Code https://open.weixin.

微信开发学习总结(一)—微信开发环境搭建

目前移动App开发领域主要分为以下几种类型: 一.微信开发环境搭建 1.要有一个用来测试的公众号. 2.用来调式代码的开发环境 1.1.注册测试公众号 微信公众号分为服务号.订阅号.企业号,订阅号可以个人申请,服务号和企业号要有企业资质才可以. 我们所说的微信公众号开发指的是订阅号和服务号. 关于订阅号和服务号的区别,官方是这样解释的 服务号:主要偏向于服务交互(功能类似12315,114,银行,提供绑定信息,服务交互),每月可群发4条消息:服务号适用人群:媒体.企业.政府或其他组织. 订阅号:

微信开发学习总结(一)微信开发环境搭建

目前移动开发处于比较火的的趋势,很多的开发者都跃跃欲试,目前移动App开发领域主要分为以下几种类型 我在平时的工作中接触得比较多的就是基于Android的Native App开发和基于微信公众号的Light App开发,今天就来带领大家快速进入微信公众号的开发领域. 一.微信开发环境搭建 工欲善其事,必先利其器.要做微信公众号开发,那么要先准备好两样必不可少的东西: 1.要有一个用来测试的公众号. 2.用来调式代码的开发环境. 1.1.注册测试公众号 微信公众号分为服务号.订阅号.企业号,订阅号

微信开发第五篇手机端微信公众号自定义菜单及OAuth2.0授权页面

说到自定义菜单,首先要想到调用微信的接口,其实微信公众号开发本身就是看对不对微信公众号接口的熟悉程度,我也是在项目中才开始接触微信公众号开发的,很感谢公司能给我这个项目机会.其实对于一个程序员来说最宝贵的是他的学习能力,而不是经验,不扯没用的了. 菜单上一篇讲到了怎么查看微信开发文档,那么很容易找到自定义菜单管理,根据里面的内容可以做一下思路 手机微信客户端与微信服务器交互,再由微信服务器与咱们自己的服务器交互,在第一次交互时先删除原始的那种可以打字的那种菜单,之后设置自己新的菜单,最后把自己的

微信开发学习总结(一)——微信开发环境搭建(转)

目前移动开发处于比较火的的趋势,很多的开发者都跃跃欲试,目前移动App开发领域主要分为以下几种类型 我在平时的工作中接触得比较多的就是基于Android的Native App开发和基于微信公众号的Light App开发,今天就来带领大家快速进入微信公众号的开发领域. 一.微信开发环境搭建 工欲善其事,必先利其器.要做微信公众号开发,那么要先准备好两样必不可少的东西: 1.要有一个用来测试的公众号. 2.用来调式代码的开发环境. 1.1.注册测试公众号 微信公众号分为服务号.订阅号.企业号,订阅号

微信开发学习总结(一)——微信开发环境搭建

目前移动开发处于比较火的的趋势,很多的开发者都跃跃欲试,目前移动App开发领域主要分为以下几种类型 我在平时的工作中接触得比较多的就是基于Android的Native App开发和基于微信公众号的Light App开发,今天就来带领大家快速进入微信公众号的开发领域. 一.微信开发环境搭建 工欲善其事,必先利其器.要做微信公众号开发,那么要先准备好两样必不可少的东西: 1.要有一个用来测试的公众号. 2.用来调式代码的开发环境. 1.1.注册测试公众号 微信公众号分为服务号.订阅号.企业号,订阅号

微信开发教程:用户账号绑定到微信公众号的方法分享

时间:2015-02-26    作者:Abyssly   来源:Abyssly Blog 最近由于工作需要,接触了微信公众号的开发.业务上要求绑定微信用户和系统用户,以便用户在一次绑定后能够通过系统用户的身份去使用一些功能.我关注的招行信用卡公众号实现了这个功能,所以估计还是可行的,在网上搜索了一下,发现这个问题没什么好的答案,很多都说取不到微信用户名实现不了,甚至有说实现了这个功能的应该是与微信有内部合作的. 搜索无果,遂自己动手实验,后发现其实完全可以的,看来实践才是检验真理的唯一标准,方