前几天开发了微信公众号,趁今天有时间,总结一下。
注意几点:
1.服务器地址URL这是要配置你的域名加你验证Token的接口路径,记住,是完整路径!。如果是通过了穿透,那么就是127.0.0.1/端口/Controller路径/方法路径!
2.令牌Token问题,在微信公众号基本配置里面可以随意填写,但是在服务端,也就是你的后台接口程序中的Token必须对应!
3.消息加解密密钥,这个在公众号可以弄成自动生成32的密钥。
4.加解密方式,本人用的是明文。
5.Token每天获取数量有限制,每次获取有效期是7200,也就是2小时,记得用容器保存。可以存储在Redis,设置一个有效期7200!
以下是代码:
1.工具类Httprequests
public static String sendGet (String url,String param) {
String result ="";
BufferedReader in =null;
try {
String urlNameString = url +"?" +param;
System.out.println("发送的链接请求:"+urlNameString);
URL reaurl = new URL(urlNameString);
URLConnection connection = reaurl.openConnection();
//设置通用
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
//建立实际的连接
connection.connect();
Map<String, List<String>> map = connection.getHeaderFields();
//定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
/**
* 向指定 URL 发送POST方法的请求
* @param url 发送请求的 URL
* @param param 参数
* @return String 所代表远程资源的响应结果
*/
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result;
}
/**
* 拿到ip
* @param req request作用域:
* @return String
*/
public static String getRemoteIP(HttpServletRequest req) {
String ip = req.getHeader("X-Real-IP");
if (ip == null || ("").equals(ip)) {
ip = req.getRemoteAddr() == null ? "127.0.0.1" : req.getRemoteAddr();
}
return ip;
}
/**
* 生成
* @param num 参数
* @return String
*/
public static String getPamens(Integer num){
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < num; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
2.写一个Service接口,返回Map类型。
/**
* 获取微信Token
* @return
*/
Map<String, Object> accessToken();
3.实现接口 lmpl
/**
* 拿到Token
* @return
*/
@Override
public Map<String, Object> accessToken() {
String param="grant_type="+ WxModel.grant_type+"&appid="+WxModel.appid+"&secret="+WxModel.wxspSecret;
//获取接口凭证
String sendGet= Httprequests.sendGet(WxModel.select_access_token,param);
System.out.println("发送git请求的返回值:"+sendGet);
JSONObject json = JSONObject.parseObject(sendGet);
String access_token=json.getString("access_token"); //凭证
System.out.println("获取的access_token:"+access_token);
int expires_in= json.getInteger("expires_in"); //凭证有效时间,单位:秒
System.out.println("有效的时间:"+expires_in);
System.out.print("获取凭证成功");
System.out.println("返回的数据:"+access_token);
Map<String, Object> map = new HashMap<String, Object>();
map.put("access_token", access_token);
map.put("expires_in", expires_in);
RedisUtil.setex("access_token",access_token,7200 );
return map;
}
4.关于WxModel,这个是要你公众号的grant_type,appid,wxspSecret,你可以登录你的公众号进行查看。在首页就可以看到
5 .Controller,如果运行报请求要用GET请求,那么就把POST换成GET。
/**
* 验证token
* @param request
* @param response
* @return
*/
@PostMapping(value= {"/getProcessRequest"})
@ResponseBody
public String getProcessRequest(HttpServletRequest request, HttpServletResponse response) {
boolean isGet=request.getMethod().toLowerCase().equals("get");
System.out.println(isGet);
System.out.println("方法是-------"+isGet);
// 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
String signature = request.getParameter("signature");
// 时间戳
String timestamp = request.getParameter("timestamp");
// 随机数
String nonce = request.getParameter("nonce");
// 随机字符串
String echostr = request.getParameter("echostr");
PrintWriter out = null;
try {
out = response.getWriter();
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,否则接入失败
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
System.out.println("成功");
out.print(echostr);
out.flush(); //必须刷新
}
} catch (IOException e) {
e.printStackTrace();
} finally {
out.close();
}
}
总结完毕,在此要感谢我一个同学,他开发过这方面,让我少爬了很多坑。代码是完整的,希望可以帮助到大家。
不懂可以加QQ群: 914084240