做网站着用什么软件最好的网站开发
- 作者: 五速梦信息网
- 时间: 2026年04月18日 09:53
当前位置: 首页 > news >正文
做网站着用什么软件,最好的网站开发,提升网站建设品质价位,免费建站免费推广的网站先上效果图 项目源码#xff1a;https://download.csdn.net/download/qq_43055855⁄89891285 源码地址
手机扫描二维码跳转到指定网页 概述
这个项目是一个基于 Java 的二维码生成与解析工具#xff0c;主要由 QRCodeUtil 和 QRCodeController 两个类组成。它利用了 Google…先上效果图 项目源码https://download.csdn.net/download/qq_43055855⁄89891285 源码地址
手机扫描二维码跳转到指定网页 概述
这个项目是一个基于 Java 的二维码生成与解析工具主要由 QRCodeUtil 和 QRCodeController 两个类组成。它利用了 Google ZXing 库来实现二维码的生成和解析功能并通过 Spring 框架进行整合提供了 RESTful API 接口用于生成带有 logo 的二维码。
主要功能
生成带有 logo 的二维码
用户可以传入二维码内容和 logo 文件路径或字节数组生成带有指定 logo 的二维码图像。通过设置编码提示类型包括字符集、错误纠正级别和边距等确保二维码的可读性和容错性。计算 logo 在二维码中的合适大小并将其居中绘制在二维码图像上使生成的二维码更加美观和具有辨识度。保存二维码到文件或输出流可以将生成的二维码保存到指定的文件目录中若目录不存在则自动创建。如果未指定文件名则随机生成一个以当前时间戳命名的 png 格式文件。也可以将二维码生成到输出流中并以 Base64 编码的形式返回给客户端方便在网页等环境中直接使用。解析二维码内容提供了两种方式解析二维码内容分别是解析本地二维码图片文件和解析网络二维码图片地址。通过将图像转换为亮度源再创建二进制位图最后使用解码提示类型进行解码获取二维码中的文本内容。RESTful API 接口QRCodeController 类提供了一个 POST 请求的接口 /qrCode接受二维码内容和可选的 logo 文件上传。根据上传的 logo 文件情况生成带有或不带 logo 的二维码并将其写入 HttpServletResponse 的输出流中返回给客户端。
新建maven项目构建springboot 技术要点
Google ZXing 库的使用
熟练掌握了 Google ZXing 库中各种类的使用如 MultiFormatWriter 用于生成二维码的位矩阵BitMatrix表示二维码的位数据BufferedImageLuminanceSource 和 HybridBinarizer用于二维码的解析等。图像处理利用 Java 的 BufferedImage 和 Graphics2D 类进行图像处理包括调整 logo 图像的大小、在二维码图像上绘制 logo 等操作。文件操作和输入输出流使用 ImageIO 进行图像文件的读取和写入操作以及处理文件的存在性检查、目录创建等。同时熟练运用 OutputStream 和 ByteArrayOutputStream 等输入输出流进行数据的传输和处理。Spring 框架整合 通过 RestController 和 Slf4j 等注解将该工具整合到 Spring 框架中方便进行日志记录和提供 RESTful API 服务。 参数校验和错误处理 在接口方法中对传入的参数进行校验如检查二维码内容是否为空、上传的文件是否为有效的图片文件等。同时对可能出现的异常进行了捕获和处理记录错误日志并返回合适的响应。
pom.xml文件代码
!– 定义这是一个springboot项目 –parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.1.18.RELEASE/version/parent!– 定义这是一个web应用 –dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-devtools/artifactId/dependency!– zxing生成二维码 –dependencygroupIdcom.google.zxing/groupIdartifactIdcore/artifactIdversion3.3.3/version/dependencydependencygroupIdcom.google.zxing/groupIdartifactIdjavase/artifactIdversion3.3.3/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-thymeleaf/artifactId/dependency/dependencies我们需要lombock插件thymeleaf魔板引擎还有两个核心二维码库 zing的core和javase
在templates下定义yml文件映射
spring:thymeleaf:prefix: classpath:/templates/在静态资源文件resources下的templates里边新建一个html文件注意需自己建文件夹
!DOCTYPE html
!– 声明文档类型 –
html langen
!– HTML文档头部 –
head!– 设置字符集为UTF-8 –meta charsetUTF-8!– 页面标题 –title二维码生成器/title!– 内联样式 –style typetext/css/* 设置文本区域的字体大小、宽度和高度 /textarea {font-size: 30px;width: 400px;height: 200px;}/ 设置提示信息的样式包括颜色和默认不显示 /.hint {color: red;display: none;}/ 设置二维码容器的样式包括居中、最小高度等 /.qrCodeContainer {display: flex;justify-content: center;align-items: center;width: 100%;min-height: 100vh;position: relative;border: 2px solid sandybrown;padding: 20px;box-sizing: border-box;}/style!– 引入jQuery库 –script srchttps://cdn.bootcss.com/jquery/2.1.1/jquery.min.js/script!– JavaScript代码 –script typetext/javascript// 当DOM准备就绪时执行\((function () {// 当按钮被点击时触发\)(button).click(function () {// 获取文本区域的值var codeContent \((textarea).val();// 获取文件输入框的DOM元素var logoInput \)(#logoInput)[0];// 获取用户选择的文件var logoFile logoInput.files[0];// 检查二维码内容是否为空if (codeContent.trim() ) {// 显示提示信息\((.hint).text(二维码内容不能为空).fadeIn(500);} else {// 清除提示信息\)(.hint).text().fadeOut(500);// 创建FormData对象存储数据var formData new FormData();// 添加二维码内容到表单数据formData.append(codeContent, codeContent);// 如果用户选择了logo文件则将其添加到表单数据if (logoFile) {formData.append(logoFile, logoFile);}// 发送AJAX请求\(.ajax({// 请求URLurl: /qrCode,// 请求类型type: POST,// 请求数据data: formData,// 不对数据进行序列化处理processData: false,// 不设置content-type头contentType: false,// 成功回调success: function (data) {// 检查返回的数据是否符合base64图片格式if (/^data:image\/png;base64,[A-Za-z0-9/]{42,}{0,2}\)/.test(data)) {console.log(Received valid base64 data:, data);// 获取画布元素var canvas document.getElementById(qrCanvas);// 获取画布上下文var ctx canvas.getContext(2d);// 创建图片对象var img new Image();// 图片加载完成时绘制到画布img.onload function () {canvas.width img.width;canvas.height img.height;ctx.drawImage(img, 0, 0);// document.body.appendChild(canvas); // 可选操作将画布添加到body};// 设置图片源为返回的base64数据img.src data;} else {console.error(Invalid base64 data received:, data);}},// 错误回调error: function (error) {console.error(error);}});}});});/script
/head
!– HTML文档主体 –
body
!– 输入框用户在此输入要生成二维码的内容 –
textarea placeholder请输入要生成二维码内容网址…/textareabr
!– 文件输入框用户可以选择logo图片 –
input typefile idlogoInputbr
!– 按钮用户点击生成二维码 –
button点击我生成二维码/button
!– 提示信息 –
span classhint/span
!– 二维码容器包含画布用于显示生成的二维码 –
div classqrCodeContainercanvas idqrCanvas/canvas
/div
/body
/html这个html文件主要是前端页面的展示包括样式的设置向后端发送ajax请求数据调用接口成功回调后的数据渲染。 核心代码 // 发送AJAX请求\(.ajax({// 请求URLurl: /qrCode,// 请求类型type: POST,// 请求数据data: formData,// 不对数据进行序列化处理processData: false,// 不设置content-type头contentType: false,// 成功回调success: function (data) {// 检查返回的数据是否符合base64图片格式if (/^data:image\/png;base64,[A-Za-z0-9/]{42,}{0,2}\)/.test(data)) {console.log(Received valid base64 data:, data);// 获取画布元素var canvas document.getElementById(qrCanvas);// 获取画布上下文var ctx canvas.getContext(2d);// 创建图片对象var img new Image();// 图片加载完成时绘制到画布img.onload function () {canvas.width img.width;canvas.height img.height;ctx.drawImage(img, 0, 0);// document.body.appendChild(canvas); // 可选操作将画布添加到body};// 设置图片源为返回的base64数据img.src data;} else {console.error(Invalid base64 data received:, data);}},// 错误回调error: function (error) {console.error(error);}});在控制层中Controller调用静态资源文件下的html在这里插入代码片
/** 处理HTTP GET请求当访问/index路径时触发。** return 返回字符串cs.html表示转发到名为cs.html的视图。/RequestMapping(/index) // 映射请求路径为/indexpublic String index(){ // 方法名返回一个字符串return cs.html; // 返回值指示转发到名为cs.html的视图}
新建二维码工具类QRCodeUtil
定义二维码的基本尺寸和参数
// 定义二维码的基本尺寸和颜色private static final int CODE_WIDTH 500; // 二维码宽度单位像素。private static final int CODE_HEIGHT 500; // 二维码高度单位像素。private static final int FRONT_COLOR 0x000000; // 二维码前景色0x000000 表示黑色。private static final int BACKGROUND_COLOR 0xFFFFFF; // 二维码背景色0xFFFFFF 表示白色。新建一个BufferedImage类型的方法用于存储图像
private static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {BufferedImage resizedImage new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);// 创建一个新的 BufferedImage 对象用于存储调整大小后的图像设置宽度、高度和类型TYPE_INT_RGB表示 24 位 RGB 颜色。Graphics2D g resizedImage.createGraphics();// 在新的 BufferedImage 对象上创建一个 Graphics2D 对象用于绘制调整后的图像。g.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);// 在新的 BufferedImage 对象上绘制原始图像指定目标宽度和高度使其调整大小。g.dispose();// 释放 Graphics2D 对象占用的资源。return resizedImage;// 返回调整大小后的 BufferedImage 对象。}接着就是创建二维码并保存文件 /** 创建二维码并保存到文件。** param codeContent 二维码内容* param codeImgFileSaveDir 二维码图片保存的目录* param fileName 二维码图片文件名称/public static void createCodeToFile(String codeContent, File codeImgFileSaveDir, String fileName, String logoPath) {try {if (codeContent null || .equals(codeContent)) {log.info(二维码内容为空不进行操作…);return;}codeContent codeContent.trim();// 如果二维码内容为空记录日志并返回不进行后续操作。否则去除二维码内容两端的空白字符。if (codeImgFileSaveDir null || codeImgFileSaveDir.isFile()) {codeImgFileSaveDir FileSystemView.getFileSystemView().getHomeDirectory();log.info(二维码图片存在目录为空默认放在桌面…);}// 如果二维码图片保存目录为空或为文件而不是目录将保存目录设置为桌面目录并记录日志。if (!codeImgFileSaveDir.exists()) {codeImgFileSaveDir.mkdirs();log.info(二维码图片存在目录不存在开始创建…);}// 如果保存目录不存在创建该目录并记录日志。if (fileName null || .equals(fileName)) {fileName System.currentTimeMillis() .png;log.info(二维码图片文件名为空随机生成 png 格式图片…);}// 如果二维码图片文件名为空使用当前时间戳作为文件名并设置为 png 格式记录日志。// 使用新方法生成带有 logo 的二维码图像BufferedImage bufferedImage getBufferedImageWithLogo(codeContent, logoPath);File codeImgFile new File(codeImgFileSaveDir, fileName);// 创建一个 File 对象表示二维码图片文件使用保存目录和文件名。ImageIO.write(bufferedImage, png, codeImgFile);// 使用 ImageIO 将带有 logo 的二维码图像写入文件指定文件格式为 png。log.info(二维码图片生成成功 codeImgFile.getPath());// 记录日志打印二维码图片生成成功的消息和文件路径。} catch (Exception e) {e.printStackTrace();// 如果在生成二维码图片过程中发生异常打印异常堆栈信息。}}创建二维码输出流的方法
public static void createCodeToOutputStream(String codeContent, OutputStream outputStream, byte[] logoBytes) {try {if (codeContent null || .equals(codeContent.trim())) {log.info(二维码内容为空不进行操作…);return;}codeContent codeContent.trim();// 如果二维码内容为空记录日志并返回不进行后续操作。否则去除二维码内容两端的空白字符。BufferedImage bufferedImage getBufferedImageWithLogo(codeContent, logoBytes);try (ByteArrayOutputStream baos new ByteArrayOutputStream()) {ImageIO.write(bufferedImage, png, baos);// 将带有 logo 的二维码图像写入 ByteArrayOutputStream指定文件格式为 png。byte[] imageBytes baos.toByteArray();// 获取 ByteArrayOutputStream 中的字节数组表示二维码图像数据。String base64Image Base64.getEncoder().encodeToString(imageBytes);// 使用 Base64 编码器将二维码图像数据编码为字符串。outputStream.write((data:image/png;base64, base64Image).getBytes());// 将包含 Base64 编码的二维码图像数据写入输出流格式为data:image/png;base64,加上编码后的字符串。log.info(二维码图片生成到输出流成功…);// 记录日志打印二维码图片生成到输出流成功的消息。} catch (IOException e) {log.error(输出流写入错误: {}, e.getMessage());// 如果在写入输出流过程中发生 IOException记录错误日志打印错误消息。}} catch (Exception e) {e.printStackTrace();log.error(发生错误: {}!, e.getMessage());// 如果在生成二维码图片过程中发生其他异常打印异常堆栈信息并记录错误日志打印错误消息。}}这是图像的尺寸
/**** param originalImage // 原始图像 param targetWidth 目标宽度* param targetHeight 目标高度* return/private static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {BufferedImage resizedImage new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);// 创建一个新的 BufferedImage 对象用于存储调整大小后的图像设置宽度、高度和类型TYPE_INT_RGB表示 24 位 RGB 颜色。Graphics2D g resizedImage.createGraphics();// 在新的 BufferedImage 对象上创建一个 Graphics2D 对象用于绘制调整后的图像。g.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);// 在新的 BufferedImage 对象上绘制原始图像指定目标宽度和高度使其调整大小。g.dispose();// 释放 Graphics2D 对象占用的资源。return resizedImage;// 返回调整大小后的 BufferedImage 对象。}
获取图片logo public static BufferedImage getBufferedImageWithLogo(String codeContent, byte[] logoBytes) {try {log.info(生成带有 logo 的二维码内容{}logo 字节数组长度{}, codeContent, logoBytes! null? logoBytes.length : 0);// 记录日志表明正在生成带有 logo 的二维码并打印二维码内容和 logo 字节数组的长度如果不为 null。// 设置编码提示类型MapEncodeHintType, Object hints new HashMap();// 创建一个 HashMap 来存储编码提示类型和对应的值。hints.put(EncodeHintType.CHARACTER_SET, UTF-8);// 设置编码字符集为 UTF-8确保二维码中的文本可以正确编码和解码。hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);// 设置二维码的错误纠正级别为 M中等提高二维码的容错能力。hints.put(EncodeHintType.MARGIN, 1);// 设置二维码的边距为 1控制二维码周围的空白区域大小。// 创建多格式写入器实例MultiFormatWriter multiFormatWriter new MultiFormatWriter();// 创建一个 MultiFormatWriter 对象用于生成不同格式的条形码和二维码。// 生成二维码的 BitMatrixBitMatrix bitMatrix multiFormatWriter.encode(codeContent, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, hints);// 使用 MultiFormatWriter 的 encode 方法生成二维码的位矩阵传入二维码内容、格式QR_CODE、宽度、高度和编码提示类型。// 创建二维码图像BufferedImage bufferedImage new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR);// 创建一个 BufferedImage 对象用于存储二维码图像设置图像的宽度、高度和类型TYPE_INT_BGR表示 24 位 RGB 颜色。// 根据 BitMatrix 填充图像for (int x 0; x CODE_WIDTH; x) {for (int y 0; y CODE_HEIGHT; y) {bufferedImage.setRGB(x, y, bitMatrix.get(x, y)? FRONT_COLOR : BACKGROUND_COLOR);}}// 遍历二维码的位矩阵根据位矩阵中的值设置图像的像素颜色将前景色黑色或背景色白色设置到 BufferedImage 中。// 添加 logoif (logoBytes! null logoBytes.length 0) {log.info(添加 logo字节数组长度{}, logoBytes.length);// 如果 logo 字节数组不为 null 且长度大于 0记录日志并打印 logo 字节数组的长度。BufferedImage logoImage ImageIO.read(new ByteArrayInputStream(logoBytes));// 使用 ImageIO 从字节数组输入流中读取 logo 图像创建一个 BufferedImage 对象表示 logo 图像。int logoWidth bufferedImage.getWidth() / 4;int logoHeight bufferedImage.getHeight() / 4;// 计算 logo 图像在二维码中的大小这里将 logo 的宽度和高度设置为二维码宽度和高度的四分之一。BufferedImage resizedLogoImage resizeImage(logoImage, logoWidth, logoHeight);// 调用 resizeImage 方法将 logo 图像调整为计算出的大小得到调整后的 BufferedImage 对象。Graphics2D g bufferedImage.createGraphics();// 在二维码图像上创建一个 Graphics2D 对象用于绘制 logo。int x (bufferedImage.getWidth() - logoWidth) / 2;int y (bufferedImage.getHeight() - logoHeight) / 2;// 计算 logo 在二维码图像中的位置使其居中显示。g.drawImage(resizedLogoImage, x, y, null);// 在二维码图像上绘制调整后的 logo 图像指定位置为计算出的坐标。g.dispose();// 释放 Graphics2D 对象占用的资源。}return bufferedImage;// 返回带有 logo 的二维码图像。} catch (WriterException | IOException e) {e.printStackTrace();log.error(生成带有 logo 的二维码时发生错误{}, e.getMessage());// 如果在生成二维码过程中发生异常打印异常堆栈信息并记录错误日志打印错误消息。// 可以根据需要返回一个默认的图像或者抛出一个自定义异常return null;// 在发生错误时返回 null表示生成二维码失败。}}获取二维码上面的logo内容 /**** param codeContent 二维码的内容 param logoPath logo的路径* return/public static BufferedImage getBufferedImageWithLogo(String codeContent, String logoPath) {try {log.info(生成带有 logo 的二维码内容{}logo 路径{}, codeContent, logoPath);// 记录日志表明正在生成带有 logo 的二维码并打印二维码内容和 logo 路径。// 设置编码提示类型MapEncodeHintType, Object hints new HashMap();// 创建一个 HashMap 来存储编码提示类型和对应的值。hints.put(EncodeHintType.CHARACTER_SET, UTF-8);// 设置编码字符集为 UTF-8确保二维码中的文本可以正确编码和解码。hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);// 设置二维码的错误纠正级别为 M中等提高二维码的容错能力。hints.put(EncodeHintType.MARGIN, 1);// 设置二维码的边距为 1控制二维码周围的空白区域大小。// 创建多格式写入器实例MultiFormatWriter multiFormatWriter new MultiFormatWriter();// 创建一个 MultiFormatWriter 对象用于生成不同格式的条形码和二维码。// 生成二维码的 BitMatrixBitMatrix bitMatrix multiFormatWriter.encode(codeContent, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, hints);// 使用 MultiFormatWriter 的 encode 方法生成二维码的位矩阵传入二维码内容、格式QR_CODE、宽度、高度和编码提示类型。// 创建二维码图像BufferedImage bufferedImage new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR);// 创建一个 BufferedImage 对象用于存储二维码图像设置图像的宽度、高度和类型TYPE_INT_BGR表示 24 位 RGB 颜色。// 根据 BitMatrix 填充图像for (int x 0; x CODE_WIDTH; x) {for (int y 0; y CODE_HEIGHT; y) {bufferedImage.setRGB(x, y, bitMatrix.get(x, y)? FRONT_COLOR : BACKGROUND_COLOR);}}// 遍历二维码的位矩阵根据位矩阵中的值设置图像的像素颜色将前景色黑色或背景色白色设置到 BufferedImage 中。// 添加 logoif (logoPath! null !.equals(logoPath)) {log.info(添加 logo路径{}, logoPath);// 如果 logo 路径不为空且不为空字符串记录日志并打印 logo 路径。BufferedImage logoImage ImageIO.read(new File(logoPath));// 使用 ImageIO 读取 logo 图像文件创建一个 BufferedImage 对象表示 logo 图像。int logoWidth bufferedImage.getWidth() / 5;int logoHeight bufferedImage.getHeight() / 5;// 计算 logo 图像在二维码中的大小这里将 logo 的宽度和高度设置为二维码宽度和高度的五分之一。BufferedImage resizedLogoImage resizeImage(logoImage, logoWidth, logoHeight);// 调用 resizeImage 方法将 logo 图像调整为计算出的大小得到调整后的 BufferedImage 对象。Graphics2D g bufferedImage.createGraphics();// 在二维码图像上创建一个 Graphics2D 对象用于绘制 logo。int x (bufferedImage.getWidth() - logoWidth) / 2;int y (bufferedImage.getHeight() - logoHeight) / 2;// 计算 logo 在二维码图像中的位置使其居中显示。g.drawImage(resizedLogoImage, x, y, null);// 在二维码图像上绘制调整后的 logo 图像指定位置为计算出的坐标。g.dispose();// 释放 Graphics2D 对象占用的资源。}return bufferedImage;// 返回带有 logo 的二维码图像。} catch (WriterException | IOException e) {e.printStackTrace();log.error(生成带有 logo 的二维码时发生错误{}, e.getMessage());// 如果在生成二维码过程中发生异常打印异常堆栈信息并记录错误日志打印错误消息。// 可以根据需要返回一个默认的图像或者抛出一个自定义异常return null;// 在发生错误时返回 null表示生成二维码失败。}}解析网络二维码图片内容和本地二维码图片内容 /** 解析本地二维码图片内容。** param file 本地二维码图片文件* return 二维码内容* throws Exception 如果解析失败/public static String parseQRCodeByFile(File file) {String resultStr null;// 初始化结果字符串为 null表示如果解析失败将返回 null。if (file null || file.isDirectory() ||!file.exists()) { // 检查文件是否有效return resultStr;}// 如果文件为空、是目录或不存在直接返回 null表示无法解析。try {// 读取本地图片文件BufferedImage bufferedImage ImageIO.read(file);// 使用 ImageIO 读取本地二维码图片文件创建一个 BufferedImage 对象表示图片。// 将 BufferedImage 转换为 LuminanceSourceBufferedImageLuminanceSource source new BufferedImageLuminanceSource(bufferedImage);// 创建一个 BufferedImageLuminanceSource 对象将读取的 BufferedImage 转换为亮度源用于二维码解析。// 创建二进制位图BinaryBitmap bitmap new BinaryBitmap(new HybridBinarizer(source));// 创建一个 BinaryBitmap 对象使用 HybridBinarizer 对亮度源进行二值化处理得到二进制位图用于二维码解析。// 设置解码提示类型Hashtable hints new Hashtable();// 创建一个 Hashtable 来存储解码提示类型和对应的值。hints.put(DecodeHintType.CHARACTER_SET, UTF-8);// 设置解码字符集为 UTF-8确保二维码中的文本可以正确解码。// 解码二维码Result result new MultiFormatReader().decode(bitmap, hints);// 使用 MultiFormatReader 对二进制位图进行解码传入解码提示类型得到 Result 对象表示解码结果。resultStr result.getText();// 从解码结果中获取二维码的文本内容并赋值给 resultStr。} catch (IOException e) {e.printStackTrace();} catch (NotFoundException e) {e.printStackTrace();log.error(图片非二维码图片, 路径是: {}!, file.getPath());// 如果找不到二维码或者图片不是二维码打印错误堆栈信息并记录错误日志打印图片路径。}return resultStr;// 返回解析得到的二维码内容如果解析失败返回 null。}/** 解析网络二维码图片内容。** param url 二维码图片网络地址* return 二维码内容* throws Exception 如果解析失败/public static String parseQRCodeByUrl(URL url) {String resultStr null;// 初始化结果字符串为 null表示如果解析失败将返回 null。if (url null) { // 检查 URL 是否有效return resultStr;}// 如果 URL 为空直接返回 null表示无法解析。try {// 读取网络图片文件BufferedImage bufferedImage ImageIO.read(url);// 使用 ImageIO 读取网络二维码图片文件创建一个 BufferedImage 对象表示图片。// 将 BufferedImage 转换为 LuminanceSourceBufferedImageLuminanceSource source new BufferedImageLuminanceSource(bufferedImage);// 创建一个 BufferedImageLuminanceSource 对象将读取的 BufferedImage 转换为亮度源用于二维码解析。// 创建二进制位图BinaryBitmap bitmap new BinaryBitmap(new HybridBinarizer(source));// 创建一个 BinaryBitmap 对象使用 HybridBinarizer 对亮度源进行二值化处理得到二进制位图用于二维码解析。// 设置解码提示类型Hashtable hints new Hashtable();// 创建一个 Hashtable 来存储解码提示类型和对应的值。hints.put(DecodeHintType.CHARACTER_SET, UTF-8);// 设置解码字符集为 UTF-8确保二维码中的文本可以正确解码。// 解码二维码Result result new MultiFormatReader().decode(bitmap, hints);// 使用 MultiFormatReader 对二进制位图进行解码传入解码提示类型得到 Result 对象表示解码结果。resultStr result.getText();// 从解码结果中获取二维码的文本内容并赋值给 resultStr。} catch (IOException e) {e.printStackTrace();log.error(二维码图片地址错误, 地址是: {}!, url);// 如果读取网络图片时发生 IOException打印错误堆栈信息并记录错误日志打印图片地址。} catch (NotFoundException e) {e.printStackTrace();log.error(图片非二维码图片, 地址是: {}!, url);// 如果找不到二维码或者图片不是二维码打印错误堆栈信息并记录错误日志打印图片地址。}return resultStr;// 返回解析得到的二维码内容如果解析失败返回 null。}前端调用控制层接口代码
package com.huae.MainApplication.controller;import com.huae.MainApplication.controller.QRCodeUtil;
// 导入本项目中 QRCodeUtil 工具类。import lombok.extern.slf4j.Slf4j;
// 使用 Lombok 生成日志对象。import org.springframework.http.MediaType;
// 导入 Spring 中的 MediaType用于指定请求的媒体类型。import org.springframework.web.bind.annotation.PostMapping;
// 导入 Spring 的注解用于定义 POST 请求的处理方法。import org.springframework.web.bind.annotation.RequestParam;
// 导入 Spring 的注解用于从请求中获取参数。import org.springframework.web.bind.annotation.RestController;
// 导入 Spring 的注解标记该类为 RESTful Web 服务控制器。import org.springframework.web.multipart.MultipartFile;
// 导入 Spring 的类用于处理文件上传。import javax.imageio.ImageIO;
// 导入 Java 的图像输入输出工具类。import javax.servlet.http.HttpServletResponse;
// 导入 Servlet 的响应对象。import java.awt.image.BufferedImage;
// 导入 Java 的缓冲图像类。import java.io.File;
// 导入 Java 的文件类。import java.io.IOException;
// 导入 Java 的输入输出异常类。import java.io.OutputStream;
// 导入 Java 的输出流类。import static com.huae.MainApplication.controller.QRCodeUtil.getBufferedImageWithLogo;
// 导入静态方法用于生成带有 logo 的二维码图像。RestController
Slf4j
public class QRCodeController {PostMapping(value qrCode, consumes MediaType.MULTIPART_FORM_DATA_VALUE)// 定义一个 POST 请求的处理方法请求路径为qrCode接受的请求内容类型为 multipart/form-data。public void createQRCodeWithLogo(RequestParam(codeContent) String codeContent,// 从请求中获取名为codeContent的参数类型为字符串。RequestParam(value logoFile, required false) MultipartFile logoFile,// 从请求中获取名为logoFile的参数类型为 MultipartFile表示上传的文件该参数可选。HttpServletResponse response) {try {if (codeContent null || .equals(codeContent.trim())) {log.info(二维码内容为空不进行操作…);// 如果二维码内容为空记录日志并返回不进行后续操作。return;}codeContent codeContent.trim();// 如果二维码内容不为空去除两端的空白字符。OutputStream outputStream response.getOutputStream();// 获取 HttpServletResponse 的输出流用于向客户端发送数据。if (logoFile ! null) {// 如果上传的文件不为空。// 检查上传的文件是否是有效的图片文件if (!isValidImageFile(logoFile)) {log.error(上传的文件不是有效的图片文件);// 如果文件不是有效的图片文件记录错误日志并返回。return;}// 直接将 logo 文件的内容读取到内存中而不是保存到临时文件byte[] logoBytes logoFile.getBytes();// 将上传的文件内容读取为字节数组。QRCodeUtil.createCodeToOutputStream(codeContent, outputStream, logoBytes);// 调用 QRCodeUtil 的 createCodeToOutputStream 方法生成带有 logo 的二维码并写入输出流。BufferedImage bufferedImage getBufferedImageWithLogo(codeContent, logoBytes);// 使用静态导入的方法生成带有 logo 的二维码图像。ImageIO.write(bufferedImage, png, new File(C:\temp\debug_qr.png));// 将生成的二维码图像写入指定的文件用于调试。} else {QRCodeUtil.createCodeToOutputStream(codeContent, outputStream, null);// 如果没有上传 logo 文件调用 QRCodeUtil 的 createCodeToOutputStream 方法生成不带 logo 的二维码并写入输出流。}log.info(成功生成二维码!);// 记录日志表示成功生成二维码。} catch (IOException e) {log.error(发生错误 错误信息是{}, e.getMessage());// 如果在处理过程中发生 IOException记录错误日志并打印错误消息。}}private boolean isValidImageFile(MultipartFile file) {try {// 检查文件扩展名是否为常见的图片扩展名String fileName file.getOriginalFilename();// 获取上传文件的原始文件名。if (fileName ! null (fileName.endsWith(.png) || fileName.endsWith(.jpg) || fileName.endsWith(.jpeg))) {// 如果文件名不为空且扩展名是.png、.jpg 或.jpeg。// 尝试读取文件内容作为图像BufferedImage image ImageIO.read(file.getInputStream());// 使用 ImageIO 从文件的输入流中读取图像。return image ! null;// 如果成功读取到图像返回 true表示文件是有效的图片文件。}return false;// 如果文件名不满足条件或读取图像失败返回 false表示文件不是有效的图片文件。} catch (IOException e) {return false;// 如果在读取文件过程中发生 IOException返回 false表示文件不是有效的图片文件。}}}最后controller层主页面代码
package com.huae.MainApplication.controller;import org.springframework.stereotype.Controller; // 导入Spring的Controller注解用于标记这是一个控制器类
import org.springframework.web.bind.annotation.RequestMapping; // 导入Spring的RequestMapping注解用于映射请求URL
import org.springframework.web.bind.annotation.ResponseBody; // 导入Spring的ResponseBody注解用于直接返回对象到视图层/** 控制器类处理HTTP请求。/
Controller // 标记此类为Spring MVC控制器
public class HelloController {/** 处理HTTP GET请求当访问/hello路径时触发。** return 返回字符串/index表示重定向到/index路径。/ResponseBody // 标记此方法返回的内容将直接作为HTTP响应体返回给客户端RequestMapping(/hello) // 映射请求路径为/hellopublic String hello(){ // 方法名返回一个字符串return /index; // 返回值指示重定向到/index路径}/** 处理HTTP GET请求当访问/index路径时触发。** return 返回字符串cs.html表示转发到名为cs.html的视图。*/RequestMapping(/index) // 映射请求路径为/indexpublic String index(){ // 方法名返回一个字符串return cs.html; // 返回值指示转发到名为cs.html的视图}}总结 深入了解了二维码的生成和解析原理以及如何通过代码实现这些功能。 掌握了图像处理的基本方法包括调整图像大小、绘制图像等操作。 学会了如何使用输入输出流进行数据的传输和处理以及如何将生成的二维码以不同的方式返回给客户端。 熟悉了 Spring框架的基本使用包括如何定义 RESTful API 接口、处理参数和响应等。 提高了代码的错误处理和参数校验能力确保程序的稳定性和可靠性。 总之这个二维码项目是一个很好的学习示例涵盖了多个方面的技术要点可以帮助大家深入理解和掌握 Java 编程中的各种技术。
- 上一篇: 做网站找我图片自己怎么制作企业网站
- 下一篇: 做网站挣钱么wordpress ftp存储
相关文章
-
做网站找我图片自己怎么制作企业网站
做网站找我图片自己怎么制作企业网站
- 技术栈
- 2026年04月18日
-
做网站找投资人免备案网站建站
做网站找投资人免备案网站建站
- 技术栈
- 2026年04月18日
-
做网站找哪个软件仙居住房和城乡建设部网站
做网站找哪个软件仙居住房和城乡建设部网站
- 技术栈
- 2026年04月18日
-
做网站挣钱么wordpress ftp存储
做网站挣钱么wordpress ftp存储
- 技术栈
- 2026年04月18日
-
做网站之前要先购买服务器吗平面设计月薪大概多少
做网站之前要先购买服务器吗平面设计月薪大概多少
- 技术栈
- 2026年04月18日
-
做网站知名公司wordpress 中文 插件下载
做网站知名公司wordpress 中文 插件下载
- 技术栈
- 2026年04月18日

