微信公众号 H5授权登录实现(最详细)

一、微信公众号

(一)基础信息

微信授权类型

自己的网站、APP等第三方,要实现接入微信授权登录,有多种方式:微信公众号(网页)、微信小程序、微信开放平台(APP)等等。

【项目代码】

GitHub - liyinchigithub/springboot-learn: springboot 学习项目

微信公众号(网页)

  • 公众号配置JS安全域名、code回调域名
  • 微信授权登录,获取access_token、openid等用户信息
  • jssdk认证(签名)
  • 调用jssdk相关方法调用
  • 花生壳域名内网穿透
  • 微信开放平台地址汇总
1.申请公众号
(1)第一步 认证微信公众帐号

首先,得拥有一个通过认证了的微信公众号或者开发者帐号认证费一年300块钱; 

(2)第二步 添加安全域名

在公众帐号平台后台添加 app 运行的域名地址,为某个域名添加白名单功能,让微信知道这个ip是你的机子。

例如:微信公众号是”瓜瓜“,添加了 guagua.com 为安全域名,那么我在 guagua.com 上的网页可以使用瓜瓜下公众帐号的数字签名了; 

(3)第三步 生成数字签名

在微信公众平台后台上面能找到一个 appid 及 secret字符串

通过这两个参数,请求微信提供的两个公开API地址,生成对应的access_token后再生成ticket再通过规则加密成数字签名,数字签名必须在服务端生成,这里我以Springboot来实现

2.微信公众号平台配置

微信公众平台微信公众平台,给个人、企业和组织提供业务服务与用户管理能力的全新服务平台。icon-default.png?t=N7T8https://mp.weixin.qq.com/

(1)添加开发者的微信号到公众号人员设置中

0

绑定运营者微信号

0

(2)添加开发者微信账号到web

菜单路径:首页》开发》开发者工具》Web开发工具 》绑定开发者微信号

0

0

绑定开发者微信号

0

(3)查看微信公众号appID和appScrent

菜单路径:首页》开发》基本配置 》公众号开发信息

0

(4)将AppID和AppSecret配置到项目中

3.微信公众平台接口调试工具(检测准备工作情况)

如果微信公众号认证还没通过,可以先使用官方提供的测试号来进行调试。

方便调试,在线工具:微信公众平台接口调试工具

0

注意:这边使用的appid和secret是测试号的环境(沙盒)。

微信公众平台

遇到问题:如果接口报错返回提示无效ip

解决办法:需要将本地电脑ip地址,添加到公众号ip白名单中。

菜单路径:设置与开发 > 基本配置 > IP白名单 > 查看/添加

重新请求,成功获取accessToken

【使用微信JSSDK示例】

(1)获取关注者列表接口
①  基础支持-获取access_token接口

0

备注:旧版本是formdata格式(2020年),新版本是json格式(2024年6月16日)

{ "grant_type": "client_credential", "appid": "xxxxx", "secret": "xxxxxx" }
② 获取关注列表接口

传入上一步access_token参数值,作为鉴权参数。

所有关注此公众号的微信号openid都在数组里

(2)获取用户基本信息接口 /user/info

①填入上一步获取到的access_token

②填入上上步获取到的openid(可通过获取关注者列表接口获取到)

0

最新版没有用户昵称(2024年6月16日)

遇到问题:token过期

{ "errcode": 42001, "errmsg": "access_token expired rid: 666fa0b9-04633663-35fb85fa" }“

解决办法:重新调用,基础支持获取access_token获取新的token

网页授权 | 微信开放文档微信开发者平台文档icon-default.png?t=N7T8https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html

前端通过用户触发请求公众号授权接口

  • 第一种形式:location.href
 <a href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"></a>

注意:这种方式会暴露appid在前端页面

  • 第二种形式:按钮事件(推荐)
<button @click="toWechatLogin">toWechatLogin() {/*** @description 前端请求微信开放平台(微信登录授权接口,回调code)* @param appid 微信公众号appid* @param redirect_url 微信授权流程,获取code回调地址* */// TODO 用户触发发起授权链接var appid = 'xxxxx';// 微信公众号APPIDvar redirect_uri = encodeURIComponent('http://xxxxx.zicp.vip/code');// 网页授权code回调地址window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`}

微信开发者工具,访问本地开发环境地址(模拟微信客户端内置浏览器打开业务域名,一般是登录页面)

0

0

返回数据

注意:请求`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`,不能使用客户端自带http请求库(如:axios、request)来发起请求这个地址,而是只能使用location.href方式

4.方向代理配置

第一种:本地配置Nginx代理转发(推荐)

Nginx文件

// 修改nginx.conf文件 
server {listen 80;#监听的端口号server_name wxh5.xxx.fssh.com;#本地访问的域名(注意: host文件也要配置)location / {# 前端项目接口, 反向代理路径proxy_pass http: //127.0.0.1:9020/;#代理的域名加本地项目启用的端口号 - > nginx服务会代理本地起的服务从而可以在wx开发者工具上调试, 因为你的目的就是为了在工具调试本地的微信授权登录的流程}location / sns {# 微信公众号平台接口, 反向代理路径#return 666;proxy_pass https: //api.weixin.qq.com;   }location / code {# code回调接口地址proxy_pass http: //127.0.0.1:4343; }location / api {# 后端项目接口, 反向代理路径proxy_pass http: //127.0.0.1:4343;  }
}

host文件

127.0.0.1 wxh5.xxx.fssh.com

教程:window安装配置nginx(window Nginx安装配置)

原本我使用花生壳做内网穿透,但百度到一篇文件,不使用花生壳,可以直接修改hosts文件+nginx配置,就可以用本地自定义的域名来通过微信开发者工具访问到前端项目、前端项目访问后端接口,具体如下。

cd /usr/local/etc/nginx open /usr/local/etc/nginx

我的本地前端项目地址、端口

127.0.0.1:9020

0

我的本地后端项目地址、端口

127.0.0.1:4343

重启nginx

sudo nginx -s reload

微信公众号js接口安全域名配置(域名与nginx配置自定义本地域名一致)

微信公众号测试号,回调域名配置(域名与nginx配置自定义本地域名一致)

0

微信开发者工具,访问本地前端项目,url输入自定义本地域名

开发者工具url输入,自定义本地域名+/api/

示例:后端 接口/code

对应nginx中的/code如下:

nginx.conf文件

0

 

总结,本地nginx文件配置流程:

  • (1)自定义本地访问的域名
  • (2)前端项目本地IP和端口
  • (3)后端项目本地IP和端口
  • (4)微信公众号平台接口域名
  • (5)JSSDK域名

备注:如果使用nodejs anywhere库启动打包后静态文件dist文件夹,那么IP也是127.0.0.1+anywhere端口号修改配置到nginx

5.微信JSSDK引入与配置

前端什么时候需要引入微信JS-SDK?

(1)如果你的目的是让用户点击按钮后通过重定向到微信授权页面进行登录,那么不需要引入微信JS-SDK。

这种情况下,用户的登录流程是完全由后端处理的,前端只负责触发重定向。

<!-- src/main/resources/static/wechatLogin.html --> <!DOCTYPE html> 
<html lang="en"> 
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
<title>Wechat Login</title> 
</head><body> 
<h1>Wechat Login Test</h1> 
<button onclick="location.href='/login/wechat'">Login with Wechat</button> 
<!-- <button onclick=window.location.href=`https://open.weixin.qq.com/connect/oauth2/authorize?appid=xxxxx&redirect_uri=https://xxxx.vicp.fun/login/wechat/callback&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`>Login with Wechat
</button>--> 
</body> 
</html> 
<!-- wechatLogin.html 页面本身不需要包含请求参数 code 和 state。 这个页面只是提供一个按钮,用户点击后会被重定向到微信的授权页面。 在这个过程中,code 和 state 参数是由微信在用户授权后自动附加到回调URL上的。 -->
(2)当你需要用到用户地理位置、微信支付、分享等。

如果你需要在你的H5页面中使用这些功能,或者需要通过微信网页直接获取用户信息而不是重定向,那么你应该引入和配置JS-SDK。

引入和配置步骤

(1)引入JS-SDK:

在你的HTML页面中,添加以下脚本标签来引入微信JS-SDK。

  <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

(2)配置JS-SDK:

你需要后端提供JS-SDK的配置信息,包括appId, timestamp, nonceStr, signature等。这些信息需要通过调用微信的接口获得。

配置示例如下:

   wx.config({        debug: true, // 开启调试模式appId: '你的AppID', // 必填,公众号的唯一标识 timestamp: '生成签名的时间戳', // 必填,生成签名的时间戳nonceStr: '生成签名的随机串', // 必填,生成签名的随机串 signature: '签名', // 必填,签名 jsApiList: ['checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage'] // 必填,需要使用的JS接口列表    });

(3)发起微信登录请求:

如果你决定使用JS-SDK来处理登录,可以使用wx.login方法来发起微信登录请求。

  wx.login({        
success: function(res) {      if (res.code) {            // 使用返回的code去后端换取access_token等信息   } else {          console.log('登录失败!' + res.errMsg);        }      }  });

在wechatLogin.html实现引入JSSDK并获取用户地理位置、分享。

(1)你需要从后端获取必要的配置参数(appId, timestamp, nonceStr, signature),这通常涉及到服务器端的一些处理,以确保安全性。这里假设你已经有了一个API可以调用来获取这些数据。

在HTML中添加以下脚本来配置SDK

(2)使用JS-SDK获取地理位置

在配置成功后,你可以调用wx.getLocation方法来获取用户的地理位置:

<script>
wx.ready(function() {// 获取地理位置wx.getLocation({type: 'wgs84',success: function (res) {var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。var speed = res.speed; // 速度,以米/每秒计var accuracy = res.accuracy; // 位置精度alert('Latitude: ' + latitude + '\nLongitude: ' + longitude);}});// 配置分享给朋友的信息wx.updateAppMessageShareData({ title: '分享标题', // 分享标题desc: '分享描述', // 分享描述link: 'https://yourwebsite.com', // 分享链接imgUrl: 'https://yourwebsite.com/image.jpg', // 分享图标success: function () {// 设置成功alert('已分享');}});// 配置分享到朋友圈的信息wx.updateTimelineShareData({ title: '分享标题', // 分享标题link: 'https://yourwebsite.com', // 分享链接imgUrl: 'https://yourwebsite.com/image.jpg', // 分享图标success: function () {// 设置成功alert('已分享到朋友圈');}});
});
</script>

(3)处理错误

添加错误处理来响应配置失败的情况:

<script>
wx.error(function(res){// config信息验证失败会执行error函数,如签名过期导致验证失败alert("Error: " + res.errMsg);
});
</script>

总结

如果你的页面只是需要一个简单的微信登录按钮,并通过后端处理登录流程,那么不需要引入微信JS-SDK。

6.UnionID 微信开放平台

(1)如果需要在多公众号、移动应用之间做用户共通,则需前往微信开放平台,将这些公众号和应用绑定到一个开放平台账号下,绑定后,一个用户虽然对多个公众号和应用有多个不同的OpenID,但他对所有这些同一开放平台账号下的公众号和应用,只有一个UnionID,可以在用户管理-获取用户基本信息(UnionID机制)文档了解详情。

7.公众号消息会话

(1)群发消息:

公众号可以以一定频次(订阅号为每天1次,服务号为每月4次),向用户群发消息,包括文字消息、图文消息、图片、视频、语音等。

(2)被动回复消息:

在用户给公众号发消息后,微信服务器会将消息发到开发者预先在开发者中心设置的服务器地址(开发者需要进行消息真实性验证),公众号可以在5秒内做出回复,可以回复一个消息,也可以回复命令告诉微信服务器这条消息暂不回复。被动回复消息可以设置加密(在公众平台官网的开发者中心处设置,设置后,按照消息加解密文档来进行处理。其他3种消息的调用因为是API调用而不是对请求的返回,所以不需要加解密)。

(3)客服消息:

用户在公众号内发消息/触发特定行为后,公众号可以给用户发消息。

具体发送规则见公众号客服消息文档:客服账号管理 | 微信开放文档

(4)模板消息:

在需要对用户发送服务通知(如刷卡提醒、服务预约成功通知等)时,公众号可以用特定内容模板,主动向用户发送消息。

8.返回码

微信开放文档

遇到问题:微信开发者工具访问测试页面,点击授权微信登录按钮后,跳转提示”Scope 参数错误或没有 Scope 权限“

0

解决办法(排查方案):

  • 使用的是订阅号,订阅号没有权限使用网页授权,详细可参考接口权限:微信开放文档
  • 需要已认证的服务号
  • 网页授权回调域名填写错误
  • Scope参数顺序不对
  • 服务号不支持扫码登录,要网站应用才支持:关于微信快速登录功能的说明 | 微信开放文档
  • snsapi_userinfo的接口权限被封

https://mp.weixin.qq.com/advanced/advanced?action=table&token=1037385634&lang=zh_CN

接口权限 》网页服务》 网页权限》

0

设置网页授权域名

参考:网页授权 | 微信开放文档

参考:Scope 参数错误或没有 Scope 权限,错误码:10005 | 微信开放社区

第三步:依据接口文档实现业务逻辑

验证URL有效性成功后即接入生效,成为开发者。

你可以在公众平台网站中申请微信认证,认证成功后,将获得更多接口权限,满足更多业务需求。

成为开发者后,用户每次向公众号发送消息、或者产生自定义菜单、或产生微信支付订单等情况时,开发者填写的服务器配置URL将得到微信服务器推送过来的消息和事件,开发者可以依据自身业务逻辑进行响应,如回复消息。

公众号调用各接口时,一般会获得正确的结果,具体结果可见对应接口的说明。返回错误时,可根据返回码来查询错误原因。全局返回码说明

用户向公众号发送消息时,公众号方收到的消息发送者是一个OpenID,是使用用户微信号加密后的结果,每个用户对每个公众号有一个唯一的OpenID。

此外,由于开发者经常有需在多个平台(移动应用、网站、公众账号)之间共通用户账号,统一账号体系的需求,微信开放平台(open.weixin.qq.com)提供了UnionID机制。开发者可通过OpenID来获取用户基本信息,而如果开发者拥有多个应用(移动应用、网站应用和公众账号,公众账号只有在被绑定到微信开放平台账号下后,才会获取UnionID),可通过获取用户基本信息中的UnionID来区分用户的唯一性,因为只要是同一个微信开放平台账号下的移动应用、网站应用和公众账号,用户的UnionID是唯一的。换句话说,同一用户,对同一个微信开放平台账号下的不同应用,UnionID是相同的。详情请在微信开放平台的资源中心-移动应用开发-微信登录-授权关系接口调用指引-获取用户个人信息(UnionID机制)中查看。

另请注意,微信公众号接口必须以http://或https://开头,分别支持80端口和443端口。

9.AccessToken过期刷新

因为accessToken获取次数有限,我想在有效期7200秒内,使用同一个accessToken去请求获取用户信息,如果token过期了用刷新token去换一个新的accessToken,如果刷新token也过期了,那么再去重新请求新的accessToken,避免把当日accessToken获取次数用完。

如何实现?

为了有效管理微信 accessToken 的使用和刷新,你可以实现一个服务来处理 accessToken 的获取、存储、刷新以及过期逻辑。

这个服务将负责确保在请求微信 API 时使用有效的 accessToken,并在必要时自动刷新。

实现步骤:

(1)存储 accessToken 和 refreshToken:

你可以使用数据库或内存缓存(如 Redis)来存储 accessToken、refreshToken 及其过期时间。

(2)获取 accessToken 的服务方法:

  • 检查当前存储的 accessToken 是否有效。
  • 如果有效,直接返回它。
  • 如果无效,检查 refreshToken 是否还有效。
  • 如果 refreshToken 有效,使用它来获取新的 accessToken。
  • 如果 refreshToken 也失效,重新进行认证以获取新的 accessToken 和 refreshToken。

10.开发者注意事项

(1)微信公众平台开发

是指为微信公众号进行业务开发,为移动应用、PC端网站、公众号第三方平台(为各行各业公众号运营者提供服务)的开发,请前往微信开放平台接入。

(2)在申请到认证公众号之前,你可以先通过测试号申请系统,快速申请一个接口测试号,立即开始接口测试开发。

(3)在开发过程中,可以使用接口调试工具来在线调试某些接口。

(4)每个接口都有每日接口调用频次限制,可以在公众平台官网-开发者中心处查看具体频次。

(5)在开发出现问题时,可以通过接口调用的返回码,以及报警排查指引(在公众平台官网-开发者中心处可以设置接口报警),来发现和解决问题。

(6)公众平台以access_token为接口调用凭据,来调用接口,所有接口的调用需要先获取access_token,access_token在2小时内有效,过期需要重新获取,但1天内获取次数有限,开发者需自行存储,详见获取接口调用凭据(access_token)文档。10.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/32878.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试:关于word2vec的相关知识点Hierarchical Softmax和NegativeSampling

1、为什么需要Hierarchical Softmax和Negative Sampling 从输入层到隐含层需要一个维度为NK的权重矩阵&#xff0c;从隐含层到输出层又需要一个维度为KN的权重矩阵&#xff0c;学习权重可以用反向传播算法实现&#xff0c;每次迭代时将权重沿梯度更优的方向进行一小步更新。但…

100337. 最大化子数组的总成本

Powered by:NEFU AB-IN Link 文章目录 100337. 最大化子数组的总成本题意思路代码 100337. 最大化子数组的总成本 题意 给你一个长度为 n 的整数数组 nums。 子数组 nums[l…r]&#xff08;其中 0 < l < r < n&#xff09;的 成本 定义为&#xff1a; cost(l, r)…

详细解析MATLAB和Simulink中的文件格式:mat, mdl, mexw32, 和 m 文件

matlab 探索MATLAB和Simulink中的文件格式&#xff1a;MAT, MDL, MEXW32, 和 M 文件**MAT 文件 (.mat)****MDL 文件 (.mdl)****MEX 文件 (.mexw32/.mexw64)****M 文件 (.m)****总结** 探索MATLAB和Simulink中的文件格式&#xff1a;MAT, MDL, MEXW32, 和 M 文件 当你开始使用M…

Python 虚拟环境 requirements.txt 文件生成 ;pipenv导出pip安装文件

搜索关键词: Python 虚拟环境Pipenv requirements.txt 文件生成;Pipenv 导出 pip requirements.txt安装文件 本文基于python版本 >3.9 文章内容有效日期2023年01月开始(因为此方法从这个时间开始是完全ok的) 上述为pipenv的演示版本 使用以下命令可精准生成requirement…

【Vue】图片懒加载的实现

封装全局指令img-lazy // 定义懒加载插件 import { useIntersectionObserver } from vueuse/coreexport const lazyPlugin {install (app) {// 懒加载指令逻辑app.directive(img-lazy, {mounted (el, binding) {// el: 指令绑定的那个元素 img// binding: binding.value 指令…

總結電磁學

參考: 陈曦<<电磁学讲义>>http://ithatron.phys.tsinghua.edu.cn/downloads/electricty_and_magnetism.pdf 4 电磁学的实验基础 我们已经回顾了经典物理学的框架。在现代物理学中,人们经常从一些基本的原则(如相对论协变性、对称性等等)出发来建立模型,然后…

Java8 --- Gradle7.4整合IDEA

目录 一、Gradle整合IDEA 1.1、Groovy安装 1.1.1、配置环境变量 ​编辑 1.2、创建项目 ​编辑 1.3、Groovy基本语法 1.3.1、基本语法 1.3.2、引号 1.3.3、语句结构 1.3.4、数据类型 1.3.5、集合操作 1.4、使用Gradle创建普通Java工程 1.5、使用Gradle创建Java ss…

深入理解go语言反射机制

1、前言 每当我们学习一个新的知识点时&#xff0c;一般来说&#xff0c;最关心两件事&#xff0c;一是该知识点的用法&#xff0c;另外就是使用场景。go反射机制作为go语言特性中一个比较高级的功能&#xff0c;我们也需要从上面两个方面去进行学习&#xff0c;前者告诉我们如…

如何在Java中进行网络编程?

如何在Java中进行网络编程&#xff1f; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将探讨如何在Java中进行网络编程&#xff0c;这是实现客户端和服…

Vite: 关于静态资源的处理机制

概述 随着前端技术的飞速发展&#xff0c;项目规模和复杂度不断增加&#xff0c;如何高效地处理静态资源成为了提升开发效率和应用性能的关键Vite&#xff0c;作为新一代前端构建工具&#xff0c;以其轻量级、快速启动和热更新著称&#xff0c;同时也为静态资源的管理和优化提…

使用 axios 进行 HTTP 请求

使用 axios 进行 HTTP 请求 文章目录 使用 axios 进行 HTTP 请求1、介绍2、安装和引入3、axios 基本使用4、axios 发送 GET 请求5、axios 发送 POST 请求6、高级使用7、总结 1、介绍 什么是 axios axios 是一个基于 promise 的 HTTP 库&#xff0c;可以用于浏览器和 Node.js 中…

计算机组成入门知识

前言&#x1f440;~ 数据库的知识点先暂且分享到这&#xff0c;接下来开始接触计算机组成以及计算机网络相关的知识点&#xff0c;这一章先介绍一些基础的计算机组成知识 一台计算机如何组成的&#xff1f; 存储器 CPU cpu的工作流程 主频 如何衡量CPU好坏呢&#xff1f…

创意产业如何应对AI的挑战。

最近的一个月&#xff0c;音乐领域迎来了一个革命性的变化。一系列音乐大模型轮番上线&#xff0c;它们以惊人的创作能力&#xff0c;将素人生产音乐的门槛降到了最低。这些AI音乐模型的出现&#xff0c;引发了关于AI是否会彻底颠覆音乐圈的讨论。然而&#xff0c;短暂的兴奋过…

我的常见问题记录

1,maven在idea工具可以正常使用,在命令窗口执行出现问题 代码: E:\test-hello\simple-test>mvn clean compile [INFO] Scanning for projects... [WARNING] [WARNING] Some problems were encountered while building the effective model for org.consola:simple-test:jar…

【从0实现React18】 (三) 初探reconciler 带你初步探寻React的核心逻辑

Reconciler 使React核心逻辑所在的模块&#xff0c;中文名叫协调器&#xff0c;协调(reconciler)就是diff算法的意思 reconciler有什么用&#xff1f; 在前端框架出现之前&#xff0c;通常会使用 jQuery 这样的库来开发页面。jQuery 是一个过程驱动的库&#xff0c;开发者需要…

【windows解压】解压文件名乱码

windows解压&#xff0c;文件名乱码但内容正常。 我也不知道什么时候设置出的问题。。。换了解压工具也没用&#xff0c;后来是这样解决的。 目录 1.环境和工具 2.打开【控制面板】 3.点击【时钟和区域】 4.选择【区域】 5.【管理】中【更改系统区域设置】 6.选择并确定…

算是一些Transformer学习当中的重点内容

一、基础概念 Transformer是一种神经网络结构&#xff0c;由Vaswani等人在2017年的论文Attentions All YouNeed”中提出&#xff0c;用于处理机器翻译、语言建模和文本生成等自然语言处理任务。Transformer同样是encoder-decoder的结构&#xff0c;只不过这里的“encoder”和“…

设计模式——工厂方法模式

文章目录 工厂方法模式简介工厂方法模式的组成部分工厂方法模式的结构Factory和Method的含义工厂方法模式的应用场景工厂方法模式的示例1. 文档生成器2. 数据库连接 工厂方法模式简介 工厂方法模式&#xff08;Factory Method Pattern&#xff09;是一种创建型设计模式&#x…

安卓设备屏幕分辨率适配

需求 适配1.83寸的手表屏幕 屏幕分辨率为240px*284px dpi203.18 计量单位 px &#xff08;Pixels&#xff09;&#xff1a; 其实就是像素单位&#xff0c;是屏幕上最小可见的单元&#xff0c;比如我们通常说的手机分辨列表800*400都是px的单位&#xff08;px 的单位是 像素&am…