java实现手机扫描二维码后网站跳转新页面,提供zxing和hutools的方式实现二维码的生成,动态刷新,验证跳转功能。
1.效果图:
二维码设置有效时间
失效重新获取二维码
手机扫描二维码成功后网站跳转新页面
2.后端代码:
/*** @description 二维码控制器*/
@Controller
public class QrcodeController {@Autowiredprivate RedisUtils redisUtils;/*** @description 二维码页面* @return java.lang.String**/@GetMapping({"/","/index"})public String index(ModelMap modelMap){modelMap.put("userId", 1);return "index";}/*** @description 生成二维码* @param request* @Param response* @return void**/@GetMapping("/getQrcode")@ResponseBodypublic void getQrcode(HttpServletRequest request, HttpServletResponse response) throws Exception {//二维码中的链接,需要公网网址才可以用手机扫描出来,本地测试开通natapp进行内网渗透String url = "http://qh22wg.natappfree.cc/scanQrcode";//过期时间,30slong expireTime = 30;//设置参数String random = request.getParameter("random");String userId = request.getParameter("userId");//生成二维码唯一标识String key = String.valueOf(System.currentTimeMillis());//设置二维码过期时间redisUtils.set(key,random,expireTime);//二维码中的内容String content = url + "?key=" + key + "&userId=" + userId;//二维码图片中间logoString imgPath = null;Boolean needCompress = true;//拿到图片流ByteArrayOutputStream out = QRCodeUtil.encodeIO(content, imgPath, needCompress);//返回二维码response.setCharacterEncoding("UTF-8");response.setContentType("image/jpeg;charset=UTF-8");response.setContentLength(out.size());ServletOutputStream outputStream = response.getOutputStream();outputStream.write(out.toByteArray());outputStream.flush();outputStream.close();}/*** @description 扫描二维码* @param request* @Param key* @Param userId* @return java.lang.String**/@GetMapping("/scanQrcode")@ResponseBodypublic String scanQrcode(HttpServletRequest request, String key, String userId) throws Exception {if(redisUtils.exists(key)){redisUtils.set(userId + "_qrcode_status", "success");return "扫描成功";}return "二维码失效, 请重新扫描";}/*** @description 验证扫描二维码* @param userId**/@RequestMapping("/confirmQrcode")@ResponseBodypublic AjaxResult confirmQrcode(String userId){if(redisUtils.exists(userId + "_qrcode_status")){redisUtils.remove(userId + "_qrcode_status");//扫描成功后跳转新链接return AjaxResult.success("扫描成功", "/success");}return AjaxResult.error("二维码失效, 请重新扫描");}/*** @description 扫描二维码成功跳转页面* @param* @return java.lang.String**/@GetMapping("/success")public String success(ModelMap modelMap){return "success";}}
zxing生成二维码工具:
public class QRCodeUtil {private static final String CHARSET = "utf-8";private static final String FORMAT_NAME = "JPG";// 二维码尺寸private static final int QRCODE_SIZE = 300;// LOGO宽度private static final int WIDTH = 60;// LOGO高度private static final int HEIGHT = 60;private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception {Hashtable hints = new Hashtable();hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);hints.put(EncodeHintType.CHARACTER_SET, CHARSET);hints.put(EncodeHintType.MARGIN, 1);BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,hints);int width = bitMatrix.getWidth();int height = bitMatrix.getHeight();BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);}}if (imgPath == null || "".equals(imgPath)) {return image;}// 插入图片QRCodeUtil.insertImage(image, imgPath, needCompress);return image;}private static void insertImage(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) { // 压缩LOGOif (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;}// 插入LOGOGraphics2D 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();}public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);mkdirs(destPath);ImageIO.write(image, FORMAT_NAME, new File(destPath));}public static BufferedImage encode(String content, String imgPath, boolean needCompress) throws Exception {BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);return image;}public static void mkdirs(String destPath) {File file = new File(destPath);// 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)if (!file.exists() && !file.isDirectory()) {file.mkdirs();}}public static void encode(String content, String imgPath, String destPath) throws Exception {QRCodeUtil.encode(content, imgPath, destPath, false);}public static byte[] getQRCodeImage(String content) throws WriterException, IOException {QRCodeWriter qrCodeWriter = new QRCodeWriter();BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE);ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream();MatrixToImageWriter.writeToStream(bitMatrix, FORMAT_NAME, pngOutputStream);byte[] pngData = pngOutputStream.toByteArray();return pngData;}public static void encode(String content, String destPath) throws Exception {QRCodeUtil.encode(content, null, destPath, false);}public static void encode(String content, String imgPath, OutputStream output, boolean needCompress)throws Exception {BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);ImageIO.write(image, FORMAT_NAME, output);}public static void encode(String content, OutputStream output) throws Exception {QRCodeUtil.encode(content, null, output, false);}public static String decode(File file) throws Exception {BufferedImage image;image = ImageIO.read(file);if (image == null) {return null;}BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));Result result;Hashtable hints = new Hashtable();hints.put(DecodeHintType.CHARACTER_SET, CHARSET);result = new MultiFormatReader().decode(bitmap, hints);String resultStr = result.getText();return resultStr;}public static String decode(String path) throws Exception {return QRCodeUtil.decode(new File(path));}//获取生成二维码的图片流public static ByteArrayOutputStream encodeIO(String content,String imgPath,Boolean needCompress) throws Exception {BufferedImage image = QRCodeUtil.createImage(content, imgPath,needCompress);//创建储存图片二进制流的输出流ByteArrayOutputStream baos = new ByteArrayOutputStream();//将二进制数据写入ByteArrayOutputStreamImageIO.write(image, "jpg", baos);return baos;}
}
3.demo下载:https://download.csdn.net/download/weixin_39220472/33632560