暂时未有相关云产品技术能力~
本文讲解了如何在SpringBoot项目中整合EasyExcel,实现Excel快捷导入导出,解析Excel导入导出的实现过程,提供了相关源码。一、什么是 EasyExcelEasyExcel 是一款基于Java的开源Excel操作工具,它提供了简单且强大的 API,使开发人员可以轻松地读写、操作和生成Excel文件。EasyExcel 支持 Excel 文件的导入和导出,可以处理大量数据,具有高性能和低内存占用。它可以读取 Excel 文件中的数据,并将数据转换为 Java 对象,也可以将Java对象写入Excel文件。EasyExcel 还提供了丰富的格式化选项和功能,如设置单元格样式、合并单元格、设置公式等。同时,EasyExcel 还支持多线程操作,可以在处理大量数据时提高处理效率。由于其简单易用的特点,EasyExcel 被广泛应用于数据导入导出、报表生成、数据分析等领域。说明链接项目地址https://github.com/alibaba/easyexcel源码链接https://www.yuque.com/easyexcel/doc/easyexcel二、EasyExcel常用注解EasyExcel 提供了一些常用的注解,用于在Excel读写过程中标识和控制字段的行为。以下是EasyExcel的常用注解:@ExcelProperty:用于标识Excel中的字段,可以指定字段在Excel中的列索引或列名。例如:@ExcelProperty("姓名"),@ExcelProperty(index = 0)。@ExcelIgnore:用于标识不需要导入或导出的字段。@ExcelIgnoreUnannotated:用于标识未被 @ExcelProperty 注解标识的字段是否被忽略。@ExcelHead:用于标识 Excel 表头的样式。可以设置表头的高度、字体样式、背景颜色等。@ExcelColumnWidth:用于设置 Excel 列的宽度。@ExcelDateTimeFormat:用于设置日期时间字段的格式化规则。@ExcelBooleanFormat:用于设置布尔类型字段在 Excel 中的显示文本。@ExcelNumberFormat:用于设置数字字段的格式化规则。这些注解可以根据实际需求进行组合使用,以便在 Excel 读写过程中更灵活地控制字段的行为和样式。三、整合 EasyExcel3.1 引入依赖要引入 EasyExcel 依赖,你需要在你的项目的 pom.xml 文件中添加以下依赖项:<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.3.0</version> </dependency>这将引入 EasyExcel 的最新版本(当前为 2.3.0)。请同学们确保 Maven 配置正确,并且能够从 Maven 仓库下载依赖项。完成后,Maven 将自动下载并管理 EasyExcel 依赖项,如下图所示。3.2 实体类定义当使用 EasyExcel 时,实体类需要按照以下规则进行定义。实体类需要添加 @ExcelIgnoreUnannotated 注解,以确保未被 @ExcelProperty 注解标记的字段被忽略。使用 @ExcelProperty 注解标记需要在 Excel 中读写的字段,可以指定字段在 Excel 中的列索引或列名。可以使用其他注解(如 @ExcelDateTimeFormat、@ExcelNumberFormat 等)来进一步定义字段的格式化规则。下面是一个示例代码,展示了一个使用 EasyExcel 读写 Excel 文件的实体类定义:@ExcelIgnoreUnannotated public class Student { @ExcelProperty(index = 0) // 列索引为0 private String name; @ExcelProperty(index = 1) // 列索引为1 private int age; @ExcelProperty(index = 2) // 列索引为2 private String gender; @ExcelProperty(index = 3) // 列索引为3 private Date birthday; // Getters and Setters // ... }在上述代码中,Student 类定义了4个字段,分别对应 Excel 文件中的4列。通过使用 @ExcelProperty 注解并指定列索引,我们告诉EasyExcel 需要将这些字段映射到相应的列。请注意,这只是一个示例,你可以根据自己的需求定义更多的字段和注解来满足 Excel 读写的需求。3.3 自定义转换器在 EasyExcel 中,可以通过实现 Converter 接口来定义自定义转换器。Converter 接口有两个泛型参数,分别表示读取时的类型和写入时的类型。下面是一个简单的示例,展示了如何实现 Converter 接口来定义一个将 Boolean 类型转换为 字符串 的转换器。public class BooleanToStringConverter implements Converter<Boolean, String> { @Override public String convertToExcelData(Boolean value) { return value ? "是" : "否"; } @Override public Boolean convertToJavaData(String value) { return "是".equals(value); } }在上述示例中,BooleanToStringConverter 实现了 Converter 接口,并实现了 convertToExcelData() 和 convertToJavaData() 方法。convertToExcelData() 方法将 Boolean 类型的值转换为 字符串,convertToJavaData() 方法将字符串转换为 Boolean 类型的值。要在读取或写入 Excel 时使用该转换器,可以通过 @ExcelConverter 注解将转换器与相应的字段关联起来,代码如下。@ExcelProperty(index = 0) @ExcelConverter(BooleanToStringConverter.class) private Boolean married;在上述代码中,通过 @ExcelConverter 注解指定了 BooleanToStringConverter 作为该字段的转换器,EasyExcel 在读取或写入 Excel 时将使用该转换器进行数据转换。通过实现 Converter 接口,你可以定义各种自定义转换器,以满足不同类型的数据转换需求。3.4 编写导出 Excel 接口EasyExcel 是一个 Java 的开源库,它支持导出 Excel 文件,通过EasyExcel,同学们可以方便地将Java对象的数据导出到Excel文件中。EasyExcel 提供了丰富的 API,可以配置导出的 Excel 的样式、格式以及数据内容,非常灵活易用,同学们可以使用 EasyExcel 导出各种类型的数据,包括基本类型、集合、自定义对象等,同时,EasyExcel 还支持大数据量的导出,可以有效地处理大批量数据的导出操作。总之,EasyExcel 是一个功能强大且易于使用的导出Excel的工具。下面是一个示例代码,展示了如何使用 EasyExcel 导出Excel的接口,请同学们参考学习。import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.metadata.WriteSheet; import java.util.ArrayList; import java.util.List; public class ExcelExportService { public void exportExcel(String filePath) { // 准备数据 List<Student> studentList = prepareData(); // 创建ExcelWriter对象 ExcelWriter excelWriter = EasyExcel.write(filePath, Student.class).build(); // 创建WriteSheet对象 WriteSheet writeSheet = EasyExcel.writerSheet("学生信息").build(); // 将数据写入Excel excelWriter.write(studentList, writeSheet); // 关闭ExcelWriter对象 excelWriter.finish(); } private List<Student> prepareData() { // 创建测试数据 List<Student> studentList = new ArrayList<>(); studentList.add(new Student("张三", 18, "男")); studentList.add(new Student("李四", 20, "女")); studentList.add(new Student("王五", 19, "男")); return studentList; } public static void main(String[] args) { ExcelExportService excelExportService = new ExcelExportService(); excelExportService.exportExcel("student.xlsx"); } }在上述代码中,ExcelExportService 类封装了导出Excel的接口。在 exportExcel 方法中,首先准备数据,然后创建 ExcelWriter 对象,该对象用于写入 Excel 文件。接下来创建 WriteSheet 对象,用于指定写入的 Sheet 名称。最后,通过 excelWriter.write 方法将数据写入 Excel,并通过 excelWriter.finish 方法完成写入操作。在 prepareData 方法中,创建了一个包含学生信息的测试数据列表。在 main 方法中,创建了 ExcelExportService 对象,并调用 exportExcel 方法导出Excel文件。导出的 Excel 文件名为 student.xlsx。同学们可以根据实际需求,修改数据和文件路径,以实现自己的导出功能。3.5 编写导入 Excel 接口EasyExcel 支持导入 Excel 文件。通过 EasyExcel,你可以方便地将 Excel 文件中的数据读取到 Java 对象中。EasyExcel 提供了丰富的 API ,可以配置读取 Excel 的方式、读取的 Sheet、读取的行数等。你可以使用 EasyExcel 读取各种类型的数据,包括基本类型、集合、自定义对象等。同时,EasyExcel 还支持大数据量的导入,可以高效地处理大批量数据的导入操作。EasyExcel 还提供了监听器的机制,同学们可以通过监听器来对读取到的数据进行处理和验证。总之,EasyExcel 是一个功能强大且易于使用的导入 Excel 的工具。下面是一个示例代码,展示了如何使用 EasyExcel 导入Excel的接口。import com.alibaba.excel.EasyExcel; import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.read.metadata.ReadSheet; import java.util.List; public class ExcelImportService { public void importExcel(String filePath) { // 创建Excel读取监听器 ReadListener<Student> listener = new ExcelReadListener(); // 创建读取Sheet配置 ReadSheet readSheet = EasyExcel.readSheet(0).registerReadListener(listener).build(); // 执行读取操作 EasyExcel.read(filePath, Student.class).build().read(readSheet); // 获取读取的数据 List<Student> studentList = ((ExcelReadListener) listener).getStudentList(); // 处理读取的数据 processImportedData(studentList); } private void processImportedData(List<Student> studentList) { // 处理导入的数据 } public static void main(String[] args) { ExcelImportService excelImportService = new ExcelImportService(); excelImportService.importExcel("student.xlsx"); } }在上述代码中,ExcelImportService 类封装了导入 Excel 的接口。在 importExcel 方法中,首先创建 Excel 读取监听器 ExcelReadListener,用于处理读取到的数据。然后创建读取 Sheet 配置 ReadSheet,并通过 registerReadListener 方法将监听器注册到读取配置中。接下来,使用 EasyExcel 进行读取操作,将读取到的数据交给监听器进行处理。最后,通过 `processImportedData 方法处理导入的数据。在 main 方法中,创建了 ExcelImportService 对象,并调用 importExcel 方法导入 Excel 文件。导入的 Excel 文件名为 student.xlsx。同学们可以根据实际需求,修改文件路径和处理数据的逻辑,以实现自己的导入功能。四、总结本文讲解了如何在SpringBoot项目中整合EasyExcel,实现Excel快捷导入导出,解析Excel导入导出的实现过程,提供了相关源码。
一、为什么要进行日志输出1.1 什么是日志输出Java的日志输出是指在程序运行时,通过记录一系列信息来了解程序的执行情况和状态,并将这些信息输出到控制台或者文件中等目的地。Java提供了很多种日志输出框架,比如JDK自带的java.util.logging、Log4j、Logback、Slf4j等第三方框架。这些框架提供了丰富的功能和配置选项,可以实现不同级别的日志输出、不同格式的日志消息、输出到不同的目的地(控制台、文件、数据库等),以及日志滚动、异步输出等特性。在Java应用程序的开发和运维中,日志输出是非常重要的一环,它可以帮助我们快速定位问题,监控系统运行状况,分析业务数据,优化程序性能等。1.2 为什么要进行日志输出MyBatisPlus配置日志输出可以帮助我们更好地了解应用程序在运行时的行为,包括数据库操作语句、查询结果、异常信息等。通过查看日志输出,我们可以快速定位问题并进行调试,提高开发效率和程序稳定性。此外,对于一些关键业务场景,比如数据修改等,日志记录也可以作为审计或者安全监控的依据,确保数据的完整性和安全性。二、MyBatisPlus可以配置哪几类日志?2.1 Log4j2Log4j2 是Apache基金会的一个开源项目,具有高性能、多线程安全、可扩展等特点。Log4j2是Apache基金会的一个开源日志框架,是Log4j框架的升级版。与Log4j相比,Log4j2具有更好的性能和可靠性,并支持异步日志、自动配置等新特性。Log4j2提供了丰富的日志输出选项,可以将日志信息输出到控制台、文件、数据库等目的地,同时支持不同格式的日志消息,灵活配置各种日志属性。可以说,Log4j2是Java应用程序中最流行、最成熟的日志框架之一,广泛应用于各种场景中,包括Web应用、大数据分析、企业应用等。在使用Log4j2时,只需要引入相应的依赖,配置对应的配置文件即可开始记录日志。在使用 Log4j2 作为 MybatisPlus 的日志框架时,需要在 pom.xml 中引入 log4j2 的依赖,代码如下。<!-- pom.xml --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>${log4j2.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>${log4j2.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>${log4j2.version}</version> </dependency>然后在 log4j2 的配置文件中,配置输出级别、输出格式以及输出目的地等,代码如下。<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } [%t] - %c.%M(%L)%n%m%n"/> </Console> </Appenders> <Loggers> <Root level="debug"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>上述配置将日志输出到控制台,并按照指定的格式进行输出。2.2 LogbackLogback是一个开源的日志框架,是log4j框架的继承者,也是目前广泛使用的Java日志框架之一。Logback 提供了良好的性能和灵活的配置选项,它支持多种日志输出格式、日志级别、日志滚动等特性,并且能够与不同的日志门面框架(如Slf4j)进行整合,方便地适应不同的项目需求。在Logback中,最基本的组成部分是Logger、Appender和Layout。Logger用于记录日志消息,Appender用于将日志消息输出到指定的目的地,Layout用于定义日志消息的输出格式。除此之外,Logback还提供了过滤器、异步输出等高级特性,可以进一步优化日志输出的效率和可靠性。使用 Logback 作为 MybatisPlus 的日志框架时,需要在 pom.xml 中引入 logback 的依赖,代码如下。<!-- pom.xml --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> </dependency>然后在 logback 的配置文件中,配置输出级别、输出格式以及输出目的地等,代码如下。<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } [%t] - %c.%M(%L)%n%m%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="STDOUT"/> </root> </configuration>上述配置将日志输出到控制台,并按照指定的格式进行输出。2.3 Slf4jSlf4j 是一个简单的日志门面框架,可以与不同的日志实现进行整合。Slf4j是一个简单的、通用的日志门面框架,旨在解决Java应用中使用不同日志框架导致的兼容性问题。Slf4j只定义了一组接口和规范,并未实现具体的日志功能,而是通过与底层日志实现框架进行适配,实现与各种日志框架的整合。Slf4j提供了丰富的日志级别、格式等配置选项,同时也支持MDC等高级功能,可以帮助开发人员快速、灵活地记录和管理日志信息。相对于直接使用Log4j或者其他日志框架,使用Slf4j的优势在于可以轻松地切换不同日志框架,并且避免引入多个日志框架导致的冲突和兼容性问题。使用 Slf4j 作为 MybatisPlus 的日志框架时,需要在 pom.xml 中引入 slf4j 的依赖,代码如下。<!-- pom.xml --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency>然后在配置文件中,指定要使用的日志实现,代码如下。<!-- pom.xml --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>${log4j2.version}</version> </dependency>三、什么场景下需要打印日志在Spring Boot项目中,打印日志是非常重要的。下面列举了一些场景下需要打印日志。输出 a = 1 测试结果 b = -2调试程序:打印日志可以帮助开发人员快速定位问题,查看代码的执行情况,找到出错的原因。监控系统状态:通过打印日志来监控系统的运行状况,包括系统负载、请求处理时间等指标,及时发现问题并进行调整。安全审计:打印日志可以记录敏感操作,比如用户登录、数据修改等,作为安全审计的依据,确保数据的完整性和安全性。性能分析:通过打印不同级别的日志信息,可以了解应用程序的性能表现,包括响应时间、数据库查询时间等,从而优化程序并提高性能。业务分析:通过打印日志,可以对业务流程进行分析和统计,了解用户行为等信息,为业务决策提供依据。总之,在任何需要跟踪程序运行状态或者进行问题排查的场景中,打印日志都是必要的。但是注意,过多、过于详细的日志输出会给系统性能带来影响,所以需要根据实际需要进行设置。
前言电脑之间的远程控制很多人都知道,用windows自带的微软远程桌面搭配内网穿透工具就可以实现,但有时候也会遇到在下班路上需要紧急处理工作,但是身边有没有电脑的情况。遇到这种情况,其实我们可以通过手机去远程控制公司的电脑,完美解决身边没有电脑的紧急情况。windows端之间的远程控制可以用系统自带的微软远程桌面,手机端其实也可以,只需要安装相应的微软远程桌面 app。然后在被控端电脑上通过 cpolar 内网穿透来映射远程桌面 3389 端口,手机上就可以使用所生成的公网 TCP 端口地址,实现在外随时随地远程控制电脑。下面简单几步实现手机远程控制 windows 电脑。1. 被控端电脑启用远程桌面在被控端电脑上,点击开始菜单栏,打开设置——系统,如下图所示。找到远程桌面,如下图所示。启用远程桌面,如下图所示。2. 安装cpolar内网穿透2.1 注册cpolar账号进入 cpolar 官网,点击右上角的免费注册,使用邮箱免费注册一个 cpolar 账号并登录,如下图所示。2.2 下载cpolar客户端登录成功后,点击下载 cpolar 到本地并安装(一路默认安装即可),如下图所示。cpolar 安装成功后会默认安装两个样例隧道(可自行修改或删减):remoteDesktop:指向本地3389端口,tcp协议website:指向本地8080端口,http协议本次我们可以直接使用 remoteDesktop 远程桌面隧道。3. 获取远程桌面公网地址3.1 登录cpolar web ui管理界面在浏览器上访问127.0.0.1:9200,使用所注册的 cpolar 邮箱账号登录 cpolar web ui 管理界面(默认为本地9200端口),如下图所示。3.2 启动远程桌面隧道登录成功进入主界面后,我们点击左侧仪表盘的隧道管理——隧道列表,找到远程桌面隧道,可以看到隧道状态正常为active,表示为正常在线状态,如下图所示。3.3 获取远程桌面公网随机临时地址我们点击左侧仪表盘的状态——在线隧道列表,可以看到远程桌面隧道已经有生成了相应的公网地址+公网端口号,我们将公网TCP端口地址复制下来(注意tcp://无需复制),如下图所示。3.4 使用手机远程测试手机下载安装微软远程桌面,可以在百度搜索微软远程桌面app下载,或者在这个链接下载https://m.clinicmed.net/appxz/26192.html,如下图所示。下载完成后打开,点击右上角添加,然后点击桌面,如下图所示。然后点击手动添加,如下图所示。输入上面的公网地址,同理,其他软件连接方式,PC名称填写公网地址即可,如下图所示。
摘要电子邮件在我们日常生活中有着广泛的应用,在注册各类网站时,通常需要发送验证码作为身份验证,邮箱验证和短信验证一样,也是身份验证的一种重要方式。电子邮件的出现可以方便我们的正常收发邮件,但由于垃圾邮件过多,严重影响了人们使用电子邮件的使用体验,人们需要花费更多的时间去过滤没有用的邮件,同时也浪费了网络邮件的电子资源。为了妥善垃圾邮件的问题,所以需要开发一套不良邮件过滤系统,基于一定过滤规则和用户自定义的黑名单、白名单,对即将接收的邮件进行自动化过滤,净化现有的邮件环境。本文详细讲解不良邮件过滤系统的开发,本系统基于贝叶斯算法过滤垃圾邮件,在贝叶斯算法实验表明运用该算法获得了较好的邮件过滤正确率。关键词:邮件过滤;贝叶斯算法;电子邮件;垃圾邮件前言近年来我国的社会发展非常快,软件IT极速也在不断发展之中。互联网的不断发展,网络信息也在不断增多,当然也包括了良好信息和不良信息。在数据量不断变大的背景之下,传统人工过滤的方式不再适用于垃圾过滤工作,所以需要开发一套软件系统帮助人们过滤垃圾信息。对于电子邮件来说也是一样,如果单单靠人工去做垃圾邮件过滤,那是不行的,我们必须要有一套不良邮件过滤管理系统,来帮助我们进行自动化的邮件过滤。为了防止垃圾邮件的不断入侵,人们想出了很多方案,比如设置IP入站规则,对在黑名单的IP地址加以过滤,这样可以对已知的黑客进行防御,但这样对其他应用程序有误伤,无法只对当前应用生效,所以没有被广泛使用。当然还有对邮件标题进行过滤,如果邮件标题有一些敏感词汇,邮件服务提供商会自动帮忙过滤,减少对收件人的干扰,这个方法是目前广泛使用的自动过滤方法。淡然现在还支持对MOQI长度进行限制,对于MOQI超过指定长度的邮件加以自动过滤,防止邮件服务被恶意攻击导致系统崩溃,节省电子邮件的系统资源,增加收发邮件的效率。垃圾邮件的存在消耗了使用人的大量时间,也消耗了我国互联网的带宽,所以必须要依法取缔。根据我国工信部发布的《中国互联网邮件发展情况报告》显示,每个网民平均每天会收到3.8封邮件,其中垃圾邮件2.6封,占了百分之70左右,所以垃圾邮件的存在已经大大影响了人民群众的生活。根据我国邮件协会发布的数据显示,我国网民数量已经超过五亿,每年会发送900亿封电子邮件,其中超过一半的邮件是垃圾邮件,我国已经是垃圾邮件的严重国家,所以开发不良邮件过滤系统非常有必要。在开发不良邮件过滤系统的过程中,我采用了Java和Vue技术框架,Java是一门基于服务端的开发语言,只需要在服务器上安装JDK,不管是什么操作系统都支持Java程序的运行和部署,兼容性非常好。另外Java支持对邮件进行收发操作,在垃圾邮件的内容、关键词、发件地址的过滤方便,可以较好地使用贝里斯算法,所以不良邮件过滤系统采用Java语言作为服务端的开发语言。在构建不良邮件过滤系统的前端界面时,我采用了Vue框架。Vue是一个基于JavaScript的框架,拥有了组件化的开发特点,可以降低开发的工作量,对于邮件页面的显示也非常的友好,所以不良邮件过滤系统采用Vue作为前端框架。不良邮件过滤系统的底层逻辑还是人工过滤的方式,即对邮件的标题、邮件内容文本、邮件附件进行关键词匹配和算法过滤,只是系统过滤的效率更高,成本更低。在收发邮件的技术方面,目前支持SMTP协议和IMAP协议进行收发邮件,这也是我在开发不良邮件过滤系统中所采用的的协议,另外还涉及到不同协议的不同服务和端口,会在本文中详细阐述。在不良邮件过滤系统中的附件扫描模块,可以采用第三方的扫描技术,如360、电脑管家等,可以调用第三方的服务,简化我们的开发量。这个系统主要使用基于关键词匹配的过滤方式,这个方法实现起来比较简单,只需要使用Java语言编写一个贝里斯算法即可,但在对付高级垃圾邮件时效果不是很好,高级垃圾邮件会进行一些伪装处理,绕过过滤规则进行发送,这也是后续要探讨的内容。本文将讲解使用Java语言开发一套完整的不良邮件过滤系统,帮助人们过滤垃圾邮件。1 绪论1.1 研究背景及意义1.1.1 研究背景目前,诸如邮箱用户、邮局服务提供者、网络服务提供者甚至电信服务的用户都受到随机邮件和病毒附件等问题的影响。传统的邮件过滤技术包括过滤客户、过滤服务器和防火墙。这些技术有以下缺陷:实时性能不佳,内容不过滤,准备战略不可靠。随着因特网日益受欢迎,电子邮件已成为最重要的因特网应用程序,因为其速度和成本较低。然而,一些人利用电子邮件获取巨额利润,导致垃圾邮件的泛滥,用户需要花费大量时间清理垃圾邮件,消耗了大量储存、计算和网络资源,影响了电子邮件用户的正常工作和学习。过滤垃圾邮件是世界各地普遍存在的问题,这篇文章分析当前的现行技术,并设计一个过滤器来识别和过滤随机邮件。首先,总结了目前的主要随机邮件方法,然后提出了处理随机邮件的不同角度的过滤方法,利用现有的技术,最大限度地提高效率和效力,同时利用现有的邮件过滤方案,通过数据提取分析用户的行为特点,并从功能角度起草规则来过滤电子邮件,然后提出了一些无法或无法与以前的方式处理的情况。基于 URL 为基础的过滤方法,即互通链接,在实验中,大部分未经确认的电子邮件分析在内容上是相同的,因此提供了与电子邮件相似的算法,比较实验表明,该过滤器不仅表现良好,而且还能够准确和检索应用结果。1.1.2 研究意义随着互联网技术的传播,电子邮件已成为人们生活的重要部分。传统信件和贺卡逐渐被电子邮件取代。由于其舒适、快捷和环境保护的优势,电子邮件为人们的生活提供了便利,越来越多的人从电子邮件获得商业和个人信息。然而,随机邮件的产生也给人们带来很多麻烦。大量垃圾邮件占用了存储空间,浪费了人们、能源和互联网交通费用。因此,邮件邮件过滤可以提供大量的社会资源,提高工作效率,减少个人损失和孤独,并创造一个良好的公共网络环境。互联网不仅为现代社会的普通人提供了舒适,而且在特定的应用领域提供了舒适。通过电子邮件交换信息也已成为人们分享信息的主要方式,随机邮件邮件给每个人的生活带来了重大问题,因此寻找随机邮件过滤系统至关重要。虽然目前有许多邮件过滤系统的程序,但这些清理结束系统一般适用于个人用户或当地单位,不包括特定的应用领域。这篇文章设计了邮件过滤系统,该系统既适用于普通人,也适用于某一应用领域的需要。1.1.3 垃圾邮件的危害互联网邮件系统是在合作环境中建立的,最初的设计者并不期望人们会以这种方式滥用该系统,SMTP 的设计是为了确保该系统中的任何人都能向其他人发送信息,一旦随机邮件发送者开始为每个人收集电子邮件地址,滥用的机会就会出现,随机邮件发送者从用户新闻集和邮名单中收集Big View的电子邮件地址,有时还会使用包括电子邮件在内的客户名单。有些收藏家甚至出售这些清单。没有找到办法消除垃圾邮件。目前,当地电子邮件账户超过 6500 万,邮件邮件的泛滥严重影响了电子邮件服务提供商和邮件用户的利益。垃圾邮件发送者利用邮件服务器或操作系统中的空白,向其他用户发送商业、政治或其他目的的电子邮件,并利用带有“隐藏功能”的垃圾邮件发送软件发送商业广告和具有政治目的的促销材料,其中一些信息可能逃避普通的过滤设备。他们与正常的通信共享有限的带宽,使人无法战胜。垃圾邮件的及时,标准的即时集中,在内容方面,没有特殊规则,没有积极和扩大的攻击,没有明显的特征,难以捕捉;可变表达形式和通信手段;过滤随机邮件的困难:目前,大多数邮件服务器无法从普通邮件中找到随机邮件。目前的过滤技术主要依赖于关键词语的过滤、影响不明确、反应速度缓慢以及计算数量庞大,发件人的地址和身份被伪造,难以追踪来源,无法禁止。1.1.4 病毒邮件的危害邮件病毒含有特定的标题和内容,模型可能以几种方式出现。虽然他们有复杂的感染机制,但研究他们的特征也可以帮助过滤病毒。例如:“Love Bug”病毒,标题是“Love YOU”,Flying D是一种通过邮件传播的蠕虫。在网络环境中,邮件病毒通过电子邮件传播,加上计算机病毒的常见特性,如可扩散性、可操作性、销毁性和可操作性,并具有一些新的功能,如快速感染、大规模传播、复杂和多样的扩散形式以及难以彻底消除。每次发生病毒时,大量主机、服务器和网络设备都会沉没并瘫痪。1.1.5 邮件过滤的重要性随着互联网的流行,电子邮件已成为人们日常沟通的工具。然而,许多“不受欢迎”的电子邮件也通过互联网发送,如销售广告、快速浓缩和黄色邮件,“不受欢迎”的电子邮件通常是指未经请求发送的电子邮件,或者可能是发送给与电文主题无关的新闻团体或名单服务器的同样电文的重复。目前,世界上“垃圾邮件”的比例从2001年的12%上升到51%,这一数字表明“垃圾邮件”的流量达到了令人担忧的程度。这些“垃圾邮件”邮件迅速填满电子邮件用户的邮箱:虽然因特网服务提供商的邮件服务器有很大的存储空间,但却降低了网络的运行效率,消耗了网络带宽,导致邮件服务器超负荷,从而降低了整个网络的运作效率;同时,它也阻碍了合法的电子邮件市场的运行。国际调查显示,“垃圾邮件”是因特网服务提供者面临的第二大问题。此外,由于随机邮件供应商可以从用户新闻集获得电子邮件地址,许多研究人员不愿意在公共论坛上发表文章。事实上,许多过滤程序是根据用户指定的过滤规则运作的,如收集“不需要的”电子邮件列表,手动过滤“不需要的”信息,例如删除从已知的“不需要的”电子邮件地址发送的电文,以及对含有某些单词或单词的电文进行分类。然而,这种过滤邮件的方法是人为的,而这些规则根据对关键词的比较而分类的方法有以下缺陷:要求用户拥有强大的专业知识和丰富的经验,并有足够的时间来制定这些清算规则,这一过程很繁琐。如果这是能力文件的正常表达形式,你只能做出肯定或否,思考缺乏灵活性。用于比较的关键词集太小,无法进行全面的邮件分析。不适应动态变化,因为随机邮件发送的内容、发件人地址等不断变化,用户必须经常调整这些规则,从而为用户带来更大的工作磁盘。可以注意到,电子邮件用户需要一个更有效的自动方式过滤邮件内容。因此,研究自动邮件过滤方法非常重要。1.1.6 邮件过滤的重要性候选人的最终目的是启动程序,明显的假设程序是不做任何事情或将其传递给目的地。在mta情况下,系指交付代理;MDA系指收到的邮件;对对来说,这意味着把信息保持原样,让用户决定如何处理它。另一个常见的程序是省略字母,在MTA意味着接收字母,而不是交出字母。另一方面,MDA和你被允许忽略消息。对于mta过滤器,忽略信件的最合适方法是拒绝它们。实现这一目标,可以使用基于结果的临时或永久响应代码。一些MDA过滤器也可以拒绝消息。因为MTA可以根据mda的退出状态报告交付失败。“候选人不能拒绝该信,因为该信已在收到,因为该信已由由过滤。MDA和MTA可将信件保存在另一文件夹中,这对用户在阅读前过滤信件很有用,MTA不能这样做,因为他们无法访问信件文件夹。通常可以使用的另一种程序是将电文发送给另一目的地,其中包括:重新发布电文,通过重写收件人在信封上的电文重新发出电文,或在新电文中重新发出电文,或对电文作出答复。一些过滤器能够更改字体,可以更改、删除或添加字段,并处理信件文本。这类程序的一个常见用途是通过添加字段向下列候选人传递信息。例如,MTA可以添加一个头田,然后由MDA过滤器或玛雅验证。调整头部场是安全和容易的,而不打破头部。更改正字符是另一个问题,从多余的字符中删除多余的字符部分,或在节点上添加缺失的符。但是,如果这些变化没有正确进行,很容易打破mime结构。MIME可以使用以下代表来执行清理结束程序。例如,每一层级的过滤器都能利用这一优势,例如,适合根据smtp信息进行清算的MTA过滤器,而候选人不能进行某些类型的测试,例如,并非所有候选人都能获得信封和收发人的信息,而只是一个只处理连接到一个邮箱的网站的候选人MDA,因为其通常不支持多邮箱的访问。在某些层次上,一些女性候选人可能遇到业绩问题,例如,在某些情况下,信息内容的过滤可能会严重影响mta过滤器的性能,通常在MDA或ya进行过滤。下面所列的MTA、MDA和MDA过滤器的潜在过滤程序指的是可以使用的过滤程序“P”表示,这一特定的过滤器和邮件代理组合将导致性能损失,其中过滤部分指的是对不同的最终用户使用不同的过滤规则。1.2 邮件过滤产品的国内外研究现状不需要的电子邮件是发件人未经收件人许可,在邮箱中向收件人发送一些不需要的信息。垃圾邮件的特点有以下几类:电子邮件头信息不完整,或隐藏所有电子邮件头信息;伪造发货人含有虚假指导信息的信息;用户不参与纯粹的广告,宣传图片内容和基层链接不健康。据中国因特网协会的反垃圾邮件中心提供的数据。2007年,来自中国互联网用户的垃圾邮件总数为694亿美元,而2006年为500亿美元,增加了38.8%。据估计,中国垃圾邮件造成的经济损失在2007年达到18.84亿美元,比2006年的10.4315亿美元增加了80.6%。为他们服务,对国家安全造成重大损害。随着因特网应用的扩大,越来越多的垃圾邮件也在增加,对社会和特定领域造成了巨大的。垃圾邮件的损害主要在以下方面:占用网络带宽,浪费网络资源,导致邮件服务器拥塞,降低整个网络的性能。当互联网充斥着垃圾邮件时,它将接管互联网。大量垃圾邮件也会占用服务器的内存。垃圾邮件还会损害互联网服务提供商的市场形象,扭曲互联网服务提供商的市场,导致无形资产的损失。浪费宝贵用户的时间和在线消费,并占用电子邮件空间。如果我们每天花时间在垃圾邮件上,它会降低我们的个人生产力。对于个人来说,这是浪费时间和网络流量。对整个社会来说,这是对社会资源的浪费,减少了人们创造的社会财富。对网络安全构成威胁。一些罪犯通过垃圾邮件传播谣言,扰乱社会秩序。尤其是这些妖魔鬼怪、诈骗钱财、传播色情信息等方面的垃圾邮件将严重危害社会。思想破坏了人们在特定领域的应用。国内外一些反革命分子利用垃圾邮件传播反革命言论,对反革命分子的思想稳定产生了消极影响。随着垃圾邮件的不断传播,反垃圾邮件技术也在不断发展。目前广泛使用的邮件过滤技术包括以下几个方面:基于主题和电子邮件文本的关键词过滤。通过阅读邮件的主题或内容,或包含多个关键字,评估邮件是否为垃圾邮件。这可以是特定的字符串或关键字匹配。正则表达式通常用于匹配关键字。这项技术简单易行。这种方法的优点是可以很好地过滤特定的消息,但缺点是需要定期更新关键字,维护起来很麻烦。黑白名单过滤。黑名单过滤包括首先检查发件人和服务器信息。这些信息包括黑名单上的反党和反人类元素。电子邮件是垃圾邮件。白名单过滤则相反。白名单的内容包含允许的内容,例如,发件人是该部门的指挥官和工作人员。如果发送方和服务器被添加到白名单,这是一条普通消息。否则就是垃圾邮件。黑名单的优点是,它可以快速从黑名单中过滤出已知用户,但缺点是缺少许多其他垃圾邮件。基于规则的过滤。根据消息的某些特征创建规则。当新消息到达时,根据这些规则。这项技术必须为阅读各类信息维护大量规则。该方法还使用了多种相同规则的过滤方法,其缺点是开发和维护规范非常麻烦。基于意图的检测和过滤。针对包含非法URL的电子邮件的通用意图检测过滤器。中文URL翻译是一个统一的资源定位器,也称为网址或web链接。这是一种在互联网上描述网址的符号方法。此检测方法用于检测URL指示的内容,以确定邮件是否为垃圾邮件。基于统计算法的滤波。在这种方法中,最常用的是统计方法贝叶斯分类原理。当以单词为特征时,训练大量以前在电子邮件中出现的这些特征的概率,并使用bayesa统计公式来计算概率。要对垃圾邮件进行分类,您应该将概率分类为后验概率。统计方法广泛应用于邮件过滤中,可以过滤大部分垃圾邮件,但需要对大量样本邮件进行训练,以引起注意并及时更新特征数据库。1.3 邮件过滤器的研究现状电子邮件过滤实际上是对成问题文本的一种分类,即将电子邮件分为“垃圾邮件”和法定电子邮件分为两类。近年来,出现了一些电子邮件过滤系统,利用学习机器自动获取知识并提高系统的效率。基于规则或电子邮件内容的电子邮件分类系统。基于方法的规则由知识和逻辑的机械基础组成。知识库储存从某一领域的专家那里获得的经验,一个有推断能力的推断引擎,即从知识中得出的结论,而不仅仅是寻找现成的答案。因为许多推理规则必须由知识的工程师手手写,发展成本非常昂贵。基于方法的内容,从取样监测到寻找规则(即使用一些自动确定的培训数据建造集),以及在未来使用这些样品。学习机器最重要的理论原理之一是统计数字。传统的普查是一项关于样本数量的近似理论研究,这种研究往往是无限的。基于过滤技术的内容包括过滤实体的电子邮件和电子邮件头。有两种基于过滤技术的内容。一个是垃圾邮件,该邮件基于材料提取分析的优点,即过滤方法与过滤方法相同,通常是基于电子邮件过滤的关键词,包括一个关键词和多个关键词。包含灵活安排和方便调整的模式的效用。萨萨卡人在应用这种技术方面更成功。然而,这一方法有许多不足之处:首先,从本质上讲,它是二维判断,局限于空间,而且对知识缺乏信心,因为这些关键字往往出现在普通邮件邮件中。第二,用户必须确定自己的规则、用户的高质量要求和纯粹的分配手册,这些规则可能不完整;此外,中文的多重含义和同义词使得其固有的局限性。另一个是根据数据采矿技术过滤电子邮件,该技术可以使用文字和统计分类算法,不考虑语境。它在自我学习和高度精密调整方面发挥带头作用。其他研究包括:根据记忆信息发现垃圾邮件的方法,以及根据事件对信息优势的描述提取数据。由于相对简单的机制、实际环境中的良好表现以及研究的主要方向,大多数自动文本都采用了模式内容。1994年,特里·佩恩利用CN2和ibpl学习方法对电子邮件进行分类,研究了用户程序和用户反馈,以建立电子邮件过滤规则,从而建立了magi代理(电子邮件代理代理)电子邮件系统。maggie将学习过程中制定的电子邮件过滤规则保存在一份综合文件中,用户可以人工修改。1996年,蕾妮根据天真的贝兹算法建造了学习机器,应用了邮件分级系统。在创建“ile”系统过程中,renee指出,每个用户都有不同的信息集,电子邮件的组织方式也不同,因此用户可以手动调整错误错误的电子邮件。如果分类速度相对较快,不需要用户的大量干预,用户可以将不正确分类的电子邮件传送到不同类别,以重建培训组,利用天真的贝兹算法进行再培训,并不断改进分类的精确度,不断对这些邮件进行修改。然而,由于分类方面存在许多错误,用户仍然需要花费大量时间来确定分类是否存在错误。1998年,蕾妮通过收到用户提供的关键词来过滤电子邮件,每个电文都是以色列行动小组(以色列国防军)使用学习机器k-nearest(邻居)的样板,使用了一种分类算法信号和一种信息分类神经网络。实验结果表明,分类的准确度为94.8%的土壤和4.2%的邻居克-纳雷斯特,分类算法指95.7%和2.3%。在前往最符合电子邮件特征分类的三卷之前,使用用户手工保存的邮件获取典型的空间载体,向用户提供电子邮件分类的目标文件夹。因为mailcat在邮件上运送人。用户仍然需要花很多时间处理电子邮件。实验结果:时间分类为0.3秒,目标60- 80%文件夹的精确度为用户提供,目标80- 98%文件夹的精确度为用户提供。1.4 电子邮件的工作原理电子邮件是在20多年前出现的,这是第一个完全由文件传输协议组成的电子邮件系统,但不能创建和发送照片、传真和语音邮件。后来,根据简单而实用的rfc822,它被广泛使用。电子邮件系统由两个子系统组成:用户代理u(用户代理u)。代理信息(MTA)将消息从来源到目的地。用户代理是为与邮件系统互动提供命令线界面、列表或图表的当地程序。邮件代理在后面执行电子邮件服务。在从当地主机远程邮件发送或接收邮件时,用户必须提交信函、目的地地址等,通常以域名的形式提供目的地地址。分析员然后发送UDP包与国内域名系统服务器,寻找当地的名字通过域名系统找到ip地址返回p地址返回有关的语言表示。通过这种方式,环境署可与目标机构建立这方面的技术合作方案,并实现重要的沟通协议的最高标准。在邮件和通信中,如果目标是原始设备,则信息何时将直接发送给当地邮政信箱或当地的红大星。如果邮件是远程邮件,在收到呼叫请求后,应(通过电子邮件传输协议)通过与远距离主机的连接方式发送邮件,并负责接收当地用户。之后,红大卫之星负责发送电子邮件。红色大卫之星”这个程序使用一个识别文件,以确定文字表达的程度,该文字与检索到的信息是一致的。一旦过程以另一种方式进行。红大卫之星”也可以自动回复收到的电文,也可以在收到特定电文后操作。《邮局协议》现在是第三期,也就是《的3期,使用户能够从远程服务器上检索并读取信息,然后在服务器上删除这些信息,尽管它有助于在服务器上提供磁盘空间,但用户容易造成混乱7L。IMAP(因特网存取协议)提供了一个广泛的读取机制,可以生成、销毁和在服务器上保存许多邮箱。这样,虽然用户可以从多个地点进入信箱,但信息似乎没有被在不同的电脑上。从某种意义上讲,互联网是邮件系统是客户/服务器系统的分配,并具有服务器/服务器的特点。换句话说,客户通过与服务器对话发送和接收电子邮件,服务器与另一个服务器交谈。客户可以直接发送给将发送到收邮箱的服务器(MTA)或另一个MTA (MTA),后者将继续处理信件。该系统通过单一层次的服务安排具有高功率。每个服务器只需要在与服务器平等的基础上直接知道。使用电子邮件传输协议(或更新esmtp,延长电子邮件传输协议)向与MTA的对话发送信息。可将信件直接发送给收件人,或发送到当地哪些地方将继续发送。从本质上讲,互联网是不同步的,实时传送电文不可靠,如果由于时间的、网络堵塞或其他原因而无法立即送达收件人,就可能出错。但是,如果电文可以发送到永久连接,但始终可以发送到某一时刻(例如,用户网络上的邮件服务器或因特网服务供应商的邮件服务器),则可将该电文置于等待交付的等待名单上,并在承认失败之前作出多次尝试。当消息无法发送时,MTA可以发送电子邮件地址20我会通知用户失败。接收MTA信息的设备,接收并不意味着用户已读取该信息,只是在该信息已发送到用户信箱后。电子邮件传输协议的一个重要内容是通知发件人已收到电文,但通知未交付。MTA本身实际上不发送消息。他们愿意发送更多的信息,就像向另一个网络。MTA在发送信息的最后一台物理机器上收到外部程序。这是由MDA完成的。MDA用于给用户邮箱写信,也将信件交给其他MTA,并将信件交给其他邮件系统。通常有一个MTA(直接交付给邮箱的另一个用户)和根据技术合作方案进行的其他交付。许多MTA也是用于处理电子邮件系统的红色大卫之星。国内递送可能不会导致,而是将信件转到另一个装置。在这一点上,机器作为服务器接收信息,然后作为客户向另一个目的地发送信息。在这个过程中,信件被放置在等待发送的列表中,这使得这个过程更加可靠,如果没有排队,系统故障将使丢失的信件变得更可靠。如果电文发给没有当地系统账户的用户,则该电文将继续传递到另一个MTA。在这种情况下,收件人的地址在确定目标领域方面分析,因特网域名系统被用来查找目的地。红色大卫之星,处理正确的送货机制。1.5 邮件通讯协议研究现状在因特网上,电子邮件是通过建立25号港口与目的地之间的技术合作方案发送的。收听该港口是使用电子邮件传输协议(简单邮件传输协议)的电子邮件程序。这个程序接受即将到来的通信并将信件复制到合适的邮箱。如果电文不能交付,包含未交付电文第一部分的错误报告将退还发件人。电子邮件传输协议是一个简单的协议。与端口25联系后,发送机器(客户)等待机器(服务器)开始。服务器开始发送单行文字。确定他是否准备接受电子邮件。如果你没有准备好,客户放弃联系,稍后再试。如果服务器想获得电子邮件,客户说电子邮件来自哪里和去哪里。如果目的地有这样的收件人,通知客户继续发送消息。然后将消息发送给接收它的服务器。一般来说,不是测试,因为这方面的技术合作方案提供了可靠的字节字节。如果有更多的电子邮件,你也可以在此发送。当所有电子邮件在双向交换时,通信将被编辑。OPO协议使得生物重要的工作站能够存取目前正在为第三版开发的信息,即称为《第3版》。色情资讯3允许工作站在邮件服务器上检索信息。以赛亚3传递数据信息,可能是指示或答案。在按电子邮件程序的集器键时,电子邮件程序首先将域名域名分析协议的域名分析协议给p服务器,在分析因特网协议地址时,电子邮件程序将开始向110个邮件服务器使用技术合作协议。当成功的电子邮件程序连接到bob服务器时,将使用所使用的命令将邮箱帐户发送给bob服务器,在完成认证工作后,使用电子邮件程序将服务器发送邮箱帐户,该程序使用的是六位数命令,要求服务器返回邮箱,统计数据,例如邮件总数和信件数量,然后列出将列出服务器上的邮件数量。retr将接收电子邮件,在收到包裹后,使用驱动器到电子邮件服务器的删除到删除国家。在使用速度时,邮件服务器删除指定删除标记的信件。流行病学目前支持电子邮件处理。具体程序是:向服务器发送电子邮件;拨打电子邮件客户以连接服务器;下载所有未读电子邮件。这种情况与存取无关,是存储和前端,将邮件从邮件服务器传送到个人终端设备,通常是在电脑或mac上。一旦消息发送到您的电脑或麦克,信件将在邮件服务器上删除。以赛亚书3并不支持扩展到服务器上的信息。通过电子邮件发送和接收内部电子邮件并将其发送给服务器。服务器将以用户名、密码和p地址为基础,以确保用户发送的邮件是该服务器的合法用户。如果批准通过,信件将被列入等待名单。邮件服务器通过查看收件人地址获得访问,然后通过当地邮件服务器系统查询邮件服务器地址。如果收件人是收件人,则域名系统,方法是退回该领域的邮件服务器地址。本地组件是通过电子邮件传输协议连接到邮件服务器的服务器。发送的电子邮件的大多数服务器还检查电子邮件服务器的可靠性,以确定发件人是否是该领域发件人的电子邮件服务器。核实电文通过后收到收到,或拒绝电文,视该电文是否是即时发件人的设置而定。它与文件兼容,可以在电子邮件中附上任何二元内容并将其发送至MTA传输文件。“二进制”可以指任何形式的任何数据。例如,一个可以保存的文件处理词——阿司匹林字符串,但其格式可能只被处理过的特定词所采纳。然而,它可以以未知的形式阅读文件,并像字节一样处理,该文件可以与文件加密,可以由发件人在不知道任何内容形式的情况下妥善处理。收到可以解密所附文件,显示其显示,或将其保存在磁盘上。一些图象、图片、vcard电子商务卡等)可以显示许多不同的文档格式,可以产生非常先进的视觉效果和图形界面。文件夹包括标准网络上的电子邮件,其中有特殊的头和文本格式。来文的案文由若干部分组成,每一节可使发言变得更安静。身体的每一部分或身体的每一部分,都以解释性电文,包括解密指令开始(3)。。1.6 本课题研究内容随着垃圾邮件的扩散和反垃圾邮件的斗争吸引了越来越多的关注,各种技术和各种系统的出现,而不论过滤程序如何,无论是服务器还是客户,无论其地址、内容、信件、过滤信封,这些技术在过滤垃圾邮件方面发挥了重要作用。以垃圾邮件过滤为基础的服务器和客户都有优势,但与垃圾邮件过滤为基础的服务器相比,可以更好地解决洪灾问题,因为等到垃圾邮件送达客户,造成资源浪费,甚至在更早清理垃圾邮件时的其他重大风险,可以最大限度地减少损失。这一专题进一步研究和分析,电子电子邮件。《反垃圾邮件协议》原则上将软件和过滤装置标准化,提出一套较高的效率、较低的价格和较强的解决办法,该系统也具有重要的理论意义和实际价值。本文以不良邮件过滤系统设计与实现为主题,开发一套不良邮件过滤系统。对当前国内外不良邮件过滤系统研究背景进行研究,对目前有关此类邮件过滤系统进行分析,然后通过分析得出研究本系统的现实意义。对系统所需要的相关技术进行阐述,对软件编程所需要的物理条件进行研究。分析本系统需要实现的功能模块,包括功能直接依赖的需求,和功能的安全性、可交互性等非完全依赖的需求。阐述系统的整体结构设计,主要从总体架构、功能设计和数据库层面入手。系统功能和界面功能展示。最后对该系统的设计与实现继续全面的总结,并提出该系统目前所存在的一些不足,并对该系统提出未来的展望。
4.4系统详细设计4.4.1 登陆注册模块的功能设计登陆注册模块需要包括用户登陆功能和用户注册功能,用户在登陆界面只需输入登陆账号、登陆密码,点击登陆按钮即可进入系统首页。若条件允许,登陆页面还要有跳转注册界面的超链接,注册需要额外输入手机号,完成注册后即可重新登陆系统。通过注册确定不同用户的权限,不同权限的用户登录后系统会执行不同的功能。未注册用户就只能进行公开调查问卷的在线答题。注册的用户除了有以上功能以外还可以查看调查问卷的调查结果,如图4-3所示。4.4.2 调查问卷查询模块的功能设计调查问卷查询模块用于查询发布者发布的问卷信息。当发布者在系统中发布了自定义问卷之后,数据将自动存档到调查问卷模块,该模块需要实现调查问卷的查询功能。该模块需要满足不同需求的人群对于调查问卷的查询,并能够显示调查问卷的发布时间以及问卷调查的统计结果,其功能结构示意图如图4-4所示。4.4.3 发布调查问卷模块的功能设计发布调查问卷模块的作用,就是帮助发布者发布调查问卷。发布人在输入调查问卷的标题、问卷内容后,点击发布按钮即可完成调查问卷的发布。用户可以通过该模块进行调查问卷的创建、编辑、删除、发布以及设置调查问卷的开始时间和结束时间等,其功能结构示意图如图4-5所示。4.4.4 后台管理员管理模块的功能设计后台管理员管理模块适用于管理员对调查问卷进行管理,需要对不合理的问卷进行删除,实现对问卷进行新增、编辑、条件查询功能,如图4-6所示。4.4.5 数据可视化模块的功能设计数据可视化模块用于展示问卷的统计分析功能,需要有一张图表作为载体,展示问卷的情况,如图4-7所示。4.5数据库分析与设计问卷管理系统数据库是问卷信息的数据库,相关信息是高度专业化的。数据库的设计和创建是为了反映整个数据的业务流程,而不仅仅是存储数据。系统关键数据表的主要逻辑结构设计如下图所示。4.6本章小结第四章是问卷调查系统的设计部分。对登陆注册模块、调查问卷查询模块、发布调查问卷模块、后台管理员管理模块、数据可视化模块这五大模块进行了架构设计,和对数据库进行了设计。5系统功能与界面的实现5.1 登录注册的设计实现用户在进入问卷调查系统后,首先进入到登陆界面,如图5-1所示。用户需要输入用户名和登陆密码,点击下方蓝色的立即登陆按钮,完成用户登陆系统的操作。图5-1 系统登陆界面如果用户没有输入用户名或密码直接点击“立即登陆”按钮,系统会给与红色字体反馈,提示用户需要输入用户名和密码,如图5-2所示。图5-2 系统登陆验证失败界面如果用户没有系统账号,可以点击下方白色“前去注册”按钮,即可跳转到登录页。用户进入系统后,可以看到系统的首页,如图5-3所示。图5-3 系统首页5.2 调查问卷查询模块的设计实现进入系统后,用户可以查询到他人发布的问卷,如图5-3所示。点击某个问卷的查看按钮,即可进入问卷,问卷详情界面如图5-4所示。图5-4 问卷详情界面5.3 发布调查问卷模块的设计实现用户可以发布自己的问卷信息,点击右上角的“添加问卷”按钮,输入问卷标题、选择问卷模板,最终跳转到发布界面,如图5-5所示。图5-5 新增问卷界面问卷题目支持多种类型,分为单选题、多选题、问答题和打分题,还可以选择是否为必填项,问卷发起人可以根据自己的需要定制问卷内容,如图5-6所示。图5-6 问卷编辑界面为了方便用户发布问卷,系统设置了根据模板添加题目的功能,用户只需点击模板内容,模板中的问卷题目会自动加入问卷,非常方便,如图5-7、5-8、5-9所示。图5-7 问卷模板界面A图5-8 问卷模板界面B图5-9 问卷模板界面C问卷内容编辑完成后,用户即可预览自己制作的问卷内容,如图5-10所示。图5-10 问卷预览界面5.4 后台管理员管理模块的设计实现管理员使用admin账户登陆系统,可以看到系统的所有用户信息,如图5-11所示。图5-11 用户管理界面6结论与展望6.1 结论从整个问卷系统的构成开始,介绍问卷管理系统的五大功能模块。最后,我开发完成了这套问卷管理系统。设计开始时,多数国内外文献收集和比较,对问卷管理系统的现状进行了分析,并说明开发问卷系统的意义和重要性,同时根据国内外现状介绍开发问卷调查系统所用的热门技术框架,接着分析问卷管理系统实际需求,确定问卷调查系统的具体功能。在问卷系统的开发阶段,使用Vue和SpringBoot进行编程,最终将问卷调查系统开发完成。6.2 展望本文设计的问卷管理系统能够投入使用,满足调查问卷的基本要求,适用于问卷调查及相关职工需求调查。然而,由于缺乏个人水平等因素,研究中还存在许多问题和差距。例如,本文的调查系统使用MongoDB存储系统生成的数据。但是,如果以后信息量增加,可能会对性能产生一些影响。考虑稍后增加缓存以增加数据存储容量。第二,确保检查员的信息安全也是重中之重,在问卷调查系统中,用于数据采用明文存储,所以如果未来要完善这套系统,首先要将用户的明文数据进行MP5加密传输,保证用户的数据安全。参考文献[1] 区县问卷调查管理系统设计与实现[D]. 岳建涛.重庆大学 2021[2] 财政部. 关于开展城乡问卷调查工作的指导意见[J]. 中国实用乡村医生杂志, 2021, 019(021):1-3.[3] 邓本霞. 问卷调查, 惠及民生[J]. 法制与经济(中旬), 2021, 000(004):93+95.[4] 石枫. 城乡问卷调查运行困境及问题[J]. 现代经济信息, 2021(12):51-52.[5] 黄华波. 问卷调查的制度特性与经办模式分析[J]. 中国社会保障, 2021(8).[6] 精准施策是决胜问卷调查攻坚的关键[J]. 王运柏. 新湘评论. 2020(07)[7] 问卷调查委托商保承办的现状及问题分析[J]. 朱铭来,解莹,李海燕. 2020(03)[8] 新问卷调查系统的设计与实现[D]. 张业恒.郑州大学 2021[9] 电子问卷调查助推精准扶贫的现状与对策[J]. 向运华,罗家琪. 决策与信息. 2021(12).[10] Suggestion on Critical Illness Insurance in China[J] . L Zhu,H Xu,X Cui. Value in Health . 2016 (7)[11] 云南省城镇问卷调查信息系统开发研究[D]. 李锐.云南大学 2021[12] 李若翰. 问卷调查管理系统设计与实现[D].江西财经大学,2021.[13] 金霞.广西问卷调查制度存在的问题及建议[J].现代商贸工业,2021,42(11):40-41.[14] 黄大敏,刘双花,赵云.问卷调查的完全知晓情况及影响因素[J].广西医学,2021,43(01):92-95.[15] 李阳,田文华,段光锋.上海市问卷调查政策:演进、现状与思考[J].保险理论与实践,2020(01):74-86.引用说明:引用以上内容的用户,必须同意以下内容,否则请勿引用!出于自愿而使用本文,了解引用本文的风险,且同意自己承担引用本文的风险。利用本文内容构建的任何信息内容以及导致的任何版权纠纷和法律争议及后果和作者无关,作者对此不承担任何责任。在任何情况下,对于因引用本文而导致的任何难以合理预估的损失(包括但不仅限于商业利润损失、业务中断与业务信息丢失),作者概不承担任何责任。必须了解使用本文内容的风险,作者不对其提供二次维护服务,也不提供任何有关资料。
抽象还记得在校期间上《大学物理》课的时候,老师在讲物质之间的万有引力定律,其实我内心不是很理解,就感觉有点点抽象,在生活中没有实际应用。换句话说,我们看不见,摸不着,但不能否认他的存在。又比如说,水果就是一个抽象概念。“吃水果”,代表吃苹果香蕉梨等具体的水果,而不是“水果”这个物质。在Java面向对象编程中,也有“抽象”这一个概念,Java提供了abstract关键字。abstractabstract是Java语言中一个重要的关键字,是表示抽象的修饰符,可以修饰类和方法,被修饰的类和方法分别被称为抽象类和抽象方法。比如水果类就是一个抽象类,具体到某种水果的实现时,总是归类于某类水果种类。所以说,在需要某个抽象类的具体实例化时,只能用具体类的实例来代替。而且,抽象类不能实例化,不能new一个新对象。抽象类在Java中,抽象类可以理解为一个半成品,需要子类继承该抽象类,并且覆盖抽象方法,这样子类才有new对象的能力。但如果子类还是没能实现父类的抽象方法,那么子类也是抽象类,可以无限循环下去。抽象类一般位于抽象层,表示该类的设计还没完善,还没得到具体解释,必须在子类进一步完善之后,才可以实例化对象。创建一个抽象类:Userpackage cn.zwz; public interface User { void say(); }创建User类的实例化:Studentpackage cn.zwz; public class Student implements User{ @Override public void say() { System.out.println("我是学生"); } }Student类实现了抽象类User的say方法,才能实例化对象进行调用方法:package cn.zwz; public class Main { public static void main(String[] args) { Student student = new Student(); student.say(); } }Java的abstract有一定的约束条件,比如:1.抽象类可以没有抽象方法,如:public abstract class User { }2.在一个类中存在抽象方法时,该类会变成抽象类public abstract class User { abstract void say(); }3.类的构造方法不能抽象化public abstract class User { private String name; private int age; // 错误 abstract public User(String name, int age) { this.name = name; this.age = age; } }4.类的静态方法不能抽象化public abstract class User { /** * 错误 */ public abstract static int add(int a,int b) { return a + b; } }5.抽象类抽象方法不能被final修饰public abstract class User { private String name; private final int age; // 错误 }6.抽象方法不能和public等权限关键字连用。public abstract class User { private String name; private abstract int age; // 错误 }接口在Java程序设计中,不支持多继承,但支持实现多个接口。Java提供了interface关键字来定义接口,可以理解为是一种规范或者一种标准。Java采用单一继承机制,多继承的使用场景则用接口来弥补。比如有一名工人张三,在人类生物学角度看,只有一位生物学意义上的父亲。但对张三来说,在不同场景下有不同的身份,在学校是一个学生,在公司是一名软件工程师,在超市是一名消费者…根据传统的面向对象概念,张三必须要有学生父亲,才能成为学生;必须要有一名消费者父亲,才能成为消费者…这显然是不成立的。Java如何实现?就是用了接口的概念,张三接了学生的口,那么他就是学生,接了消费者的口,那么他就是消费者。又比如说生活中各式各样的标准件,比如A4纸,无需提供纸张的长宽度,即可完成打印;比如电器的220V电压,无需提供电阻和电流值;又比如说软考,我们通过学习成长,拿到了软考证书,就可以去当软件工程师。接口就是规范、标准,在日常生活中有着各式各样广泛的应用。在Java开发中也是这样,开发者在设计接口时,可以不关注细节,只关心接口的功能和数据格式要求。比如下面的一个User接口public interface User { /** * 要实现说话功能 */ public void say(); /** * 要实现加法计算功能 * @param x * @param y * @return */ public int add(int x,int y); }在Java程序设计中,接口的出现让面向对象程序设计理念前进了一大步,使得代码能够更好的模拟现有世界。接口的具体实现在Java中,一个类可以通过关键字 implements 申明自己实现的接口。如果需要实现多个接口,用逗号隔开即可。如下Student学生类实现了User接口。public class Student implements User{ @Override public void say() { System.out.println("我是一名学生!"); } @Override public int add(int x, int y) { return x + y; } }Student类实现了User接口,和继承机制一样,继承了接口中定义的常量和抽象方法。常量可以直接使用,但抽象方法需要在类中提供具体实现;也可以不实现且继续成为抽象类,不能实例化对象。接口和抽象类的关系接口是抽象类的子集,是抽象类的一种特殊实现。接口中所有方法都必须是抽象的,但抽象类中可以有不抽象的方法。接口中方法默认为public、abstract,抽象类中默认为public、static、final,两者存在明显差异。接口不能存在构造方法,而抽象类可以。接口没有普通成员变量,但抽象类可以。接口不能存在静态方法,但抽象类可以。Java类可以实现多个接口,但只能继承一个抽象类。接口的作用从以上抽象类和接口的对比中可以发现,接口是在系统架构设计方面发挥更多的作用,主要用于定义模块之间的关联信息。而抽象类在实际编程中提供更好的作用,可以实现代码的复用,降低代码的耦合性。多态机制多态是面向对象程序设计的一大特性,也是一个基本的设计原则。对于同样一个触发条件,不同对象的响应事件是不一样的,也就是多态。在生物学的多样性,也就是Java的多态机制。Java可以通过方法重载、方法覆盖来实现多态机制,在不同的应用场景有着丰富的应用场景。
View UI是基于Vue的一个组件库,能够帮助前端开发人员快速构建界面!如果您还没有接触过View UI,还不会配置开发环境,请点击这里 先看一个花里胡哨的界面,感受一下吧! 一、基础用法 View UI 中含有 Grid 栅格 组件,我们可以使用它,对界面快速的划分。如下图所示:View UI 中含有 <Row> 标签,它就是我们所说的行 这一个概念上图的每一行,都是由一对<Row>标签构成,代码如下:1. <template> 2. <div> 3. <Row> 4. <Col span="12"><Button long type="warning">ZWZ-12</Button></Col> 5. <Col span="12"><Button long type="info">ZWZ-12</Button></Col> 6. </Row> 7. </div> 8. </template>在<Row>标签内包含了<Col>标签,就是我们所说的列。View UI将界面按照横竖快速划分,先分行,再分列。<Col>标签中,可以设置一个属性span,就是列的宽度。View UI将一整行平均分为24块,span属性就是当前<Col>占了几块。24是1,2,3,4,6,8,12,24的倍数,能够满足大多数的分割需求。我这里使用加长版按钮铺满整合列,使得演示效果更加明显。以上就是View UI中,横竖划分区域的基础用法。 二、间距分割 看了之前的界面,每个按钮之前紧密的安排在一起。但在实际应用中,明显是不行的。列与列之前必须要有所空隙,这样才能让界面更具美感。比如下图所示:View UI 当然考虑到了这一点,我们可以在<Row>标签中设置 gutter 属性,给列与列之前留出空隙。属性名属性说明gutter栅格间距,单位 px,左右平分1. <template> 2. <div> 3. <Row :gutter="16"> 4. <Col span="8"><Button long type="primary">ZWZ-8</Button></Col> 5. <Col span="8"><Button long type="success">ZWZ-8</Button></Col> 6. <Col span="8"><Button long type="error">ZWZ-8</Button></Col> 7. </Row> 8. </div> 9. </template>我们将<Row>标签的gutter属性设置为16,每个列之前的空隙就变成了16px,这样界面变得更加美观。三、水平垂直居中如果<Row>下的<Col>标签块数之和,不到24,就会出现空白的区域,如下所示:这也是日常开发中经常遇到的问题,我们可以给<Row>标签设置align属性和justify属性,分别代表该行的垂直对齐方式和水平对齐方式。属性属性说明属性类型alignflex 布局下的垂直对齐方式,可选值为top、middle、bottomStringjustifyflex 布局下的水平排列方式,可选值为start、end、center、space-around、space-betweenString1. <Row align="center" justify="center" :gutter="16"> 2. </Row>设置后,该行所在的列会被居中显示 本文首发CSDN,原文地址 https://zwz99.blog.csdn.net/article/details/116882859 四、动态排序 之前横竖不管如何划分,都是固定死的。但是可曾想过,每个列需要动态定位。比如四个列为1、2、3、4排列,某个事件后,需要1、3、2、4排列,这可咋整?View UI作者当然也考虑到了这一点,我们只需要给<Col>标签设置order属性即可,order就是列所在行中的排序值,排序值越小越靠左。属性名属性说明order栅格的顺序,在flex布局模式下有效我们给order设置一个自动变化定时器,就完成了下面的闪烁界面!1. <template> 2. <div> 3. <Row :gutter="16"> 4. <Col span="4" :order="index41"><Button long type="error">ZWZ-4</Button></Col> 5. <Col span="4" :order="index42"><Button long type="primary">ZWZ-4</Button></Col> 6. <Col span="4" :order="index43"><Button long type="info">ZWZ-4</Button></Col> 7. <Col span="4" :order="index44"><Button long type="success">ZWZ-4</Button></Col> 8. <Col span="4" :order="index45"><Button long type="warning">ZWZ-4</Button></Col> 9. <Col span="4" :order="index46"><Button long type="error">ZWZ-4</Button></Col> 10. </Row> 11. </div> 12. </template> 以上是我在实际开发中经常使用到的点,不知你有没有get到呢?View UI还支持响应式布局,即根据浏览器宽度动态设置所在列的宽度,当然这在我的实际开发中很少用到,所以就不再一一叙述了。完整代码:1. <template> 2. <div> 3. <Row :gutter="16"> 4. <Col span="12" :order="index11"><Button long type="primary">ZWZ-12</Button></Col> 5. <Col span="12" :order="index12"><Button long type="info">ZWZ-12</Button></Col> 6. </Row> 7. <br> 8. <Row :gutter="16"> 9. <Col span="8" :order="index21"><Button long type="success">ZWZ-8</Button></Col> 10. <Col span="8" :order="index22"><Button long type="warning">ZWZ-8</Button></Col> 11. <Col span="8" :order="index23"><Button long type="error">ZWZ-8</Button></Col> 12. </Row> 13. <br> 14. <Row :gutter="16"> 15. <Col span="6" :order="index31"><Button long type="primary">ZWZ-6</Button></Col> 16. <Col span="6" :order="index32"><Button long type="info">ZWZ-6</Button></Col> 17. <Col span="6" :order="index33"><Button long type="success">ZWZ-6</Button></Col> 18. <Col span="6" :order="index34"><Button long type="warning">ZWZ-6</Button></Col> 19. </Row> 20. <br> 21. <Row align="center" justify="center" :gutter="16"> 22. <Col span="4" :order="index41"><Button long type="error">ZWZ-4</Button></Col> 23. <Col span="4" :order="index42"><Button long type="primary">ZWZ-4</Button></Col> 24. <Col span="4" :order="index43"><Button long type="info">ZWZ-4</Button></Col> 25. <Col span="4" :order="index44"><Button long type="success">ZWZ-4</Button></Col> 26. <Col span="4" :order="index45"><Button long type="warning">ZWZ-4</Button></Col> 27. <Col span="4" :order="index46"><Button long type="error">ZWZ-4</Button></Col> 28. </Row> 29. </div> 30. </template> 31. 32. <script> 33. 34. export default { 35. name: 'app', 36. data() { 37. return { 38. index11: 0, 39. index12: 1, 40. index21: 0, 41. index22: 1, 42. index23: 2, 43. index31: 0, 44. index32: 1, 45. index33: 2, 46. index34: 3, 47. index41: 0, 48. index42: 1, 49. index43: 2, 50. index44: 3, 51. index45: 4, 52. index46: 5, 53. } 54. }, 55. methods: { 56. init() { 57. this.timer = setInterval(this.changeIndex, 100); 58. }, 59. changeIndex() { 60. this.index11 = (this.index11 + 1) % 2; 61. this.index12 = (this.index12 + 1) % 2; 62. this.index21 = (this.index21 + 1) % 3; 63. this.index22 = (this.index22 + 1) % 3; 64. this.index23 = (this.index23 + 1) % 3; 65. this.index31 = (this.index31 + 1) % 4; 66. this.index32 = (this.index32 + 1) % 4; 67. this.index33 = (this.index33 + 1) % 4; 68. this.index34 = (this.index34 + 1) % 4; 69. this.index41 = (this.index41 + 1) % 6; 70. this.index42 = (this.index42 + 1) % 6; 71. this.index43 = (this.index43 + 1) % 6; 72. this.index44 = (this.index44 + 1) % 6; 73. this.index45 = (this.index45 + 1) % 6; 74. this.index46 = (this.index46 + 1) % 6; 75. } 76. }, 77. mounted() { 78. this.init(); 79. } 80. } 81. </script> 82. 83. <style> 84. </style>
前言Vue是国内最流行的前端框架之一,View UI是基于Vue的组件库。有了它,可以快速搭建Vue系统,并保证系统的UI质量。View UI 和 Element UI 一样,都是Vue组件库的佼佼者。作者也是使用View UI组件库搭建了公司的OA系统,最近特地回顾下研发期间学过的内容。 一、下载安装包1.1 nodejs nodejs是Vue开发必备的开发环境,下载安装包正常安装即可nodejs下载 : http://nodejs.cn/download/nodejs 下载 1.2 VsCodeVsCode是Vue的开发工具,当然也可以使用 HbuilderX。VsCode下载:https://code.visualstudio.com/VsCode 下载VsCode安装后默认为英文界面,需要设置为简体中文1. 按下键盘快捷键 【Ctrl+Shift+P】2.输入lang设置简体中文 二、安装脚手架 安装淘宝镜像(可选)npm install -g cnpm --registry=http://registry.npm.taobao.org卸载现有脚手架(可选)npm uninstall -g @vue/cli安装脚手架,我使用的是3.0.4版本npm install -g @vue/cli@3.0.4 三、运行项目 命令行(cmd) cd 到指定的目录cd c:\java\vue创建项目 testvue create test创建完成后 进入项目目录cd test安装View UI 相关依赖npm install view-design --saveVue项目引入依赖main.js文件添加View UI,完整代码见底部1. import ViewUI from 'view-design'; 2. import 'view-design/dist/styles/iview.css'; 3. 4. Vue.use(ViewUI);前端使用View UI组件1. <template> 2. <div> 3. <Button type="primary">Primary</Button> 4. </div> 5. </template> 运行项目npm run dev其中dev还是serve由 package.json 配置决定 比如我的配置是dev,那就是dev1. { 2. "name": "test", 3. "version": "0.1.0", 4. "private": true, 5. "scripts": { 6. "dev": "vue-cli-service serve", 7. "build": "vue-cli-service build", 8. "lint": "vue-cli-service lint" 9. }, 10. // 省略更多 11. } 运行结果VsCode 控制台 运行结果图 想写的有很多,一步一步来,先把最基础的环境搭建写明白。搭建了基本的开发环境,才可以进一步测试View UI的各大组件。附:main.js完整代码1. import Vue from 'vue' 2. import App from './App.vue' 3. import ViewUI from 'view-design'; 4. import 'view-design/dist/styles/iview.css'; 5. 6. Vue.use(ViewUI); 7. Vue.config.productionTip = false 8. 9. new Vue({ 10. render: h => h(App), 11. }).$mount('#app')
在调用企业微信的API接口之前,需要自行编写HTTPS请求的方法,在这里用Java实现钉钉API直接为我们准备好了HTTPS请求,只需导包即可,而企业微信需要自行实现本文主要介绍,如何使用Java代码,发起企业微信API支持的HTTPS请求,获取access_token目录一、编写HTTPS请求二、获取 access_token 一、编写HTTPS请求 首先创建一个类,实现 X509TrustManager 接口1. import javax.net.ssl.*; 2. import java.io.BufferedReader; 3. import java.io.InputStream; 4. import java.io.InputStreamReader; 5. import java.io.OutputStream; 6. import java.net.URL; 7. import java.security.cert.CertificateException; 8. import java.security.cert.X509Certificate; 9. 10. public class WeChatUtils implements X509TrustManager { 11. 12. /** 13. * 处理https GET/POST请求 14. * @param requestUrl 请求地址 15. * @param requestMethod 请求方法 16. * @param outputStr 参数 17. * @return 18. */ 19. public static String httpsRequest(String requestUrl,String requestMethod,String outputStr){ 20. StringBuffer buffer=null; 21. try{ 22. //创建SSLContext 23. SSLContext sslContext=SSLContext.getInstance("SSL"); 24. TrustManager[] tm={new WeChatUtils()}; 25. //初始化 26. sslContext.init(null, tm, new java.security.SecureRandom());; 27. //获取SSLSocketFactory对象 28. SSLSocketFactory ssf=sslContext.getSocketFactory(); 29. URL url=new URL(requestUrl); 30. HttpsURLConnection conn=(HttpsURLConnection)url.openConnection(); 31. conn.setDoOutput(true); 32. conn.setDoInput(true); 33. conn.setUseCaches(false); 34. conn.setRequestMethod(requestMethod); 35. //设置当前实例使用的SSLSoctetFactory 36. conn.setSSLSocketFactory(ssf); 37. conn.connect(); 38. //往服务器端写内容 39. if(null!=outputStr){ 40. OutputStream os=conn.getOutputStream(); 41. os.write(outputStr.getBytes("utf-8")); 42. os.close(); 43. } 44. //读取服务器端返回的内容 45. InputStream is=conn.getInputStream(); 46. InputStreamReader isr=new InputStreamReader(is,"utf-8"); 47. BufferedReader br=new BufferedReader(isr); 48. buffer=new StringBuffer(); 49. String line=null; 50. while((line=br.readLine())!=null){ 51. buffer.append(line); 52. } 53. }catch(Exception e){ 54. e.printStackTrace(); 55. } 56. return buffer.toString(); 57. } 58. 59. @Override 60. public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { 61. 62. } 63. 64. @Override 65. public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { 66. 67. } 68. 69. @Override 70. public X509Certificate[] getAcceptedIssuers() { 71. return new X509Certificate[0]; 72. } 73. }原文CSDN链接:https://zwz99.blog.csdn.net/article/details/113845625二、获取 access_token获取access_token是调用企业微信API接口的第一步,相当于创建了一个登录凭证,其它的业务API接口,都需要依赖于access_token来鉴权调用者身份。因此开发者,在使用业务接口前,要明确access_token的颁发来源,使用正确的access_token。请求方式: GET(HTTPS)请求地址: https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRETcorpid:每个企业都拥有唯一的corpid,获取此信息可在管理后台“我的企业”-“企业信息”下查看“企业ID”corpsecret:secret是企业应用里面用于保障数据安全的“钥匙”,每一个应用都有一个独立的访问密钥,为了保证数据的安全,secret务必不能泄漏1. import com.alibaba.fastjson.JSON; 2. import com.alibaba.fastjson.JSONObject; 3. 4. public static String getToken(){ 5. String str= httpsRequest("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + "wwxxxxxxxxxxxxxxxx" + "&corpsecret=" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","GET",null); 6. JSONObject err = JSON.parseObject(str); 7. if(err.getString("errmsg").equals("ok")){ 8. return err.getString("access_token"); 9. } 10. return null; 11. }调用getToken方法,即可获得到最新的Token,用以调用企业微信各类API接口。返回结果1. { 2. "errcode": 0, 3. "errmsg": "ok", 4. "access_token": "fhafhdsajhfjkshfjkshjkfsjkdfhjkahfkjahjfhajkfhajk", 5. "expires_in": 7200 6. }方法返回fhafhdsajhfjkshfjkshjkfsjkdfhjkahfkjahjfhajkfhajk附:fastjson maven1. <dependency> 2. <groupId>com.alibaba</groupId> 3. <artifactId>fastjson</artifactId> 4. <version>1.2.9</version> 5. </dependency>
我们在开发企业内部应用时,需要实现内部应用和企业微信的双向同步,即互联互通。举个例子同步一:企业内部OA系统在修改内部通讯录时,可以同步企业微信(直接调API接口即可)同步二:在企业微信后台修改通讯录时,反馈给内部OA系统(本文讲解)总的来说,实现通讯录回调的流程分为四步:第一步:管理员在企业微信在后台修改通讯录信息(除了API接口修改之外的都算)第二步:企业微信修改通讯录后,以XML的方式,向企业内部系统发送修改详情第三步:企业内部系统收到XML信息后,解密信息第四步:对于解密后的信息,修改企业内部系统的通讯录具体实现 一、导包解密工具下载地址下载企业微信提供的解密工具,放到自己的项目内。注意com包不能改名字如果1.9版本的包无法通过编译,可以使用1.4的包1. <dependency> 2. <groupId>commons-codec</groupId> 3. <artifactId>commons-codec</artifactId> 4. <version>1.4</version> 5. </dependency> 二、验证URL在企业微信管理后台,配置URL test方法为验证URL的模板,拿来即用ParameterSettings是我放固定字段的类,相应参数替换即可1. import com.qq.weixin.mp.aes.AesException; 2. import com.qq.weixin.mp.aes.WXBizMsgCrypt; 3. 4. import javax.servlet.http.HttpServletRequest; 5. import javax.servlet.http.HttpServletResponse; 6. import java.io.PrintWriter; 7. 8. /** 9. * 验证URL 10. * @param request 11. * @param response 12. * @throws Exception 13. */ 14. public void test(HttpServletRequest request, HttpServletResponse response) throws Exception { 15. // 微信加密签名 16. String msg_signature = request.getParameter("msg_signature"); 17. // 时间戳 18. String timestamp = request.getParameter("timestamp"); 19. // 随机数 20. String nonce = request.getParameter("nonce"); 21. // 随机字符串 22. String echostr = request.getParameter("echostr"); 23. 24. System.out.println("request=" + request.getRequestURL()); 25. 26. PrintWriter out = response.getWriter(); 27. // 通过检验msg_signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 28. String result = null; 29. try { 30. WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(ParameterSettings.YHHD_TOKEN, ParameterSettings.YHHD_EAK, ParameterSettings.AS_CORPID); 31. result = wxcpt.VerifyURL(msg_signature, timestamp, nonce, echostr); 32. } catch (AesException e) { 33. e.printStackTrace(); 34. } 35. if (result == null) { 36. result = ParameterSettings.YHHD_TOKEN; 37. } 38. out.print(result); 39. out.close(); 40. out = null; 41. }原文CSDN链接:https://zwz99.blog.csdn.net/article/details/113818974三、解密验证URL完成后,将该URL的接口方法替代成下方callBack方法的代码当企业微信发送回调通知时,该方法会实现接收该模板会将XML格式的数据转换为标准JSON,方便后续处理JSON用了阿里的fastjson,maven依赖如下:1. <dependency> 2. <groupId>com.alibaba</groupId> 3. <artifactId>fastjson</artifactId> 4. <version>1.2.9</version> 5. </dependency>1. import com.alibaba.fastjson.JSONObject; 2. import com.qq.weixin.mp.aes.AesException; 3. import com.qq.weixin.mp.aes.WXBizMsgCrypt; 4. import org.springframework.web.bind.annotation.RequestMapping; 5. import org.springframework.web.bind.annotation.RequestMethod; 6. 7. import javax.servlet.ServletInputStream; 8. import javax.servlet.http.HttpServletRequest; 9. import javax.servlet.http.HttpServletResponse; 10. import java.io.BufferedReader; 11. import java.io.IOException; 12. import java.io.InputStreamReader; 13. import java.io.PrintWriter; 14. 15. 16. /** 17. * 企业微信发送XML到这个方法 18. * @param request 19. * @param response 20. * @throws Exception 21. */ 22. @RequestMapping(value = "/callBack", method = RequestMethod.POST) 23. public void callBack(HttpServletRequest request, HttpServletResponse response) throws Exception { 24. request.setCharacterEncoding("UTF-8"); 25. response.setCharacterEncoding("UTF-8"); 26. String respMessage = ""; 27. respMessage=getDecryptMsg(request); 28. //进行回调处理 29. dealCallBackEvent(respMessage); 30. PrintWriter out = response.getWriter(); 31. out.print(respMessage); 32. out.close(); 33. } 34. 35. /** 36. * 解密XML数据转换JSON 37. * @param request 38. * @return 39. */ 40. public String getDecryptMsg(HttpServletRequest request) { 41. String postData=""; // 密文,对应POST请求的数据 42. String result=""; // 明文,解密之后的结果 43. String msg_signature = request.getParameter("msg_signature"); // 微信加密签名 44. String timestamp = request.getParameter("timestamp"); // 时间戳 45. String nonce = request.getParameter("nonce"); // 随机数 46. try { 47. //1.获取加密的请求消息:使用输入流获得加密请求消息postData 48. ServletInputStream in = request.getInputStream(); 49. BufferedReader reader =new BufferedReader(new InputStreamReader(in)); 50. 51. String tempStr=""; //作为输出字符串的临时串,用于判断是否读取完毕 52. while(null!=(tempStr=reader.readLine())){ 53. postData+=tempStr; 54. } 55. //2.获取消息明文:对加密的请求消息进行解密获得明文 56. WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(ParameterSettings.YHHD_TOKEN, ParameterSettings.YHHD_EAK, ParameterSettings.YH_CORPID); 57. result = wxcpt.DecryptMsg(msg_signature, timestamp, nonce, postData); 58. } catch (IOException e) { 59. e.printStackTrace(); 60. } catch (AesException e) { 61. e.printStackTrace(); 62. } 63. return result; 64. } 65. 66. /** 67. * 对解密后的数据进行业务逻辑处理 68. * @param text 69. */ 70. private void dealCallBackEvent(String text) { 71. JSONObject json = XmlTool.documentToJSONObject(text); 72. String event = json.getString("Event"); 73. String changeType = json.getString("ChangeType"); 74. if (event.equals("change_contact")) { 75. if (changeType.equals("create_user")) { // 创建用户回调 76. String name = json.getString("Name"); 77. String userID = json.getString("UserID"); 78. String departmentStr = json.getString("Department"); // 部门为逗号分开的字符串 79. String[] departmentList = departmentStr.split(","); 80. String corpID = json.getString("ToUserName"); 81. String mobile = json.getString("Mobile"); 82. if (corpID.equals(ParameterSettings.YH_CORPID)) { // 替换企业ID 83. // 业务逻辑代码 84. } 85. } 86. } 87. } 核心代码到此结束,以下是其他所有代码1. import java.util.List; 2. 3. import org.dom4j.Attribute; 4. import org.dom4j.Document; 5. import org.dom4j.DocumentException; 6. import org.dom4j.DocumentHelper; 7. import org.dom4j.Element; 8. 9. import com.alibaba.fastjson.JSONArray; 10. import com.alibaba.fastjson.JSONObject; 11. 12. public class XmlTool { 13. /** 14. * String 转 org.dom4j.Document 15. * @param xml 16. * @return 17. * @throws DocumentException 18. */ 19. public static Document strToDocument(String xml){ 20. try { 21. //加上xml标签是为了获取最外层的标签,如果不需要可以去掉 22. return DocumentHelper.parseText(xml); 23. } catch (DocumentException e) { 24. return null; 25. } 26. } 27. 28. /** 29. * org.dom4j.Document 转 com.alibaba.fastjson.JSONObject 30. * @param xml 31. * @return 32. * @throws DocumentException 33. */ 34. public static JSONObject documentToJSONObject(String xml){ 35. return elementToJSONObject(strToDocument(xml).getRootElement()); 36. } 37. 38. /** 39. * org.dom4j.Element 转 com.alibaba.fastjson.JSONObject 40. * @param node 41. * @return 42. */ 43. public static JSONObject elementToJSONObject(Element node) { 44. JSONObject result = new JSONObject(); 45. // 当前节点的名称、文本内容和属性 46. List<Attribute> listAttr = node.attributes();// 当前节点的所有属性的list 47. for (Attribute attr : listAttr) {// 遍历当前节点的所有属性 48. result.put(attr.getName(), attr.getValue()); 49. } 50. // 递归遍历当前节点所有的子节点 51. List<Element> listElement = node.elements();// 所有一级子节点的list 52. if (!listElement.isEmpty()) { 53. for (Element e : listElement) {// 遍历所有一级子节点 54. if (e.attributes().isEmpty() && e.elements().isEmpty()) // 判断一级节点是否有属性和子节点 55. result.put(e.getName(), e.getTextTrim());// 沒有则将当前节点作为上级节点的属性对待 56. else { 57. if (!result.containsKey(e.getName())) // 判断父节点是否存在该一级节点名称的属性 58. result.put(e.getName(), new JSONArray());// 没有则创建 59. ((JSONArray) result.get(e.getName())).add(elementToJSONObject(e));// 将该一级节点放入该节点名称的属性对应的值中 60. } 61. } 62. } 63. return result; 64. } 65. } 1. import lombok.Data; 2. import java.util.List; 3. 4. @Data 5. public class Items { 6. List<Item> item; 7. }1. import lombok.Data; 2. 3. import java.util.List; 4. 5. @Data 6. public class Item { 7. private String type; 8. 9. private List<TextValue> text; 10. 11. private String name; 12. 13. private List<WebValue> web; 14. }1. import lombok.Data; 2. 3. import java.util.List; 4. 5. @Data 6. public class Member { 7. private String toUserName; 8. private String fromUserName; 9. private String createTime; 10. private String msgType; 11. private String event; 12. private String changeType; 13. private String userID; 14. private String newUserID; 15. private String name; 16. private String department; 17. private String isLeaderInDept; 18. private String position; 19. private String mobile; 20. private String gender; 21. private String email; 22. private String status; 23. private String avatar; 24. private String alias; 25. private String telephone; 26. private String address; 27. private List<Items> extAttr; 28. }1. import lombok.Data; 2. 3. @Data 4. public class TextValue { 5. 6. private String Value; 7. }1. import lombok.Data; 2. 3. @Data 4. public class WebValue { 5. private String Title; 6. private String Url; 7. }
在之前的小程序项目中,争对用户信息的有效性问题(比如手机号是否真实),我使用了微信小程序自带的获取手机号的功能,获取到用户的手机号,因为微信绑定的手机号一定经过微信的严格验证,能够确保手机号真实。但是根据客户的需求,需要实现使用短信验证码登入的功能,那么没办法,客户是上帝,我只能去实现它。 前言 对于获取微信绑定的手机号来确保小程序用户的真实性,可以看我这篇文章,我写的很详细。接下来讲解如何实现短信验证码来校验用户的有效性。本文主要讲解实现微信小程序获取手机短信验证码的后端部分,希望能帮到大家实现过程如下腾讯云中创建短信签名、创建短信正文模板,人工审核使用Java SDK调用短信发送API接口短信发送成功(因为客户要求使用腾讯云服务器,所以我这里用腾讯云为例) 第一步:创建短信签名、创建短信正文模板首先理解一下相关概念:短信签名短信签名是位于短信正文前【】中的署名,用于标识公司或业务,例如【腾讯科技】。申请时企业用户需要上传资质证明,个人用户需要上传个人身份证明。短信签名需要审核通过后才可使用。签名示例:认证企业为:深圳市腾讯计算机系统有限公司,可以申请与企业名相关的签名【腾讯科技】,也可以申请公司旗下的产品名称相关的签名【微信】、【腾讯云】等。简而言之,如果短信内容为:【腾讯科技】您的QQ登录验证码是1234,5分钟内有效。那么,短信签名就是——腾讯科技。这样看懂了吧?短信模板短信模板即具体发送的短信正文内容,短信模板支持验证码模板、通知类短信模板和营销短信模板。短信内容可以通过模板参数实现个性化定制。如果短信内容为:腾讯科技需要发送短信验证码:【腾讯科技】您的QQ登录验证码是1234,2分钟内有效。那么,短信模板就是:您的QQ登录验证码是{1},{2}分钟内有效。模板参数中{1},{2}是变量,且按序排列,他们的值可以在实际下发时通过设置模板参数的值来自定义。为了避免开发者滥发短信,所以短信签名、短信模板需要腾讯云进行人工审核,具体操作如下:打开腾讯云官网,进入右上角控制台,进入短信界面,然后创建签名。然后同样的方法,创建短信模板接着就是人工审核,大概10分钟左右就够了。第二步:使用Java SDK调用短信发送API接口所谓使用SDK,也就是说,腾讯已经给你写好发送短信的API接口,连调用API接口的模板都给你写好了,你只要拿来用就可以。SDK下载地址(Github):https://github.com/TencentCloud/tencentcloud-sdk-java当然这个SDK里面所有功能都实现了,比如发送短信,群发短信,拉取回执状态,统计短信发送数据,包括国内的,境外的,全都有。但是功能多,导包的时间也长,而我们只需要发送国内短信即可,所以我自己把他精简了一下,因为我这里只需要发送短信的功能。我这里以IDEA为例,打开IDEA,新建一个MAVEN项目勾上Create from archetype选择org.apache.maven.archetypes:maven-archetype-webapp添加属性name:archetypeCatalog,value:internal为什么要这么做?是因为系统默认从Maven获取依赖,但是很慢,我们可以选择从本地导入,这样基本不需要时间,达到快速创建项目的效果。 创建完Maven项目,只需要修改两个文件1.pom.xml1. <?xml version="1.0" encoding="UTF-8"?> 2. <project xmlns="http://maven.apache.org/POM/4.0.0" 3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5. <modelVersion>4.0.0</modelVersion> 6. 7. <groupId>org.example</groupId> 8. <artifactId>yanzhengma</artifactId> 9. <version>1.0-SNAPSHOT</version> 10. 11. <properties> 12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 13. <maven.compiler.encoding>UTF-8</maven.compiler.encoding> 14. <java.version>11</java.version> 15. <maven.compiler.source>11</maven.compiler.source> 16. <maven.compiler.target>11</maven.compiler.target> 17. </properties> 18. 19. <dependencies> 20. <dependency> 21. <groupId>com.github.qcloudsms</groupId> 22. <artifactId>qcloudsms</artifactId> 23. <version>1.0.6</version> 24. </dependency> 25. </dependencies> 26. </project>2.随意包下的Main函数1. import com.github.qcloudsms.SmsSingleSender; 2. import com.github.qcloudsms.SmsSingleSenderResult; 3. import com.github.qcloudsms.httpclient.HTTPException; 4. import org.json.JSONException; 5. import java.io.IOException; 6. public class Main { 7. public static void main(String[] args) { 8. // 短信应用 SDK AppID 9. int appid = 1400xxxx84; // SDK AppID 以1400开头 10. // 短信应用 SDK AppKey 11. String appkey = "d4e5bxxxxxxxxxx02c907501b4ee8645"; 12. // 需要发送短信的手机号码 13. String[] phoneNumbers = {"178xxxxxx85"}; 14. // 短信模板 ID,需要在短信应用中申请 15. int templateId = 60xxx8; // NOTE: 这里的模板 ID`7839`只是示例,真实的模板 ID 需要在短信控制台中申请 16. // 签名 17. String smsSign = "XXXX"; // NOTE: 签名参数使用的是`签名内容`,而不是`签名ID`。这里的签名"腾讯云"只是示例,真实的签名需要在短信控制台申请 18. try { 19. String[] params = {"5678","5"}; 20. SmsSingleSender ssender = new SmsSingleSender(appid, appkey); 21. SmsSingleSenderResult result = ssender.sendWithParam("86", phoneNumbers[0], 22. templateId, params, smsSign, "", ""); 23. System.out.println(result); 24. } catch (HTTPException e) { 25. // HTTP 响应码错误 26. e.printStackTrace(); 27. } catch (JSONException e) { 28. // JSON 解析错误 29. e.printStackTrace(); 30. } catch (IOException e) { 31. // 网络 IO 错误 32. e.printStackTrace(); 33. } 34. } 35. }还有要这四个jar包我们就像Java运行Hello World那样,运行一下主函数,短信就发出来了接下来来解析一下代码:1.短信账号,密匙1. int appid = 1400xxxx84; 2. String appkey = "d4e5bxxxxxxxxxx02c907501b4ee8645";类似微信小程序,appid是账号,appkey是密匙,我们在腾讯云控制台获取。点进去可以查看appkey。2.需要发送的手机号 String[] phoneNumbers = {"178xxxxxx85"};3.短信模板IDint templateId = 60xxx8;在第一步的 国内短信 —— 签名管理 中 查看ID。4.签名String smsSign = "XXXX";同短信模板,你申请的是什么签名,这里就写什么,比如“腾讯科技”5.填入参数String[] params = {"5678","5"};在第一步中,介绍了短信模板的概念短信模板就是:您的QQ登录验证码是{1},{2}分钟内有效。 其中这个{1},类似SQL中的预编译,这里有几个参数,这个params数组就几个元素。短信发出去就是——您的QQ登录验证码是5678,5分钟内有效。 以上数据全部替换后,执行Main主函数就可以,短信就发出来了这就是微信小程序中,实现短信验证码登入的后端操作,时间有限,我只是简单写了一下,还有更多功能,我会在后续继续深入研究。
如果涉及到上方领域的公司不填写相关许可证明,就会被PASS掉(见下图其他部分)具体页面如下图所示: 接着就是提交审核,等待审核。不管是否通过,腾讯云都会给你打电话,确认是否你本人操作,如果不通过会告诉你改进方案,如果第一遍打不通,一个小时后会打第二遍,如果第二遍还是打不通,就会被退回。未通过:审核通过会提交到管局审核:五:域名解析我备案时所用的时间,给大家一个参考(域名解析,10分钟,部署主页,30分钟)在腾讯云控制台 —— 域名管理中,对已通过实名认证的域名进行解析选择快速添加解析即可,其中需要填写IP地址,就是云服务器的公网地址;填写的域名就是根域名即可。解析之后,外网就可以通过域名访问该服务器了具体做法:从github中随便下个html网页项目下来,放在云服务器下的 Tomcat\webapps\ROOT目录下,替换掉index.html / index.jsp即可。这样,我们访问域名,就直接可以访问到某个指定网页,而不是tomcat的主页。当然IP地址也一样可以访问! 六:申请SSL证书 我备案时所用的时间,给大家一个参考(申请SSL,2分钟;审核,20分钟)因为微信小程序一定要HTTPS,即一定要加密协议,所以我们需要申请SSL证书,来满足微信小程序的需要。选择免费证书即可,提交后会进入人工审核,我的是20分钟左右就通过了。 七:公安备案 我备案时所用的时间,给大家一个参考(备案审核,一般白天提交第二天处理,晚上提交第三天处理,周末除外)您的网站备案申请通过管局审核并获得备案号后,您必须在网站开通后30日内进行公安备案。如果您的网站涉及经营性行为还需申请经营性网站备案许可证。公安备案审核通过后,您需在30日内登录 全国公安机关互联网站安全管理服务平台,在您的已备案网站详情中,复制网站公安机关备案号,下载备案编号图标,复制备案编号 HTML 代码,并编辑您的网页源代码。公安备案网址:http://www.beian.gov.cn/portal/index我们需要先注册一个账号然后选择左方的新版网站申请,填写相关信息。其中域名证书通过腾讯云控制台中的“域名管理”栏目下载。第三步是填写网站负责人和应急负责人之类的,都填写一个人即可。提交之后,会有审核,审核期间一定要保持网站能够正常访问,即云服务器的tomcat一定要一直开着。 审核通过之后,要把备案图标放在网站 就像下图这样的,放在网站最下面完成之后,备案流程就算全部完成了。 八:部署项目 接下来我们需要把微信小程序的后台,部署到服务器上。我们先从腾讯云控制台 的 SSL证书模块,下载私钥证书,然后把证书(压缩包内的Tomcat版本)放在服务器指定的位置我们在服务器上安装一个IDE(比如eclipse,当然也可以直接把部署好的文件拷贝过去)打开项目的web.xml,在后面加一段代码,目的是配置HTTPS。1. <login-config> 2. <auth-method>CLIENT-CERT</auth-method> 3. <realm-name>Client Cert Users-only Area</realm-name> 4. </login-config> 5. <security-constraint> 6. <web-resource-collection> 7. <web-resource-name>SSL</web-resource-name> 8. <url-pattern>/*</url-pattern> 9. </web-resource-collection> 10. <user-data-constraint> 11. <transport-guarantee>CONFIDENTIAL</transport-guarantee> 12. </user-data-constraint> 13. </security-constraint>在IDE中导入,跑一次再打开Tomcat\conf\server.xml 的约60~70行的地方,将下面一行代码<Connector connectionTimeout="20000" port="443" protocol="HTTP/1.1" redirectPort="8443"/> 替换成:1. <Connector connectionTimeout="20000" port="443" protocol="HTTP/1.1" 2. redirectPort="8443" SSLEnabled="true" clientAuth="false" keystoreFile="C:/Tomcat8.5/conf/ypcqmm.net.jks" 3. keystorePass="qmm_xsh_1974" maxThreads="150" 4. scheme="https" secure="true" sslProtocol="TLS"/>先使用IDE跑起来,只要你自己电脑上能成功运行,在这里打不开没有关系。我们只需要IDE把这个项目部署到Tomcat目录下就可以了。 接着关闭IDE中的Tomcat,使用Tomcat自带的运行工具,跑起来。跑起来之后,稍等1分钟,外网就可以通过域名/项目名访问到部署的项目了。以下是我自己写的某个demo,部署上去之后,外网就可以跑起来了。 备案不易,回想起我备案的那些时候,真是痛苦,一次次的提交,一次次的被驳回。希望能帮到大家,如果其中有流程讲解的不够详细的话,欢迎下方评论区留言,必回解答!
在官网下载 Android SDK网址:https://www.androiddevtools.cn上拉菜单选择SDK Tools下载到Android目录并解压:打开 SDK Manager 开始 下载 安装 SDK会弹出以下界面:选中Tools下的这三个再选其中一个API,比如我的手机是Vivo X9 手机版本是7.1.2, 所以我选7.1.1如果你选了太高,导出来的APK安装包手机无法安装最后Extras内全部选中点击右下角的安装这个时候开始漫长的安装之旅,其中部分文件从国外下载,会很慢,别的安装教程可能会提到镜像服务器,其实就是从中国中间站来下载,提升速度,我觉得不用这个花里胡哨,直接等就完事了。在等SDK下载安装的时候,我们可以先把SDK的环境配好新建一个系统环境变量,变量名为ANDROID_SDK_HOME,变量值为你的SDK安装路径,例如我的路径就是F:\Android\android-sdk_r24.3.2-windows\android-sdk-windows老地方,找不到的翻上面教程把;%ANDROID_SDK_HOME%\platform-tools;%ANDROID_SDK_HOME%\tools添加到Path环境变量中,复制到最后面即可同样可以检测一下是否成功,Win+R 输入cmd 黑框框输入adb,如果有以下界面则成功 这个时候换一个坐姿,等待Andriod SDK的安装完毕,如果有部分安装失败的,重新点安装按钮,不行就again…….全部安装完成之后,选中的插件右边显示Installed 右下角安装按钮变成灰色接着安装ADT:ADT通俗的来讲就是把eclipse和Android联系起来,也许不对,这是我初步的理解下载到Android总目录下面我以ADT-23.0.6为例打开eclipse软件 ,帮助——安装新软件 PS:我装的是汉化版 英文版同理按照下图五步骤:然后重启eclipse最后一步我们要替换一个文件F:\Android\android-sdk_r24.3.2-windows\android-sdk-windows\build-tools\29.0.0\lib下面的dx.jar用25.0版本的dx.jar替换掉目前安装的dx.jar直接替换即可。然后打开eclipse你会发现这个,是因为Android和eclipse没有联系一起选择我们安装的SDK目录即可文字版:F:\Android\android-sdk_r24.3.2-windows\android-sdk-windows点击完成:
不知各位朋友是否有以下的烦恼: 管理几十个项目,每个项目的域名和端口记不住... 同一套系统在不同浏览器上展示不一样... 甲方经常问我项目的网址,其实我也忘记了... 客户习惯使用 C/S 架构的系统,将软件 UI 固化为 WINDOWS 桌面端的应用程序,将一个 Vue 项目摆在他的面前,他看不惯! 解决这类问题的方案之一,就是将项目包装为桌面客户端,就像双击 Excel 那样,就可以进入项目。 那么我们如何去实现呢? 接下来就切入正题! 一、使用 NW.js 打包 NW.js基于Chromium和Node.js。它允许您直接从浏览器调用Node.js代码和模块,并在应用程序中使用Web技术。此外,您可以轻松地将web应用程序打包为本机应用程序。 官网:NW.js 官网 优点:免开发、门槛低、体积小 1.1 下载、解压 NW.js 1.1.1 下载 NW.js 进入 NW.js 官网,点击下载最新版,如下图所示。 下载的是一个普通压缩包,如下图所示。 1.1.2 解压 NW.js 接着我们将压缩包解压到指定目录,解压成功后如下图所示。 1.2 配置被打包的项目 1.2.1 新建 package.json 在 1.1 步的目录内新建 package.json 文件。 提示:可以新建一个空白 txt 文档,然后重命名哦! 并将 package.json 文件的内容编辑为: { "main": "index.html", "name": "我的 CSDN 博客" } 其中 main 字段为接下来新建的 html 文件名称,name 字段可以根据需要自定义,完整的配置会在下面提供。 1.2.2 新建 index.html 接着再新建一个 index.html 文件,如下图所示。 提示:可以新建一个空白 txt 文档,然后重命名哦! 并将 index.html 文件的内容编辑为: <!DOCTYPE html> <html> <head> </head> <body> <script language="javascript" type="text/javascript"> window.location.href='https://blog.csdn.net/qq_41464123'; </script> </body> </html> 1.2.3 压缩 然后将 1.2.1 和 1.2.2 步做的 package.json 和 index.html 压缩,如下图所示。 提示:请注意压缩包内不要有文件夹哦!包内应该直接两个文件 1.2.4 更改后缀名 最后将压缩包后缀名,由 zip 改为 nw,如下图所示。 1.3 合成桌面客户端 1.3.1 合成客户端 前面两个步骤完成后,第三步就要合成桌面客户端了。 打开 cmd 窗口,进入当前目录,如下图所示。 提示:Win + R 键打开 "运行" 窗口,然后输入 "cmd" 按回车就可以打开黑框框了哦! 接着直接输入以下命令,开始合成。 copy /b nw.exe+nw.nw app.exe 运行结果如下图所示。 运行后,回到之前的目录,可以发现多了个 app.exe 文件,如下图所示。 双击即可打开,如下图所示。 1.3.2 更换图标 右键刚刚生成的 app.exe 文件,将快捷方式发送到桌面,操作过程如下图所示。 生成之后如下图所示。 接着右键快捷方式,点击属性,操作界面如下图所示。 点击浏览,选择 ico 图标后,点击确认,如下图所示。 提示:若您手上是 png 或 jpg 图片,需要转换为 ico 格式,网上有很多在线转换工具。 最后重命名快捷方式后,就大功告成啦! 最终效果如下图所示。 当然如果需要完整功能,比如窗口大小、是否全屏、顶部图标、是否固定任务栏等,可以参考如下的配置文件,并在 1.2.1 步骤配置。 { /**指定程序的起始页面。*/ "main": "index.html", /**字符串必须是小写字母或者数字,可以包含.或者_或者-不允许带空格。name必须全局唯一。*/ "name": "Blog", /**程序描述*/ "description": "我的 CSDN 博客", /**程序版本号*/ "version": "1.0.0", /**关键字*/ "keywords": ["demo","node-webkit"], /**bool值,如果设置为false,将禁用webkit的node支持。*/ "nodejs": true, /** * 指定一个node.js文件,当程序启动时,该文件会被运行,启动时间要早于node-webkit加载html的时间。 * 它在node上下文中运行,可以用它来实现类似后台线程的功能。 * (不需要可注释不用) */ //"node-main": "js/node.js", /** * bool值。默认情况下,如果将node-webkit程序打包发布,那么只能启动一个该应用的实例。 * 如果你希望允许同时启动多个实例,将该值设置为false。 */ "single-instance": true, /**窗口属性设置 */ "window": { /**字符串,设置默认title。*/ "title": "我的技术博客", /**窗口的icon。*/ "icon": "img/tubiao.ico.png", /**bool值。是否显示导航栏。*/ "toolbar": false, /**bool值。是否允许调整窗口大小。*/ "resizable": true, /**是否全屏*/ "fullscreen": false, /**是否在win任务栏显示图标*/ "show_in_taskbar": false, /**bool值。如果设置为false,程序将无边框显示。*/ "frame": true, /**字符串。窗口打开时的位置,可以设置为“null”、“center”或者“mouse”。*/ "position": "center", /**主窗口的的宽度。*/ "width": 1920, /**主窗口的的高度。*/ "height": 1080, /**窗口的最小宽度。*/ "min_width": 400, /**窗口的最小高度。*/ "min_height": 335, /**窗口显示的最大宽度,可不设。 "max_width": 800,*/ /**窗口显示的最大高度,可不设。 "max_height": 670,*/ /**bool值,如果设置为false,启动时窗口不可见。*/ "show": true, /**是否在任务栏显示图标。*/ "show_in_taskbar":true, /** * bool值。是否使用kiosk模式。如果使用kiosk模式, * 应用程序将全屏显示,并且阻止用户离开应用。 * */ "kiosk": false }, /**webkit设置*/ "webkit": { /**bool值,是否加载插件,如flash,默认值为false。*/ "plugin": true, /**bool值,是否加载Java applets,默认为false。*/ "java": false, /**bool值,是否启用页面缓存,默认为false。*/ "page-cache": false } } 二、发布 Vue 项目 聪明的同学已经发现,本篇博客的标题为 《经常忘记网址?将Vue项目一键打包为桌面客户端 十分钟让你解决烦恼》。 第一章都在讲将一个网址打包为桌面客户端。 但我们手上的不是网址,是一个 localhost(本地版) 的 Vue 项目! 第二章就主要讲解,如何将这个 Vue 项目转换为网址! 2.1 选择 Vue 项目 如果你的手上有 Vue 项目,可以忽略本小节;如果没有可以从下面的代码仓库中进行下载,同学们可以挑选自己喜欢的 Vue 项目进行打包。 2.1.1 Vue和SpringBoot的前后端分离开发模板 博客:博客介绍源代码:GitEE、GitHub、GitCode 2.1.2 基于 Vue 的大病保险管理系统 博客:博客介绍源代码:GitEE、GitHub、GitCode 2.1.3 基于 Vue 的假日旅社管理系统 博客:博客介绍教学课程:CSDN 学院教学课程源代码:GitEE、GitHub、GitCode 2.1.4 基于 Vue 的医院门诊预约挂号系统 博客:博客介绍源代码:GitEE、GitHub、GitCode 2.1.5 基于 Vue 的资产出入库管理系统 博客:博客介绍源代码:GitEE、GitHub、GitCode 2.1.6 更多... 更多题材的 Vue 系统可在文章底部评论区互动! 2.2 编译 Vue 项目 2.2.1 获取项目源代码 选定待打包的 Vue 项目后,先把项目源代码克隆到本地,克隆命令为 git clone 仓库地址,如下所示。 git clone git@gitee.com:yyzwz/template.git 代码下载完成后,打开项目文件夹,如下图所示。 2.2.2 安装依赖、编译项目 若你的电脑没有配置 node.js 和 Vue 脚手架,或者不知道如何安装 VsCode,可以移步 Vue 环境配置讲解。 使用 VsCode 打开项目的 front 文件夹。 运行 npm i 命令。 安装完成后,界面如下图所示。 接着使用 npm run build 命令,生成编译文件,编译成功后如下图所示。 可以发现在项目根目录多了个 dist 文件夹,如下图所示,这里面就是存放了 Vue 项目的待部署文件。 2.2.3 Nginx 配置 Nginx 和 Tomcat 一样,是一个轻量级的应用服务器,官网下载页面是:Nginx 下载。 同学们可以下载最新稳定版的 Nginx,如下图所示。 下载完成后解压到指定目录,如下图所示。 打开 conf 目录下的 nginx.conf 配置文件,编译为如下所示。 如果你没有域名,可以使用下面的配置 #worker角色的工作进程的个数 设置为CPU逻辑数量的两倍 worker_processes 1; events { #每一个worker进程能并发处理(发起)的最大连接数 worker_connections 2048; } http { #开启高效文件传输模式 sendfile on; #长连接超时时间,单位是秒 keepalive_timeout 65; #用于指定响应客户端的超时时间 send_timeout 30; #允许客户端请求的最大单文件字节数。 client_max_body_size 100m; #缓冲区代理缓冲用户端请求的最大字节数 client_body_buffer_size 128k; #导入外部配置文件 文件扩展名与文件类型映射表 include mime.types; #让浏览器认为响应是普通的文件流,并提示用户下载文件 如 图片 pdf等 default_type application/octet-stream; charset utf-8; tcp_nopush on; gzip on; #压缩最小文件阀值 gzip_min_length 1k; #缓冲区大小 gzip_buffers 4 16k; #http协议版本 gzip_http_version 1.0; #IE版本1-6不支持gzip压缩,关闭 gzip_disable 'MSIE[1-6].'; #压缩级别 gzip_comp_level 6; #需要压缩的文件格式 gzip_types text/css text/javascript application/javascript image/jpeg image/png image/gif; #告知客户端能否缓存 gzip_vary on; #反向代理时使用 gzip_proxied off; #负载均衡 upstream zwz { server 127.0.0.1:8081 weight=1; } server { listen 8080; server_name localhost; # server_name artskyhome.com; client_max_body_size 100m; # 设置解决大json返回不完整问题 proxy_buffers 16 1024k; proxy_buffer_size 1024k; #保留代理之前的真实客户端ip proxy_set_header X-Real-IP $remote_addr; #在多级代理的情况下,记录每次代理之前的客户端真实ip proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; charset utf-8; location / { root html; index index.html index.htm; add_header 'Access-Control-Allow-Origin' '*'; } location /zwz { proxy_pass http://zwz; } error_page 404 /404.html; } } 如果你有域名,并且有 SSL 证书,可以使用如下的配置,其中 1.pem 和 1.key 是 SSL 的证书文件。 #worker角色的工作进程的个数 设置为CPU逻辑数量的两倍 worker_processes 1; events { #每一个worker进程能并发处理(发起)的最大连接数 worker_connections 2048; } http { #开启高效文件传输模式 sendfile on; #长连接超时时间,单位是秒 keepalive_timeout 65; #用于指定响应客户端的超时时间 send_timeout 30; #允许客户端请求的最大单文件字节数。 client_max_body_size 100m; #缓冲区代理缓冲用户端请求的最大字节数 client_body_buffer_size 128k; #导入外部配置文件 文件扩展名与文件类型映射表 include mime.types; #让浏览器认为响应是普通的文件流,并提示用户下载文件 如 图片 pdf等 default_type application/octet-stream; charset utf-8; tcp_nopush on; gzip on; #压缩最小文件阀值 gzip_min_length 1k; #缓冲区大小 gzip_buffers 4 16k; #http协议版本 gzip_http_version 1.0; #IE版本1-6不支持gzip压缩,关闭 gzip_disable 'MSIE[1-6].'; #压缩级别 gzip_comp_level 6; #需要压缩的文件格式 gzip_types text/css text/javascript application/javascript image/jpeg image/png image/gif; #告知客户端能否缓存 gzip_vary on; #反向代理时使用 gzip_proxied off; #负载均衡 upstream zwz { server 127.0.0.1:8081 weight=1; } server { listen 8080 ssl; server_name localhost; # server_name artskyhome.com; client_max_body_size 100m; # 设置解决大json返回不完整问题 proxy_buffers 16 1024k; proxy_buffer_size 1024k; #保留代理之前的真实客户端ip proxy_set_header X-Real-IP $remote_addr; #在多级代理的情况下,记录每次代理之前的客户端真实ip proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ssl_certificate ssl/1.pem; ssl_certificate_key ssl/1.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; charset utf-8; location / { root html; index index.html index.htm; add_header 'Access-Control-Allow-Origin' '*'; } location /zwz { proxy_pass http://zwz; } error_page 404 /404.html; } } 接着将 2.2.2 步骤生成的 dist 文件夹内容复制到 nginx 的 html 目录下,如下图所示。 2.2.4 Nginx 发布 将上一步完整的 nginx 文件夹复制到服务器的硬盘上,如下图所示。 运行 cmd,输入以下命令,如下图所示。 cd 项目目录 start nginx 接着就可以在云服务器上看到部署的 Vue 项目了哦!也就是将 Vue 项目转换为了网址。 如果你没有云服务器,也可以在电脑本地运行,执行以下cmd 命令。 cd C:\java\git\template\nginx start nginx 接着打开 localhost:8080 就可以了,如下图所示。 也就是将 Vue 项目转换为了 localhost:8080 这个网址。 三、总结 本文讲解了如何将一个 Vue 项目打包为桌面客户端,实现像 Excel 一样双击运行,适用于管理较多项目且经常忘记网址的场景。本文还讲解了 Vue 项目从下载依赖、打包和 Nginx 部署的全过程,可以给 Vue 初学者参考学习。
2023年07月