errcode“:40001,“errmsg“:“invalid credential, access_token is invalid or not latest, could get access

今天做组件的时候需要连接微信测试号,GitHub上Action时代码没有出错,手机测试接不到消息。后来发现https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s中,%s误写为‘?’。好家伙,一个符号竟然浪费了许多时间,还是功夫不到家。

由此也引发了String.format()方法的延申思考。

在Java中,String.format() 方法用于创建格式化的字符串。在这个方法中,%s 是一个占位符,用于指示该位置将被后面参数列表中相应的字符串值所替换。具体来说,%s 对应于 String 类型的参数。

在正确的代码示例中:

 

java复制代码

String url = String.format("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s", accessToken);

%s 将会被 accessToken 变量的值所替换。假设 accessToken 的值是 "YOUR_ACCESS_TOKEN_HERE",那么执行这行代码后,url 变量的值将会是:

https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=YOUR_ACCESS_TOKEN_HERE

这种方式使得在构建需要动态插入数据的URL时非常方便和灵活。String.format() 方法还支持其他类型的占位符,如 %d 用于整数、%f 用于浮点数等,以便构建包含不同类型数据的字符串。

但是

如果尝试将 %s 替换为 ?,在 String.format() 方法的上下文中,这会导致一个异常,因为 ? 不是一个有效的格式说明符。String.format() 方法期望在字符串中的每个 % 后面跟随一个有效的格式说明符,比如 %s%d%f 等,来指示如何格式化相应的参数。

当我写如下代码:

String url = String.format("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=?", accessToken);

这里的 ? 不会被 accessToken 的值所替换,因为 ? 不是一个有效的占位符。相反,String.format() 会尝试将 ? 作为字符串的一部分直接保留在结果中,并且因为后面没有跟随有效的参数(在这个例子中,%s 才是期望的占位符),它可能会抛出一个 MissingFormatArgumentException(如果后续还有其他有效的占位符和参数,但在这个特定例子中不会),或者更常见的是,如果 ? 后面没有其他占位符,它只会简单地忽略这个无效的格式说明符并继续处理字符串。

然而,在此例子中,由于 ? 后面没有其他占位符,并且 accessToken 参数没有被正确地用于替换任何占位符,所以 accessToken 的值实际上并没有被插入到字符串中。因此,url 变量的值将会是:

https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=?

这并不是我们想要的结果,因为想要的是将 accessToken 的值插入到 URL 中。

为了修复这个问题,应该继续使用 %s 作为占位符,并确保它后面有相应的参数来替换它:

String url = String.format("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s", accessToken);

这样,%s 就会被 accessToken 的值所替换,生成正确的 URL。

当然

“?”也是可以作为占位符使用的

?在JDBC的PreparedStatement中用作参数占位符,这是另一种上下文,其中?用于在执行SQL语句之前插入参数值。在PreparedStatement中,可以使用setXXX()方法(如setInt()setString()等)为这些?占位符提供值。

例如,在JDBC中,可能会看到这样的代码:

String sql = "SELECT * FROM users WHERE id = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, 123); // 将第一个?替换为整数123
ResultSet rs = pstmt.executeQuery();

在这个例子中,?PreparedStatement中用于参数化的占位符,它允许你在执行查询之前安全地设置参数值,从而防止SQL注入攻击。

但请注意,这种用法与String.format()方法中的占位符(如%s)是完全不同的。在String.format()中,你需要使用%后跟适当的格式说明符来指定如何格式化并插入参数值。如果你尝试在String.format()中使用?作为占位符,它将被视为普通字符,并且不会被任何参数值所替换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值