zoukankan      html  css  js  c++  java
  • [JAVA实现]微信公众号网页授权登录

    网上搜资料时,网友都说官方文档太垃圾了不易看懂,如何如何的。现在个人整理了一个通俗易懂易上手的,希望可以帮助到刚接触微信接口的你。

    请看流程图!看懂图,就懂了一半了:

    其实整体流程大体只需三步:用户点击登录按钮(其实就相当于一个链接) ---》  用户点击授权登录  ----》  实现获取用户信息代码。

    然后获取用户信息代码只需三步:获取code  ----》 通过code获取access_token和openId  ---》 通过access_token和openId获取用户信息(包含union)。

    以上便是整体套路,当然官网上也有,但具体如何实现呢?

    不着急,咱们一步一步来!

    第一步:微信登录按钮

    它其实就是一个连接,不过想得到这个链接,有一点点麻烦。

    1、设置。 微信公众平台---》接口权限---》网页授权---》修改 ---》设置网页授权域名(域名,不含http://),其实就是微信调你的java方法的项目路径或项目域名,如:www.zzff.net/pp ---》点击设置后弹出页面(大致意思,将MP_verify_31qRIDcjN8ZD1lVJ.txt放在你项目路径下面,如:www.ffzz.net/pp/MP_verify_31qRIDcjN8ZD1lVJ.txt 能访问到) ---》点击确认,授权回调页面域名设置成功!

    2、拼链接。   https://open.weixin.qq.com/connect/oauth2/authorize?appid=xxx公众号IDxxxxx   &  redirect_uri = 授权回调页面域名/你的action(即微信授权后跳向的地址)

    & response_type=code(固定的) & scope = snsapi_userinfo(或者snsapi_base默认授权)  & state=STATE#wechat_redirect

     如:https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

    这个链接中参数的具体含义,官方解释如下:

    参数是否必须说明
    appid 公众号的唯一标识
    redirect_uri 授权后重定向的回调链接地址,请使用urlencode对链接进行处理
    response_type 返回类型,请填写code
    scope 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息
    state 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 
    #wechat_redirect 无论直接打开还是做页面302重定向时候,必须带此参数

    第二步:授权确认登录 

    这一步最简单,第一步登录链接拼好后,在手机微信中打开,微信便会跳转到确认授权页面,点击确认授权即可。(这一步,不用开发者做处理!)

    第三步:获取用户信息 (重点)
    这一步便是真正的代码实现的地方。开篇便讲了,它只需三步:获取code  ----》 通过code获取access_token和openId  ---》 通过access_token和openId获取用户信息。

    First:   获取code

    Second:  获取网页授权access_token和openId  

    Third:通过access_token和openId获取用户信息。

    关于union机制的细节:如果开发者需要公众号微信登录和APP微信登录共用一个微信ID,那个就需要union机制了。其实很简单,需在微信开放平台(open.weixin.qq.com)绑定公众号,获取用户信息时就会返回union字段

    具体代码实现为:实体 ----  方法  --- 工具

    实体Oauth2Token:

     1 package com.wfcm.wxUitls;
     2 
     3 /**
     4 * 类名: WeixinOauth2Token </br>
     5 * 描述:  网页授权信息  </br>
     6 * 创建时间:  2015-11-27 </br>
     7 * 发布版本:V1.0  </br>
     8  */
     9 public class Oauth2Token {
    10     // 网页授权接口调用凭证
    11     private String accessToken;
    12     // 凭证有效时长
    13     private int expiresIn;
    14     // 用于刷新凭证
    15     private String refreshToken;
    16     // 用户标识
    17     private String openId;
    18     // 用户授权作用域
    19     private String scope;
    20 
    21     public String getAccessToken() {
    22         return accessToken;
    23     }
    24 
    25     public void setAccessToken(String accessToken) {
    26         this.accessToken = accessToken;
    27     }
    28 
    29     public int getExpiresIn() {
    30         return expiresIn;
    31     }
    32 
    33     public void setExpiresIn(int expiresIn) {
    34         this.expiresIn = expiresIn;
    35     }
    36 
    37     public String getRefreshToken() {
    38         return refreshToken;
    39     }
    40 
    41     public void setRefreshToken(String refreshToken) {
    42         this.refreshToken = refreshToken;
    43     }
    44 
    45     public String getOpenId() {
    46         return openId;
    47     }
    48 
    49     public void setOpenId(String openId) {
    50         this.openId = openId;
    51     }
    52 
    53     public String getScope() {
    54         return scope;
    55     }
    56 
    57     public void setScope(String scope) {
    58         this.scope = scope;
    59     }
    60 }
    View Code

    实体SNSUserInfo:

      1 package com.wfcm.wxUitls;
      2 
      3 import java.util.List;
      4 
      5 /**
      6 * 类名: SNSUserInfo </br>
      7 * 描述: 通过网页授权获取的用户信息 </br>
      8 * 开发人员: wzf </br>
      9 * 创建时间:  2015-11-27 </br>
     10 * 发布版本:V1.0  </br>
     11  */
     12 public class SNSUserInfo {
     13     // 用户标识
     14     private String openId;
     15     // 用户昵称
     16     private String nickname;
     17     // 性别(1是男性,2是女性,0是未知)
     18     private int sex;
     19     // 国家
     20     private String country;
     21     // 省份
     22     private String province;
     23     // 城市
     24     private String city;
     25     // 用户头像链接
     26     private String headImgUrl;
     27     // 用户特权信息
     28     private List<String> privilegeList;
     29     
     30     private String unionid;
     31 
     32     public String getUnionid() {
     33         return unionid;
     34     }
     35 
     36     public void setUnionid(String unionid) {
     37         this.unionid = unionid;
     38     }
     39 
     40     public String getOpenId() {
     41         return openId;
     42     }
     43 
     44     public void setOpenId(String openId) {
     45         this.openId = openId;
     46     }
     47 
     48     public String getNickname() {
     49         return nickname;
     50     }
     51 
     52     public void setNickname(String nickname) {
     53         this.nickname = nickname;
     54     }
     55 
     56     public int getSex() {
     57         return sex;
     58     }
     59 
     60     public void setSex(int sex) {
     61         this.sex = sex;
     62     }
     63 
     64     public String getCountry() {
     65         return country;
     66     }
     67 
     68     public void setCountry(String country) {
     69         this.country = country;
     70     }
     71 
     72     public String getProvince() {
     73         return province;
     74     }
     75 
     76     public void setProvince(String province) {
     77         this.province = province;
     78     }
     79 
     80     public String getCity() {
     81         return city;
     82     }
     83 
     84     public void setCity(String city) {
     85         this.city = city;
     86     }
     87 
     88     public String getHeadImgUrl() {
     89         return headImgUrl;
     90     }
     91 
     92     public void setHeadImgUrl(String headImgUrl) {
     93         this.headImgUrl = headImgUrl;
     94     }
     95 
     96     public List<String> getPrivilegeList() {
     97         return privilegeList;
     98     }
     99 
    100     public void setPrivilegeList(List<String> privilegeList) {
    101         this.privilegeList = privilegeList;
    102     }
    103 }
    View Code

    方法WxController(其中authorize() 方法就是请求第一步获取的链接):

      1 package com.wfcm.controller;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.IOException;
      5 import java.io.InputStreamReader;
      6 import java.io.UnsupportedEncodingException;
      7 import java.net.URL;
      8 import java.net.URLConnection;
      9 import java.net.URLEncoder;
     10 import java.security.MessageDigest;
     11 import java.security.NoSuchAlgorithmException;
     12 import java.util.ArrayList;
     13 import java.util.Formatter;
     14 import java.util.HashMap;
     15 import java.util.List;
     16 import java.util.Map;
     17 import java.util.UUID;
     18 
     19 import javax.servlet.http.HttpServletRequest;
     20 import javax.servlet.http.HttpServletResponse;
     21 
     22 import org.apache.http.client.utils.URLEncodedUtils;
     23 import org.json.JSONObject;
     24 import org.slf4j.Logger;
     25 import org.slf4j.LoggerFactory;
     26 import org.springframework.beans.factory.annotation.Autowired;
     27 import org.springframework.stereotype.Controller;
     28 import org.springframework.web.bind.annotation.RequestMapping;
     29 import org.springframework.web.bind.annotation.ResponseBody;
     30 
     31 import com.alibaba.fastjson.JSON;
     32 import com.alibaba.fastjson.JSONArray;
     33 import com.alibaba.fastjson.util.IOUtils;
     34 import com.wfcm.annotation.IgnoreSign;
     35 import com.wfcm.annotation.IgnoreToken;
     36 import com.wfcm.entity.WfMemberEntity;
     37 import com.wfcm.service.WfMemberService;
     38 import com.wfcm.service.WfMemberSessionService;
     39 import com.wfcm.utils.FastJSONUtils;
     40 import com.wfcm.utils.NetUtil;
     41 import com.wfcm.utils.R;
     42 import com.wfcm.wxUitls.AccessToken;
     43 import com.wfcm.wxUitls.JsapiTicket;
     44 import com.wfcm.wxUitls.Oauth2Token;
     45 import com.wfcm.wxUitls.SNSUserInfo;
     46 
     47 @Controller
     48 @RequestMapping("/wx")
     49 @ResponseBody
     50 public class WxController {
     51 
     52     private static  Logger log = LoggerFactory.getLogger(WxController.class);
     53      
     54     
     55     /**
     56      * 向指定URL发送GET方法的请求
     57      * 
     58      * @param url
     59      *            发送请求的URL
     60      * @param param
     61      *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     62      * @return URL 所代表远程资源的响应结果
     63      * 
     64      * 用户同意授权,获取code
     65      */ 
     66     @RequestMapping("/authorize")
     67     @ResponseBody
     68     @IgnoreToken
     69     public static R authorize() {
     70         String appid = "wxbb000000000e";
     71         //String uri ="wftest.zzff.net/wx/weixinLogin"; 
     72         String uri = urlEncodeUTF8("wftest.zzff.net/api/wx/weixinLogin");
     73         String result = "";
     74         BufferedReader in = null;
     75         try {
     76             String urlNameString = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+appid+"&redirect_uri="+uri+"&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
     77             
     78             URL realUrl = new URL(urlNameString);
     79             // 打开和URL之间的连接
     80             URLConnection connection = realUrl.openConnection();
     81             // 设置通用的请求属性
     82             connection.setRequestProperty("accept", "*/*");
     83             connection.setRequestProperty("connection", "Keep-Alive");
     84             connection.setRequestProperty("user-agent",
     85                     "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
     86             // 建立实际的连接
     87             connection.connect();
     88             // 获取所有响应头字段
     89             Map<String, List<String>> map = connection.getHeaderFields();
     90             // 遍历所有的响应头字段
     91             for (String key : map.keySet()) {
     92                 System.out.println(key + "--->" + map.get(key));
     93             }
     94             // 定义 BufferedReader输入流来读取URL的响应
     95             in = new BufferedReader(new InputStreamReader(
     96                     connection.getInputStream()));
     97             String line =null;
     98             while ((line = in.readLine()) != null) {
     99                 result += line;
    100             }
    101             /*  com.alibaba.fastjson.JSONObject jsonObj= FastJSONUtils.getJSONObject(result);  
    102                 String access_token = jsonObj.getString("access_token");
    103                 long expires_in = Long.valueOf(jsonObj.getString("expires_in"));
    104             */
    105         } catch (Exception e) {
    106             System.out.println("发送GET请求出现异常!" + e);
    107             e.printStackTrace();
    108         }
    109         // 使用finally块来关闭输入流
    110         finally {
    111             try {
    112                 if (in != null) {
    113                     in.close();
    114                 }
    115             } catch (Exception e2) {
    116                 e2.printStackTrace();
    117             }
    118         }
    119         return  R.ok(result);
    120     }    
    121     
    122     @RequestMapping("/weixinLogin")
    123     @ResponseBody
    124     @IgnoreToken
    125     @IgnoreSign
    126     public void weixinLogin(HttpServletRequest request,HttpServletResponse response) throws Exception {  
    127         // 用户同意授权后,能获取到code
    128         Map<String, String[]> params = request.getParameterMap();//针对get获取get参数  
    129         String[] codes = params.get("code");//拿到code的值 
    130         String code = codes[0];//code  
    131         //String[] states = params.get("state");
    132         //String state = states[0];//state 
    133         
    134         System.out.println("****************code:"+code);          
    135         // 用户同意授权
    136         if (!"authdeny".equals(code)) {
    137              // 获取网页授权access_token
    138             Oauth2Token oauth2Token = getOauth2AccessToken("wxb0000000000e", "4c22222233333335555a9", code);
    139             System.out.println("***********************************oauth2Token信息:"+oauth2Token.toString());
    140             // 网页授权接口访问凭证
    141             String accessToken = oauth2Token.getAccessToken();
    142             // 用户标识
    143             String openId = oauth2Token.getOpenId();
    144             // 获取用户信息
    145             SNSUserInfo snsUserInfo = getSNSUserInfo(accessToken, openId);
    146             System.out.println("***********************************用户信息unionId:"+snsUserInfo.getUnionid()+"***:"+snsUserInfo.getNickname());
    147             // 设置要传递的参数
    148             
    149             //具体业务start
    150 
    151            //具体业务end
    152 
    153             String url = "http://wftest.zzff.net/#/biddd?from=login&tokenId="+snsUserInfo.getUnionid();
    154             
    155             response.sendRedirect(url); 
    156             return ;
    157         }
    158     }  
    159 
    160     
    161     /**
    162      * 获取网页授权凭证
    163      * 
    164      * @param appId 公众账号的唯一标识
    165      * @param appSecret 公众账号的密钥
    166      * @param code
    167      * @return WeixinAouth2Token
    168      */
    169     public static Oauth2Token getOauth2AccessToken(String appId, String appSecret, String code) {
    170         Oauth2Token wat = null;
    171         // 拼接请求地址
    172         String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
    173         requestUrl = requestUrl.replace("APPID", appId);
    174         requestUrl = requestUrl.replace("SECRET", appSecret);
    175         requestUrl = requestUrl.replace("CODE", code);
    176         // 获取网页授权凭证
    177         com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(NetUtil.get(requestUrl));
    178         if (null != jsonObject) {
    179             try {
    180                 wat = new Oauth2Token();
    181                 wat.setAccessToken(jsonObject.getString("access_token"));
    182                 wat.setExpiresIn(jsonObject.getInteger("expires_in"));
    183                 wat.setRefreshToken(jsonObject.getString("refresh_token"));
    184                 wat.setOpenId(jsonObject.getString("openid"));
    185                 wat.setScope(jsonObject.getString("scope"));
    186             } catch (Exception e) {
    187                 wat = null;
    188                 int errorCode = jsonObject.getInteger("errcode");
    189                 String errorMsg = jsonObject.getString("errmsg");
    190                 log.error("获取网页授权凭证失败 errcode:{} errmsg:{}", errorCode, errorMsg);
    191             }
    192         }
    193         return wat;
    194     }
    195     
    196     /**
    197      * 通过网页授权获取用户信息
    198      * 
    199      * @param accessToken 网页授权接口调用凭证
    200      * @param openId 用户标识
    201      * @return SNSUserInfo
    202      */
    203     public static SNSUserInfo getSNSUserInfo(String accessToken, String openId) {
    204         SNSUserInfo snsUserInfo = null;
    205         // 拼接请求地址
    206         String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
    207         requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
    208         // 通过网页授权获取用户信息
    209         com.alibaba.fastjson.JSONObject jsonObject =  JSON.parseObject(NetUtil.get(requestUrl));
    210 
    211         if (null != jsonObject) {
    212             try {
    213                 snsUserInfo = new SNSUserInfo();
    214                 // 用户的标识
    215                 snsUserInfo.setOpenId(jsonObject.getString("openid"));
    216                 // 昵称
    217                 snsUserInfo.setNickname(jsonObject.getString("nickname"));
    218                 // 性别(1是男性,2是女性,0是未知)
    219                 snsUserInfo.setSex(jsonObject.getInteger("sex"));
    220                 // 用户所在国家
    221                 snsUserInfo.setCountry(jsonObject.getString("country"));
    222                 // 用户所在省份
    223                 snsUserInfo.setProvince(jsonObject.getString("province"));
    224                 // 用户所在城市
    225                 snsUserInfo.setCity(jsonObject.getString("city"));
    226                 // 用户头像
    227                 snsUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl"));
    228                 // 用户特权信息
    229                 List<String> list = JSON.parseArray(jsonObject.getString("privilege"),String.class);
    230                 snsUserInfo.setPrivilegeList(list);
    231                 //与开放平台共用的唯一标识,只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
    232                 snsUserInfo.setUnionid(jsonObject.getString("unionid"));
    233             } catch (Exception e) {
    234                 snsUserInfo = null;
    235                 int errorCode = jsonObject.getInteger("errcode");
    236                 String errorMsg = jsonObject.getString("errmsg");
    237                 log.error("获取用户信息失败 errcode:{} errmsg:{}", errorCode, errorMsg);
    238             }
    239         }
    240         return snsUserInfo;
    241     }
    242    
    243     /**
    244      * URL编码(utf-8)
    245      * 
    246      * @param source
    247      * @return
    248      */
    249     public static String urlEncodeUTF8(String source) {
    250         String result = source;
    251         try {
    252             result = java.net.URLEncoder.encode(source, "utf-8");
    253         } catch (UnsupportedEncodingException e) {
    254             e.printStackTrace();
    255         }
    256         return result;
    257     }
    258     
    259     private static String byteToHex(final byte[] hash) {
    260         Formatter formatter = new Formatter();
    261         for (byte b : hash)
    262         {
    263             formatter.format("%02x", b);
    264         }
    265         String result = formatter.toString();
    266         formatter.close();
    267         return result;
    268     }
    269 
    270     private static String create_nonce_str() {
    271         return UUID.randomUUID().toString();
    272     }
    273 
    274     private static String create_timestamp() {
    275         return Long.toString(System.currentTimeMillis() / 1000);
    276     }
    277 }
    View Code

    工具NetUtil:

     1 package com.wfcm.utils;
     2 
     3 import java.io.BufferedInputStream;
     4 import java.io.IOException;
     5 import java.io.InputStreamReader;
     6 import java.io.UnsupportedEncodingException;
     7 import java.util.ArrayList;
     8 import java.util.Collection;
     9 import java.util.List;
    10 import java.util.Map;
    11 
    12 import org.apache.commons.httpclient.NameValuePair;
    13 import org.apache.http.HttpEntity;
    14 import org.apache.http.HttpResponse;
    15 import org.apache.http.client.entity.UrlEncodedFormEntity;
    16 import org.apache.http.client.methods.HttpGet;
    17 import org.apache.http.client.methods.HttpPost;
    18 import org.apache.http.impl.client.CloseableHttpClient;
    19 import org.apache.http.impl.client.HttpClientBuilder;
    20 import org.apache.http.message.BasicNameValuePair;
    21 
    22 /**
    23  * Created by Song on 2016/11/28.
    24  * 基于HttpClient提供网络访问工具
    25  */
    26 public final class NetUtil {
    27     public static CloseableHttpClient httpClient = HttpClientBuilder.create().build();
    28 
    29     /**
    30      * get请求获取String类型数据
    31      * @param url 请求链接
    32      * @return
    33      */
    34     public static String get(String url){
    35         StringBuffer sb = new StringBuffer();
    36         HttpGet httpGet = new HttpGet(url);
    37         try {
    38             HttpResponse response = httpClient.execute(httpGet);           //1
    39 
    40             HttpEntity entity = response.getEntity();
    41             InputStreamReader reader = new InputStreamReader(entity.getContent(),"utf-8");
    42             char [] charbufer;
    43             while (0<reader.read(charbufer=new char[10])){
    44                 sb.append(charbufer);
    45             }
    46         }catch (IOException e){//1
    47             e.printStackTrace();
    48         }finally {
    49             httpGet.releaseConnection();
    50         }
    51         return sb.toString();
    52     }
    53 
    54     /**
    55      * post方式请求数据
    56      * @param url 请求链接
    57      * @param data post数据体
    58      * @return
    59      */
    60     @SuppressWarnings("unchecked")
    61     public static String post(String url, Map<String,String> data){
    62         StringBuffer sb = new StringBuffer();
    63         HttpPost httpPost = new HttpPost(url);
    64         List<NameValuePair> valuePairs = new ArrayList<NameValuePair>();
    65         if(null != data) {
    66             for (String key : data.keySet()) {
    67                 valuePairs.addAll((Collection<? extends NameValuePair>) new BasicNameValuePair(key, data.get(key)));
    68             }
    69         }
    70         try {
    71             httpPost.setEntity(new UrlEncodedFormEntity((List<? extends org.apache.http.NameValuePair>) valuePairs));
    72             HttpResponse response = httpClient.execute(httpPost);
    73             HttpEntity httpEntity = response.getEntity();
    74             BufferedInputStream bis = new BufferedInputStream(httpEntity.getContent());
    75             byte [] buffer;
    76             while (0<bis.read(buffer=new byte[128])){
    77                 sb.append(new String(buffer,"utf-8"));
    78             }
    79         }catch (UnsupportedEncodingException e){//数据格式有误
    80             e.printStackTrace();
    81         }catch (IOException e){//请求出错
    82             e.printStackTrace();
    83         }finally {
    84             httpPost.releaseConnection();
    85         }
    86         return sb.toString();
    87     }
    88     
    89     
    90  }
    View Code

     R类:

    package com.wfcm.utils;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * 返回数据
     * 
     * @author xlf
     * @email xlfbe696@gmail.com
     * @date 2017年4月19日 上午11:58:56
     */
    public class R extends HashMap<String, Object> {
        private static final long serialVersionUID = 1L;
    
        public static final String SUCCESS = "success";
        
        public static final String EXCEPTION = "exception";
        
        public static final Integer SUCCESSCODE = 0;
            
        public static final Integer EXCEPTIONCODE = 500;
        
    
        public R() {
            put("errCode", 0);
            put("msg", SUCCESS);
        }
        
        public R(int code, String msg){
               put("errCode", code);
                put("msg", msg);
        }
    
        public static R error() {
            return error(500, "未知异常,请联系管理员");
        }
    
        public static R error(String msg) {
            return error(500, msg);
        }
    
        public static R error(int code, String msg) {
            R r = new R();
            r.put("errCode", code);
            r.put("msg", msg);
            return r;
        }
    
        public static R ok(String msg) {
            R r = new R();
            r.put("msg", msg);
            return r;
        }
    
        public static R ok(Map<String, Object> map) {
            R r = new R();
            r.putAll(map);
            return r;
        }
    
        public static R ok() {
            return new R();
        }
    
        public R put(String key, Object value) {
            super.put(key, value);
            return this;
        }
    }
    View Code

    OK,大功告成!整体流程已经搭建起来,读懂了这些代码差不多就明白了整个流程了,然后再看官方文档,你会觉得读起来很顺畅,而不是刚开始那种味同嚼蜡的感觉。你只需再根据官方文档仔细检查检查流程,有没有需要完善的地方,就可以了。

    还等什么呢,赶快敲实现功能吧!!!

  • 相关阅读:
    第二十二篇 正在表达式 re模块
    机器学习 —— 概率图模型(推理:采样算法)
    机器学习 —— 概率图模型(推理:MAP)
    机器学习 —— 概率图模型(推理:团树算法)
    机器学习 —— 概率图模型(推理:消息传递算法)
    第二次读书会的思考
    机器学习 —— 概率图模型(推理:变量消除)
    机器学习 —— 概率图模型(马尔科夫与条件随机场)
    机器学习 —— 概率图模型(CPD)
    机器学习 —— 概率图模型(贝叶斯网络)
  • 原文地址:https://www.cnblogs.com/hero123/p/9010506.html
Copyright © 2011-2022 走看看