1、application.yml配置文件
wechat:
appid: xxxxx
appsecret: xxxxx
template-id: xxxxxxx
配置注入
@Value("${wechat.appid}")
private String appId;
@Value("${wechat.appsecret}")
private String appSecret;
@Value("${wechat.template-id}")
private String templateId;
2、获取AccessToken
public String getWXAccessToken(){
RestTemplate restTemplate = new RestTemplate();
String apiURL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;
ResponseEntity<String> responseEntity = restTemplate.getForEntity(apiURL, String.class);
JSONObject jsonObject = JSONObject.parseObject(responseEntity.getBody());
String accessToken="";
if(jsonObject.get("access_token")!=null)
{
accessToken= (String) jsonObject.get("access_token");
}
return accessToken;
}
2、推送微信服务号信息
@Override
public String sendTemplateMsg(String openid, String msg, String template_id, String accessToken) throws Exception {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
// 构建模板消息内容
Map<String, Object> message = new HashMap<>();
message.put("touser", openid);
message.put("template_id", template_id);
Map<String, Object> data = JSON.parseObject(msg, Map.class);
message.put("data", data);
//将消息转换为JSON格式
ObjectMapper objectMapper = new ObjectMapper();
String jsonValue = objectMapper.writeValueAsString(message);
HttpEntity<String> request = new HttpEntity<>(jsonValue, headers);
String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
// 发送POST请求
String response = restTemplate.postForObject(url, request, String.class);
logger.info("sendTemplateMsg==openid:{}==msg:{}==template_id:{}==accessToken:{}==response:{}",
openid, msg, template_id,accessToken,response);
return response;
}
这段代码是一个Java方法,用于发送微信模板消息。以下是对代码的简单解释:
-
方法函数接收四个参数:用户的openid,模板消息内容,模板ID以及微信接口的访问token。
-
在方法体中,首先创建一个
RestTemplate
对象,设置HTTP头部的 "Content-Type" 为 "application/json"。 -
然后创建模板消息的内容,这是一个
Map
对象,包括 "touser"(接收用户的openid),"template_id"(模板ID)和 "data"(模板消息内容)。 "data" 的值是将模板消息内容字符串转化为Map
对象。 -
接着利用
ObjectMapper
(Jackson库的一个类,用于在Java对象和JSON之间进行转换)将Map
对象转换为JSON格式的字符串。 -
创建
HttpEntity
对象,包含JSON格式的模板消息和HTTP头部,用于发送POST请求。 -
拼接微信模板消息发送接口的URL,接口URL需要access_token作为参数。
-
利用
RestTemplate
发送POST请求,发送模板消息。 -
记录日志,并返回响应。
-
此函数假定传入的
msg
参数是JSON格式的字符串,如果不是,可能会导致JSON.parseObject(msg, Map.class);
这行代码出错。
参数样例
"msg": "{\"time4\":{\"color\":\"#173177\",\"value\":\"2024-03-30 00:42:18\"},\"thing7\":{\"color\":\"#173177\",\"value\":\"张三\"},\"thing16\":{\"color\":\"#173177\",\"value\":\"河北省沧州市献县乐寿镇冯庄村288号\"},\"car_number11\":{\"color\":\"#173177\",\"value\":\"粤A888888\"}}"
3、调用微信 OCR 接口对车牌号进行识别
@Override
public String getPlateNumberOcr(String imageUrl, String accessToken) throws UnsupportedEncodingException {
String encodedImageUrl = URLEncoder.encode(imageUrl, StandardCharsets.UTF_8.toString());
String apiURL = "https://api.weixin.qq.com/cv/ocr/platenum";
String requestUrl = apiURL + "?img_url=" + encodedImageUrl + "&access_token=" + accessToken;
logger.info("---getPlateNumberOcr--requestUrl={}",requestUrl);
RestTemplate restTemplate = new RestTemplate();
// ResponseEntity<String> response = restTemplate.postForEntity(apiURL, null, String.class);
// return response.getBody();
// 创建请求头
HttpHeaders headers = new HttpHeaders();
// headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); // 根据API要求设置
// 创建一个Map来存储请求参数
MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
map.add("img_url", imageUrl);
map.add("access_token", accessToken);
// 使用Http头和请求参数创建Http实体
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
// 发送post请求,并得到响应
ResponseEntity<String> response = restTemplate.postForEntity( requestUrl, request, String.class );
return response.getBody();
}
以下是对代码段的一些解析:
-
首先,该方法以图片链接(imageUrl)和访问token(accessToken)作为参数。
-
它使用
URLEncoder.encode
方法将图片URL进行UTF-8编码。 -
然后,它构建了请求URL,包括微信OCR API以及URL参数 "img_url" 和 "access_token"。
-
使用
logger.info
记录请求信息。 -
创建了一个新的
RestTemplate
对象用于发送HTTP请求。 -
创建一个
MultiValueMap
用来存储请求参数,并添加 "img_url" 和 "access_token"。 -
使用Http头和前面创建的
MultiValueMap
构造了一个HttpEntity
。 -
使用
RestTemplate
的postForEntity
方法发送了一个POST请求。 -
请求的响应体被返回。
3、微信授权链接并重定向到这个链接
@GetMapping(value = "/getWxAuthLink")
public RedirectView getWxAuthLink(HttpServletRequest request) throws UnsupportedEncodingException {
// 重定向的回调链接地址,一般设置为当前的服务器地址
// String redirectUri = "https://clbz.scu.edu.cn/wt/#/pages/welcome/welcome";
String encodedRedirectUri = URLEncoder.encode(redirectUri, StandardCharsets.UTF_8.toString());
// 配置微信授权链接
String wxAuthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize" +
"?appid=" + iWxSendService.getAppId() +
"&redirect_uri=" + encodedRedirectUri +
"&response_type=code" +
"&scope=snsapi_base" + // 使用snsapi_base类型的授权获取openid
"&state=STATE#wechat_redirect";
//创建重定向视图并返回
RedirectView redirectView = new RedirectView(wxAuthUrl);
return redirectView;
}
这个Java方法的作用是构建一个微信授权链接并重定向到这个链接。以下是针对代码段的一些解析:
-
方法基于HTTP GET请求。
-
在函数体中构建的微信授权链接中,
appid
是微信开放平台注册应用时获得的,redirect_uri
是当用户在微信浏览器中访问这个链接,并完成授权后,微信浏览器重定向回的URL。这里对redirect_uri
进行了URL编码。 -
response_type
指定的值为code
,表示授权类型是授权码模式。微信服务器将会在重定向的同时,通过URL参数将授权码返回给redirect_uri
。 -
scope
设置为snsapi_base
,表示应用授权作用域为 "snsapi_base",即获取用户的openid,对用户无感知。 -
state
是可选参数,可以通过这个参数携带应用的原始状态。 -
这个链接访问后将会跳转到微信的一个页面,用户同意授权后,微信则会跳转回
redirect_uri
,并附带上授权码和原始状态。 -
最后,方法创建了一个
RedirectView
对象以重定向到微信授权链接。
需要注意,redirectUri
的值在这段代码中并未指定。根据注释和被注释的代码,我们可以推测其值应该是“violation-registration-applet”,但必须由调用者来提供。此外,iWxSendService.getAppId()
是从某它服务里获取微信公众号的 appId,这个服务应该提前注入到当前的类中。
3、获取微信公众号上的所有模板列表
@GetMapping("/getTemplateList")
public String getTemplateList() {
String accessToken=iWxSendService.getWXAccessToken();
RestTemplate restTemplate = new RestTemplate();
String url = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token="
+ accessToken;
return restTemplate.getForObject(url, String.class);
}
这段Java方法用于获取微信公众号上的所有模板列表。以下是对代码的简单阐释:
-
首先,获取微信公众号的访问令牌,这个令牌让微信公众号的操作具有一定权限。
-
然后,创建一个
RestTemplate
对象,用于发送 HTTP 请求。 -
接着创建一个 URL,其中包含了获取所有模板列表的微信 API,以及之前获取的微信公众号的访问令牌。
-
最后,使用
RestTemplate
的getForObject
方法发送 HTTP 的 GET 请求。请求的响应体将被直接以String
类型返回。