微信公众号开发入门demo,获取toekn,用户个人信息等

1.微信公众号测试平台

http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

扫描进入后可以获得appid和appsecret

并且需要配置自己的域名

2.工具类,java发送HTTP请求的

package com.test.util;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;


public class Util {
	private static final String DEF_CHARSET="UTF-8";
	
	/**
	 * 向指定的地址发送get请求
     * 如果地址中有中文可能会造成乱码,可以用URLEncoder.encode("中文", "UTF-8")处理
	 * @param url
	 * @return
	 */
	public static String get(String url) {
		StringBuilder sBuilder = new StringBuilder();
		try {
			URL urlObj = new URL(url);
			//开链接
			URLConnection connection = urlObj.openConnection();
			InputStream is = connection.getInputStream();
			byte[] b = new byte[1024];
			int len;
			
			while ((len=is.read(b))!=-1 ) {
				sBuilder.append(new String(b,0,len)); 
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		
		return sBuilder.toString();
	}
	/**
	 * 向指定地址发送post请求,带着数据  
	 * data格式"qrcode=1111&longitude=21.222&latitude=23.344&address=空间大姐夫"
	 * @param url
	 * @param data
	 * @return
	 */
	public static String post(String url,String data) {
		StringBuilder sBuilder = new StringBuilder();
		try {
			URL urlObj = new URL(url);
			//开链接
			URLConnection connection = urlObj.openConnection();
			connection.setRequestProperty("charset", "utf-8");
			
			//要发送数据出去,必须要设置为可发送数据状态
			connection.setDoOutput(true);
			//获取输出流
			OutputStream os = connection.getOutputStream();
			//写出数据
			os.write(data.getBytes());
			os.close();
			//获取输入流读取数据
			InputStream is = connection.getInputStream();
			byte[] b = new byte[1024];
			int len;
			
			while ((len=is.read(b))!=-1 ) {
				sBuilder.append(new String(b,0,len)); 
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return sBuilder.toString();
	}
	public static void main(String[] args) {
		
		post("http://192.168.1.4:8080/zzserver/qrcodejb/saveQRCodeJB","qrcode=1111&longitude=21.222&latitude=23.344&address=空间大姐夫");

	}
}

3.写一个servlet

package com.test.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.test.service.WxService;

import net.sf.json.JSONObject;


/**
 * Servlet implementation class TestServlet
 */
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public TestServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String code = request.getParameter("code");
		String result=WxService.getOpenId(code);
		//String token = JSONObject.fromObject(result).getString("access_token");此种方法获取的token会报错!!!!!!!!!!!
		String token =WxService.getAccessToken();
		String openid = JSONObject.fromObject(result).getString("openid");
		System.out.println("doget======token:"+token);
		System.out.println("doget======openid:"+openid);
		String userInfo=WxService.getUserInfo(token,openid);
		System.out.println(userInfo);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

4.写一个service

package com.test.service;

import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.test.model.AccessToken;
import com.test.util.*;

import jdk.nashorn.api.scripting.URLReader;
import net.sf.json.JSONObject;


public class WxService {
	private static final String APPID="你自己公众号的appid";
	private static final String APPSECRET="你自己公众号的APPSECRET";
	private static final String GET_TOKEN_URL="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	//用于存储token
	private static AccessToken at;
	/**
	 * 获取token
	 */
	private static void getToken() {
		String url = GET_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET);
		System.out.println(url);
		String str = Util.get(url);
		
		
		
		JSONObject object= JSONObject.fromObject(str);
		String token = object.getString("access_token");
		String expireIn = object.getString("expires_in");
		//创建token对象并存起来
		at = new AccessToken(token,expireIn);
		
		
	}
	/**
	 * 向外暴露获取token的方法
	 * @return
	 */
	public static String getAccessToken() {
		if(at==null || at.isExpired()) {
			System.out.println("1");
			
			getToken();
		}
		return at.getAccessToken();
	}
	/**
	 * 获取用户的基本信息
	 * @param openId
	 * @return
	 */
	public static String getUserInfo(String accessToken,String openId) {
		String url="https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
		url = url.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
		String result=Util.get(url);
		System.out.println("getUserInfo:"+result);
		return  result;
	}
	/**
	 * 根据code获取openId
	 * 注意:此方法只能获取openid,accesstoken要用getAccessToken()获取,否则报错;
	 * @param code
	 * @return
	 * {"access_token":"17_GGijMMF0rx8PpOrQ7QaHXzXvWa5TuaHl4TJ_uTrL0t4SJNy9KdX2OqUytRmMnFto919ikZEH_pwNolsolZUJ49PaEMSP1lXc80VKa53r0fo","expires_in":7200,"refresh_token":"17_MhG27a3Y84FJEAms_8P-LQx1sfCRwlRy5DFG3zHJ28XuSqLr94GgSd8H9fZVx7Cz8eoy5nMuO0RfflJHcOi7K3Izvf-z2nBhFB2dlScfqgo","openid":"opPyS0gqyIf5bDT0hpyahIAOl5iU","scope":"snsapi_userinfo"}
	 */
	public static String getOpenId(String code) {
		String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
		url=url.replace("APPID", APPID).replace("SECRET", APPSECRET).replace("CODE", code);
		String result = Util.get(url);
		System.out.println("getOpenId:"+result);
		return result;
	}
	public static void main(String[] args) {
		//getAccessToken();
		//getUserInfo("");
	}
	
	
	
	
	/**
	 * 验证签名
	 */
	public static boolean check(String token, String timestamp, String nonce, String signature) {
		/**
		 * 1)将token、timestamp、nonce三个参数进行字典序排序 
		 * 2)将三个参数字符串拼接成一个字符串进行sha1加密 
		 * 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
		 */
		String[] strs=new String[] {token,timestamp,nonce};
		System.out.println(strs);
		Arrays.sort(strs);
		System.out.println(strs);
		String str = strs[0]+strs[1]+strs[2];
		String mysig=sha1(str);
		System.out.println(mysig);
		System.out.println(signature);
		
		return mysig.equalsIgnoreCase(signature);
	}
	
	private static String sha1(String str) {
		//获取一个加密对象
		try {
			MessageDigest md = MessageDigest.getInstance("sha1");
			//加密
			byte[] digest = md.digest(str.getBytes());
			char[] chars = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
			StringBuilder sb = new StringBuilder();
			//处理加密结果
			for(byte b:digest) {
				sb.append(chars[(b>>4)&15]);
				sb.append(chars[b&15]);
				
			}
			return sb.toString();
			
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public static Map<String, String> parseRequest(HttpServletRequest request) {
		Map<String,String> map = new HashMap<String,String>();
		try {
			InputStream is=request.getInputStream();
			SAXReader reader = new SAXReader();
			//读取输入流
			Document document = reader.read(is);
			//根据文档对象获取节点
			Element root = document.getRootElement();
			//获取根节点的所有子节点
			List<Element> elements = root.elements();
			for (Element e : elements) {
				map.put(e.getName(), e.getStringValue());
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return map;
	}

}

5.用来存放token的实体类

package com.test.model;

public class AccessToken {
	private String accessToken;
	private long expireTime;
	public String getAccessToken() {
		return accessToken;
	}
	public void setAccessToken(String accessToken) {
		this.accessToken = accessToken;
	}
	public long getExpireTime() {
		return expireTime;
	}
	public void setExpireTime(long expireTime) {
		this.expireTime = expireTime;
	}
	public AccessToken(String accessToken, String expireIn) {
		super();
		this.accessToken = accessToken;
		
		this.expireTime = System.currentTimeMillis()+Integer.parseInt(expireIn)*1000;
	}
	/**
	 * 查看是否国企
	 * @return
	 */
	public boolean isExpired() {
		return System.currentTimeMillis()>expireTime;
	}
}

 

项目源码以及jar等在github上,地址为 https://github.com/441985745/studyWechat

### 在Spring中使用CorsRegistry配置CORS 为了在Spring应用中配置跨域资源共享(CORS),可以通过实现`WebMvcConfigurer`接口并重写`addCorsMappings`方法来完成。此方法接收一个`CorsRegistry`对象作为参数,该对象提供了向注册表添加映射的方法。 下面是一个具体的例子: ```java @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") // 应用到所有 /api 开头的请求路径 .allowedOrigins("http://example.com", "https://anotherdomain.org") // 允许来自指定源的请求 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许特定 HTTP 方法 .allowedHeaders("header1", "header2", "header3") // 允许自定义请求头 .exposedHeaders("header1", "header2") // 暴露给浏览器额外的响应头 .allowCredentials(true) // 是否支持凭证 .maxAge(3600); // 预检请求的结果缓存时间 () } } ``` 这段代码展示了如何利用`CorsRegistry`来进行详细的 CORS 设置[^3]。这里指定了 `/api/` 下的所有 URL 可以被某些特定域名发起带有凭证的信息交互,并且限定了可使用的 HTTP 请求方式和头部字段等内容。 对于更复杂的场景,比如基于不同的端点有不同的 CORS 政策需求,则可以在同一个 `addCorsMappings()` 中多次调用 `addMapping()` 来分别设定不同路径下的规则。 当涉及到安全框架如 Spring Security 的时候,如果发现 CORS 配置不起作用,可能是因为 Spring Security 默认会覆盖掉全局级别的 CORS 设置。此时应该考虑调整 Spring Security 的配置逻辑或者按照官方文档指导的方式正确集成两者之间的协作关系[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值