生成微信二维码

package com.common.utils;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;


/**
 * @author EX-CHENKEFENG001
 * 
 *         微信验证、二维码生成工具类
 * 
 */
public class WechatValidateUtils {
	private static final boolean NEEDCOMPRESS = false;
	
	private static String LOGO_URL;
    // LOGO宽度
    private static final int WIDTH = 60;
    // LOGO高度
    private static final int HEIGHT = 60;
    
    static{
    	 LOGO_URL = PropertiesUtils.getProperty("context-ilife_core.properties", "pemobi.dmz.logo.url");
    }
    
	/**
	 * 生成二维码的工具类
	 * 
	 * @param data
	 *            二维码中携带的数据
	 * @param width
	 *            二维码的宽度
	 * @param height
	 *            二维码的高度
	 * @return 返回base64格式的图片(https://img-blog.csdnimg.cn/2022010618054783822.gif) <br>
	 *         eg: <code>
	 * &ltimg alt="" src="https://img-blog.csdnimg.cn/2022010618054783822.gif"&gt
	 * </code>
	 */
	public static String generateQRCode(String data, int width, int height,String isPicture) {

		Assert.assertTrue("param data cannot empty.", data != null
				&& data.trim().length() > 0);

		Assert.assertTrue("param width and height must gt 0.", width > 0
				&& height > 0);

		ByteArrayOutputStream bos = null;

		MultiFormatWriter formatWriter = new MultiFormatWriter();

		Hashtable<EncodeHintType, Object> param = new Hashtable<EncodeHintType, Object>();
		param.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
		param.put(EncodeHintType.CHARACTER_SET, "utf-8");
		param.put(EncodeHintType.MARGIN, 0);

		try {
			BitMatrix bitMatrix = formatWriter.encode(data,
					BarcodeFormat.QR_CODE, width, height, param);
			//1.1去白边
			int[] rec = bitMatrix.getEnclosingRectangle();  
			int resWidth = rec[2] + 1;  
			int resHeight = rec[3] + 1;  
			BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);  
			resMatrix.clear();  
			for (int i = 0; i < resWidth; i++) {  
			    for (int j = 0; j < resHeight; j++) {  
			        if (bitMatrix.get(i + rec[0], j + rec[1])) { 
			             resMatrix.set(i, j); 
			        } 
			    }  
			}  
			int width1 = resMatrix.getWidth();
			int height1 = resMatrix.getHeight();
			BufferedImage qrcode = new BufferedImage(width1, height1,
					BufferedImage.TYPE_INT_RGB);
			for (int x = 0; x < width1; x++) {
			    for (int y = 0; y < height1; y++) {
			    	qrcode.setRGB(x, y, resMatrix.get(x, y) == true ? 
			        Color.BLACK.getRGB():Color.WHITE.getRGB());
			    }
			}
				if(CommonUtil.isNotNull(LOGO_URL) && CommonUtil.isNotNull(isPicture)){
					insertImage(width1,qrcode,LOGO_URL,NEEDCOMPRESS);
				}
				Logger.INFO("LOGO_URL------------------------"+LOGO_URL);
			bos = new ByteArrayOutputStream();
			ImageIO.write(qrcode, "png", bos);
			
			String img = StringUtils.deleteWhitespace(Base64
					.encodeBase64String(bos.toByteArray()));
			return String.format("data:image/png;base64,%s", img);
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e) {
				}
			}
		}

	}
    private static void insertImage(int QRCODE_SIZE,BufferedImage source, String imgPath,
            boolean needCompress) throws Exception {
        File file = new File(imgPath);
        if (!file.exists()) {
            System.err.println(""+imgPath+"   该文件不存在!");
            return;
        }
        Image src = ImageIO.read(new File(imgPath));
        int width = src.getWidth(null);
        int height = src.getHeight(null);
        if (needCompress) { // 压缩LOGO
            if (width > WIDTH) {
                width = WIDTH;
            }
            if (height > HEIGHT) {
                height = HEIGHT;
            }
            Image image = src.getScaledInstance(width, height,
                    Image.SCALE_SMOOTH);
            BufferedImage tag = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
            Graphics g = tag.getGraphics();
            g.drawImage(image, 0, 0, null); // 绘制缩小后的图
            g.dispose();
            src = image;
        }
        // 插入LOGO
        Graphics2D graph = source.createGraphics();
        int x = (QRCODE_SIZE - width) / 2;
        int y = (QRCODE_SIZE - height) / 2;
        graph.drawImage(src, x, y, width, height, null);
       // Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
        graph.setStroke(new BasicStroke(3f));
        //graph.draw(shape); 去除图片白边
        graph.dispose();
    }

   
	/**
	 * @param data
	 *            二维码携带的数据
	 * @param size
	 *            二维码的宽、高
	 * @return
	 * @see WechatValidateUtils#generateQRCode(String, int, int)
	 */
	public static String generateQRCode(String data, int size,String isPicture) {
		return generateQRCode(data, size, size,isPicture);
	}

	/**
	 * 校验姓名是否合法
	 * 
	 * @param name
	 * @return 验证通过true,否则false
	 */
	public static boolean validateName(String name) {

		return StringUtils.isNotBlank(name);
	}

	/**
	 * 身份证号码校验
	 * 
	 * @param idNo
	 * @return 验证通过 true,否则 false
	 */
	public static boolean validateIdNo(String idNo) {
		if (StringUtils.isBlank(idNo)) {
			return false;
		}

		String reg = "^(?:\\d{8}(?:0[1-9]|1[0-2])[0123]\\d{4}|\\d{6}(?:18|19|20)\\d{2}(?:0[1-9]|1[0-2])[0123]\\d{4}[0-9X])?$";

		return idNo.matches(reg);
	}

	/**
	 * 校验手机号码是否合法
	 * 
	 * @param mobile
	 * @return 校验通过true,否则false
	 */
	public static boolean validateMobile(String mobile) {
		if (StringUtils.isBlank(mobile)) {
			return false;
		}
		String reg = "^(13|14|15|17|18)[0-9]{9}$";

		return mobile.matches(reg);
	}

	/**
	 * 根据身份证号码获取 性别,年龄
	 * 
	 * @param idNo
	 *            身份证号码
	 * @return
	 * 
	 *         <code>
	 * sex: 'M|F',
	 * birth: Date,
	 * birthStr: String(yyyy-MM-dd),
	 * age: int
	 * </code>
	 * 
	 */
	public static Map<String, Object> analyzeIdNo(String idNo, String format) {
		if (StringUtils.isBlank(idNo)) {
			return null;
		}
		Map<String, Object> result = new HashMap<String, Object>();
		if (StringUtils.isBlank(format)) {
			format = "yyyy-MM-dd";
		}
		DateFormat df = new SimpleDateFormat(format);
		DateFormat parser = new SimpleDateFormat("yyyyMMdd");

		String birthStr;
		String sex;

		switch (idNo.length()) {
		case 18:
			birthStr = idNo.substring(6, 14);
			sex = (Integer.valueOf(idNo.substring(16, 17)) % 2) == 0 ? "F"
					: "M";
			break;
		case 15:
			birthStr = String.format("19%s", idNo.substring(6, 12));
			sex = (Integer.valueOf(idNo.substring(14, 15)) % 2) == 0 ? "F"
					: "M";
			break;
		default:
			return null;
		}
		try {
			Date birth = parser.parse(birthStr);
			result.put("sex", sex);
			result.put("birth", birth);
			result.put("birthStr", df.format(birth));
			result.put("age", DateUtil.calculateAgeInBirth(birth, new Date()));

			return result;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static String getSHA1(String openid, String timestamp, String nonce,
			String key) {
		String[] arr = new String[] { key, timestamp, nonce, openid };
		Arrays.sort(arr);
		StringBuilder content = new StringBuilder();
		for (int i = 0; i < arr.length; i++) {
			content.append(arr[i]);
		}
		MessageDigest md = null;
		String tmpStr = null;

		try {
			md = MessageDigest.getInstance("SHA-1");
			// 将三个参数字符串拼接成一个字符串进行sha1加密
			byte[] digest = md.digest(content.toString().getBytes());
			tmpStr = byteToStr(digest);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}

		content = null;
		// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
		if(null == tmpStr) {
			return null;
		}
		return tmpStr.toLowerCase();

	}

	/**
	 * 将字节数组转换为十六进制字符串
	 * 
	 * @param byteArray
	 * @return
	 */
	private static String byteToStr(byte[] byteArray) {
		String strDigest = "";
		for (int i = 0; i < byteArray.length; i++) {
			strDigest += byteToHexStr(byteArray[i]);
		}
		return strDigest;
	}

	/**
	 * 将字节转换为十六进制字符串
	 * 
	 * @param mByte
	 * @return
	 */
	private static String byteToHexStr(byte mByte) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
				'B', 'C', 'D', 'E', 'F' };
		char[] tempArr = new char[2];
		tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
		tempArr[1] = Digit[mByte & 0X0F];

		String s = new String(tempArr);
		return s;
	}

	/**
	 * 校验openid的合法性
	 * 
	 * @param openid
	 *            授权返回的用户openid
	 * @param signature
	 *            授权后返回的加密串
	 * @param nonce
	 *            授权返回的随机数
	 * @param timestamp
	 *            授权返回的时间戳
	 * @return
	 */
	public static boolean validateOpenid(String openid, String signature,
			String nonce, String timestamp) {

		if (StringUtils.isBlank(openid)) {
			return false;
		}

		String key = Configuration.getValue("wechat.paztcf.secret.key", "");		
		System.out.println("wechat.paztcf.secret.key--------" + key );
		String signatureTemp = getSHA1(openid, timestamp, nonce, key);		
		if (StringUtils.isBlank(signature)) {
			signature = "";
		}

		return signature.equalsIgnoreCase(signatureTemp);

	}

	/**
	 * 校验openid的合法性, 如果openid合法,则返回openid,否则返回null
	 * 
	 * @param request
	 * @return
	 */
	public static String validateOpenid(HttpServletRequest request) {
		HttpSession session = request.getSession();
		String openid = (String) session.getAttribute("openid");

		if (StringUtils.isNotBlank(openid)) {
			return openid;
		}

		openid = request.getParameter("openid"); // 个人微信号
		String signature = request.getParameter("signature"); // 签名串
		String nonce = request.getParameter("nonce"); // 随机数
		String timestamp = request.getParameter("timestamp"); // 时间戳

		if (validateOpenid(openid, signature, nonce, timestamp)) {
			session.setAttribute("openid", openid);
			return openid;
		}

		return null;
	}

	/**
	 * 校验fid 与 sfid是否配对
	 * 
	 * @param fid
	 *            分享人的openid
	 * @param sfid
	 *            分享人的加密后的openid
	 * @return
	 */
	public static boolean isLegalOpenId(String fid, String sfid) {
		if (StringUtils.isBlank(fid) || StringUtils.isBlank(sfid)) {
			return false;
		}

		String signature = secretOpenid(fid);

		return sfid.equalsIgnoreCase(signature);
	}

	/**
	 * 对openid进行加密
	 * 
	 * @param openid
	 * @return
	 */
	public static String secretOpenid(String openid) {

		String key = Configuration.getValue("wechat.paztcf.secret.key", "");

		return getSHA1(openid, "100", "100", key);
	}

	/**
	 * 微信环境不精准检测
	 * 
	 * @param userAgent
	 * @return
	 */
	public static boolean isComeFromWechat(String userAgent) {
		userAgent = userAgent.toLowerCase();

		return userAgent.contains("micromessenger");
	}

	/**
	 * 微信环境不精准检测
	 * 
	 * @param userAgent
	 * @return
	 */
	public static boolean isComeFromWechat(HttpServletRequest request) {
		String userAgent = request.getHeader("User-Agent").toLowerCase();
		;

		return userAgent.contains("micromessenger");
	}

	/**
	 * 是否来自qq浏览器
	 * 
	 * @param request
	 * @return
	 */
	public static boolean isComeFromQQ(HttpServletRequest request) {
		String userAgent = request.getHeader("User-Agent").toLowerCase();
		;

		return userAgent.contains("qq");
	}

	/**
	 * 获取微信授权的url地址
	 * 
	 * @param backUrl
	 * @return
	 */
	public static String getAuthorizeUrl(String backUrl) {
		// 授权相关
		String appid = Configuration.getValue("ucp.life.appid"); // 公众账号appId
		String weappNo = Configuration.getValue("ucp.life.weappNo"); // 公众账号
		String redirectServer = Configuration.getValue("ucp.ztkf.redirect.url"); // ucp回调服务器
		String authorizeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?"
				+ "appid=%s&redirect_uri=%s&"
				+ "response_type=code&scope=snsapi_base&state=sig#wechat_redirect"; // 微信授权的地址

		try {
			backUrl = URLEncoder.encode(backUrl, "utf-8"); // 对backUrl做编码
		} catch (Exception e) {
			e.printStackTrace();
		}

		String redirectUri = String.format("%s?weappNo=%s&backUrl=%s",
				redirectServer, weappNo, backUrl); // ucp回调调转地址
		try {
			redirectUri = URLEncoder.encode(redirectUri, "utf-8"); // 对redirectUri做编码
		} catch (Exception e) {
			// nothing todo.
		}

		return String.format(authorizeUrl, appid, redirectUri);
	}


	public static void main(String[] args) throws Exception {
		// 生成二维码
		String url = "http://www.pingan.com/pa18shoplife/mobile/product/warminglife/quote.jsp?WT.mc_id=mobi07-pab-s102-ewm&eid=normal&appColumn=2A7010AC328C32F8E054002128BFD47A";
		String src = generateQRCode(url,200,"1");
		System.out.println(url.length());
		String html = "<img src=\"" + src + "\">";
		FileOutputStream ops = new FileOutputStream("D:\\QRCodeImage\\cecece.html");
		org.apache.commons.io.IOUtils.write(html, ops, "utf-8");
		ops.close();
	}

}

 

转载于:https://my.oschina.net/u/198077/blog/1595493

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值