华为云和 Sonatype 联合发布中国官方 Maven 中央仓库镜像

关于 华为云 Maven 仓库镜像

目前,华为云与 Sonatype 联合发布的国内唯一官方 Maven 中央仓,将给广大开发者提供镜像加速服务。它主要体现在:

  • 安全 - 由华为提供企业级的可信代码仓库,避免第三方包来源不明的安全风险

  • 完整 - 作为 Maven 的官方镜像节点,所有数据将实时与主节点同步,确保资源完整

  • 可靠 - 基于华为云高可靠性的能力,确保代码仓库 7*24 小时都可以访问

  • 便捷 - 基于华为云 DevCloud,提供在软件开发过程中一键获取代码仓库的能力

  • 效率 - 基于国内网络环境进行 CDN 加速优化,确保开发人员获得更极致的下载体验

使用方式

  • 打开 maven setting.xml 配置文件在配置文件的 servers 标签内加入以下用户配置信息:
1
2
3
4
5
<server>
<id>huaweicloud</id>
<username>anonymous</username>
<password>devcloud</password>
</server>
  • 在配置文件的 mirrors 标签内加入以下镜像配置信息:
1
2
3
4
5
<mirror>
<id>huaweicloud</id>
<mirrorOf>*</mirrorOf>
<url>https://mirrors.huaweicloud.com/repository/maven/</url>
</mirror>
  • 对比下阿里云的 maven 镜像个人感觉快了不少。
1
2
3
4
5
6
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>aliyun public maven repository</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>

参考资料

Java/MySQL/Maven/Tomcat 安装配置方式

Java 安装

建议安装 Java 8

  1. 下载。Windows/Linux/macOS 系统下载安装对应的安装包。
  2. 环境变量配置。
    • Windows 配置环境变量
      • 计算机=>属性=>高级系统设置=>高级=>环境变量=>系统变量=>新建变量
      • 变量名:JAVA_HOME,变量值:JDK 路径(如:C:\Program Files\Java\jdk1.8.0_181
      • 变量名:CLASSPATH,变量值:.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
      • 在已有 Path 变量的变量值最前增加:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
    • macOS 配置环境变量
      • cd ~ && vim .bash_profile
      • 输入以下内容,再保存,然后输入 source .bash_profile 生效:
      • # JDK 路径
      • JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home
      • PATH=$JAVA_HOME/bin:$PATH:.
      • CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:.
      • export JAVA_HOME
      • export PATH
      • export CLASSPATH
  3. 检验安装是否成功。 打开 cmd ,输入以下代码查询 java 版本:
1
java -version

MySQL 安装

建议安装 MySQL 5.7 及以上版本

  1. 下载。Windows/Linux/macOS 系统下载安装对应的安装包。
  2. 环境变量配置。
    • Windows 配置环境变量
      • 计算机=>属性=>高级系统设置=>高级=>环境变量=>系统变量=>新建变量
      • 变量名:MYSQL_HOME,变量值:JDK 路径(如:C:\Program Files\MySQL\mysql-5.7.29-winx64
      • 在已有 Path 变量的变量值最前增加:%MYSQL_HOME%\bin;

3.安装。 在 MySQL 安装目录下新建 my.ini 的文件,并在将以下内容复制到文件中:

1
2
3
4
5
6
7
[mysqld]
# 设置3306端口
port=3306
# 设置mysql的安装目录
basedir=C:\Program Files\MySQL\mysql-5.7.29-winx64
# 设置mysql数据库的数据的存放目录
datadir=C:\Program Files\MySQL\mysql-5.7.29-winx64\data

打开 cmd ,输入以下代码安装服务

1
mysqld --install

初始化 MySQL,初始化时 root 密码自动设置为空,并会自动创建 data 目录

1
mysqld --initialize-insecure

启动 MySQL 服务

1
net start mysql

设置 root 密码为 123456(因为初始化时 root 密码自动设置为空)

1
mysqladmin -u root password 123456

登录数据库

1
mysql -uroot -p123456

列出所有数据库

1
show databases;
  1. 检验安装是否成功。 打开 cmd ,输入以下代码查询 java 版本:
1
mysql --version

Maven 安装

建议安装 Maven 3.6 及以上版本

  1. 安装。Windows/Linux/macOS 系统下载安装对应的安装包。
  2. 环境变量配置。
    • Windows 配置环境变量
      • 计算机=>属性=>高级系统设置=>高级=>环境变量=>系统变量=>新建变量
      • 变量名:MAVEN,变量值:Maven 路径(如:C:\apache-maven-3.5.4 2
      • 在已有 Path 变量的变量值最前增加:%MAVEN_HOME%\bin;
    • macOS 配置环境变量
      • cd ~ && vim .bash_profile
      • 输入以下内容,再保存,然后输入 source .bash_profile 生效:
      • # Maven 路径
      • export M2_HOME=/Volumes/office/dev/apache-maven-3.5.0
      • export PATH=$PATH:$M2_HOME/bin

Tomcat 安装

建议安装 Tomcat 9 及以上版本

  1. 安装。Windows/Linux/macOS 系统下载安装对应的安装包。

免费的 JetBrains 注册码获取方法及软件破解激活方式

这里,我还是建议大家通过这几种方式来申请免费的注册码:

  • 通过学生证、教师证或者edu邮箱获取;
  • 也可以通过自己的开源项目来进行申请;

具体可以参考官网:https://www.jetbrains.com/idea/buy/#discounts?billing=yearly 下面的注册码,都是群友贡献的免费idea激活码(每一个都亲测可用),在此,分享给大家,不收一毛钱,有人找你要钱,那一定是骗子。 重要:使用注册码前,请先清理你之前的破解配置及相关文件,要么还原重新安装,否则不能成功!!!

新版本

因为 IntelliJ IDEA 2018.1.3 以上的版本需要联网激活,请不要修改 host!

老版本

可修改 hosts,Windows:C:\Windows\System32\drivers\etc\hosts;Linux/Mac:/etc/hosts;

1
2
3
0.0.0.0 account.jetbrains.com
0.0.0.0 www.jetbrains.com
0.0.0.0 www-weighted.jetbrains.com

网上找到注册码

1
Z7BTIL5EYM-eyJsaWNlbnNlSWQiOiJaN0JUSUw1RVlNIiwibGljZW5zZWVOYW1lIjoi5rC45LmF5r+A5rS7IGlkZWEubWVkZW1pbmcuY29tIiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdGlvbiI6IiIsImNoZWNrQ29uY3VycmVudFVzZSI6ZmFsc2UsInByb2R1Y3RzIjpbeyJjb2RlIjoiSUkiLCJwYWlkVXBUbyI6IjIwMjAtMDMtMDIifSx7ImNvZGUiOiJBQyIsInBhaWRVcFRvIjoiMjAyMC0wMy0wMiJ9LHsiY29kZSI6IkRQTiIsInBhaWRVcFRvIjoiMjAyMC0wMy0wMiJ9LHsiY29kZSI6IlBTIiwicGFpZFVwVG8iOiIyMDIwLTAzLTAyIn0seyJjb2RlIjoiR08iLCJwYWlkVXBUbyI6IjIwMjAtMDMtMDIifSx7ImNvZGUiOiJETSIsInBhaWRVcFRvIjoiMjAyMC0wMy0wMiJ9LHsiY29kZSI6IkNMIiwicGFpZFVwVG8iOiIyMDIwLTAzLTAyIn0seyJjb2RlIjoiUlMwIiwicGFpZFVwVG8iOiIyMDIwLTAzLTAyIn0seyJjb2RlIjoiUkMiLCJwYWlkVXBUbyI6IjIwMjAtMDMtMDIifSx7ImNvZGUiOiJSRCIsInBhaWRVcFRvIjoiMjAyMC0wMy0wMiJ9LHsiY29kZSI6IlBDIiwicGFpZFVwVG8iOiIyMDIwLTAzLTAyIn0seyJjb2RlIjoiUk0iLCJwYWlkVXBUbyI6IjIwMjAtMDMtMDIifSx7ImNvZGUiOiJXUyIsInBhaWRVcFRvIjoiMjAyMC0wMy0wMiJ9LHsiY29kZSI6IkRCIiwicGFpZFVwVG8iOiIyMDIwLTAzLTAyIn0seyJjb2RlIjoiREMiLCJwYWlkVXBUbyI6IjIwMjAtMDMtMDIifSx7ImNvZGUiOiJSU1UiLCJwYWlkVXBUbyI6IjIwMjAtMDMtMDIifV0sImhhc2giOiIxNjUyODc3NS8wIiwiZ3JhY2VQZXJpb2REYXlzIjo3LCJhdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlLCJpc0F1dG9Qcm9sb25nYXRlZCI6ZmFsc2V9-dimbrAeIK5F6QYGpDUwb1LWJjLYg5RsXtKnygtNYEH2s/h7sMqgMKeeee8J/qRByi4aLXR/FTdtfYF19Wu4Tye+MA6nLRVlxjhE9XRRhRsNiS1ueXWlDm3ssevRRPuSsdww20KCAhB87gLX86XHC0HMczEp2bIsMRDS4RFOp2vL7hagDWsum/a19HfgANzEzyQuD3FUdXzeT5oPtKq9yW+7mSW/zTLcu9lFASaKJwhrCuVRBnmGqw3OoPo5709BvF0XJtfIulTVrm0xW/HoeF4EuuYS16pMODMNPryGYv0Dyjt2+OaL2BRgRxlPA3pwrLc2QYaEwaNab8JTY3z0qMg==-MIIElTCCAn2gAwIBAgIBCTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE4MTEwMTEyMjk0NloXDTIwMTEwMjEyMjk0NlowaDELMAkGA1UEBhMCQ1oxDjAMBgNVBAgMBU51c2xlMQ8wDQYDVQQHDAZQcmFndWUxGTAXBgNVBAoMEEpldEJyYWlucyBzLnIuby4xHTAbBgNVBAMMFHByb2QzeS1mcm9tLTIwMTgxMTAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcQkq+zdxlR2mmRYBPzGbUNdMN6OaXiXzxIWtMEkrJMO/5oUfQJbLLuMSMK0QHFmaI37WShyxZcfRCidwXjot4zmNBKnlyHodDij/78TmVqFl8nOeD5+07B8VEaIu7c3E1N+e1doC6wht4I4+IEmtsPAdoaj5WCQVQbrI8KeT8M9VcBIWX7fD0fhexfg3ZRt0xqwMcXGNp3DdJHiO0rCdU+Itv7EmtnSVq9jBG1usMSFvMowR25mju2JcPFp1+I4ZI+FqgR8gyG8oiNDyNEoAbsR3lOpI7grUYSvkB/xVy/VoklPCK2h0f0GJxFjnye8NT1PAywoyl7RmiAVRE/EKwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQAF8uc+YJOHHwOFcPzmbjcxNDuGoOUIP+2h1R75Lecswb7ru2LWWSUMtXVKQzChLNPn/72W0k+oI056tgiwuG7M49LXp4zQVlQnFmWU1wwGvVhq5R63Rpjx1zjGUhcXgayu7+9zMUW596Lbomsg8qVve6euqsrFicYkIIuUu4zYPndJwfe0YkS5nY72SHnNdbPhEnN8wcB2Kz+OIG0lih3yz5EqFhld03bGp222ZQCIghCTVL6QBNadGsiN/lWLl4JdR3lJkZzlpFdiHijoVRdWeSWqM4y0t23c92HXKrgppoSV18XMxrWVdoSM3nuMHwxGhFyde05OdDtLpCv+jlWf5REAHHA201pAU6bJSZINyHDUTB+Beo28rRXSwSh3OUIvYwKNVeoBY+KwOJ7WnuTCUq1meE6GkKc4D/cXmgpOyW/1SmBz3XjVIi/zprZ0zf3qH5mkphtg6ksjKgKjmx1cXfZAAX6wcDBNaCL+Ortep1Dh8xDUbqbBVNBL4jbiL3i3xsfNiyJgaZ5sX7i8tmStEpLbPwvHcByuf59qJhV/bZOl8KqJBETCDJcY6O2aqhTUy+9x93ThKs1GKrRPePrWPluud7ttlgtRveit/pcBrnQcXOl1rHq7ByB8CFAxNotRUYL9IF5n3wJOgkPojMy6jetQA5Ogc8Sm7RG6vg1yow==
1
NPXHBQLDBG-eyJsaWNlbnNlSWQiOiJOUFhIQlFMREJHIiwibGljZW5zZWVOYW1lIjoi5rC45LmF5r+A5rS7IGlkZWEubWVkZW1pbmcuY29tIiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdGlvbiI6IiIsImNoZWNrQ29uY3VycmVudFVzZSI6ZmFsc2UsInByb2R1Y3RzIjpbeyJjb2RlIjoiSUkiLCJwYWlkVXBUbyI6IjIwMjAtMDItMjcifSx7ImNvZGUiOiJBQyIsInBhaWRVcFRvIjoiMjAyMC0wMi0yNyJ9LHsiY29kZSI6IkRQTiIsInBhaWRVcFRvIjoiMjAyMC0wMi0yNyJ9LHsiY29kZSI6IlBTIiwicGFpZFVwVG8iOiIyMDIwLTAyLTI3In0seyJjb2RlIjoiR08iLCJwYWlkVXBUbyI6IjIwMjAtMDItMjcifSx7ImNvZGUiOiJETSIsInBhaWRVcFRvIjoiMjAyMC0wMi0yNyJ9LHsiY29kZSI6IkNMIiwicGFpZFVwVG8iOiIyMDIwLTAyLTI3In0seyJjb2RlIjoiUlMwIiwicGFpZFVwVG8iOiIyMDIwLTAyLTI3In0seyJjb2RlIjoiUkMiLCJwYWlkVXBUbyI6IjIwMjAtMDItMjcifSx7ImNvZGUiOiJSRCIsInBhaWRVcFRvIjoiMjAyMC0wMi0yNyJ9LHsiY29kZSI6IlBDIiwicGFpZFVwVG8iOiIyMDIwLTAyLTI3In0seyJjb2RlIjoiUk0iLCJwYWlkVXBUbyI6IjIwMjAtMDItMjcifSx7ImNvZGUiOiJXUyIsInBhaWRVcFRvIjoiMjAyMC0wMi0yNyJ9LHsiY29kZSI6IkRCIiwicGFpZFVwVG8iOiIyMDIwLTAyLTI3In0seyJjb2RlIjoiREMiLCJwYWlkVXBUbyI6IjIwMjAtMDItMjcifSx7ImNvZGUiOiJSU1UiLCJwYWlkVXBUbyI6IjIwMjAtMDItMjcifV0sImhhc2giOiIxNjQ1MjY3Ni8wIiwiZ3JhY2VQZXJpb2REYXlzIjo3LCJhdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlLCJpc0F1dG9Qcm9sb25nYXRlZCI6ZmFsc2V9-EUjFu84N/OsZQiCnYXYpiEkKgzCO78hiGl96RiH2d23cQuGTlpjtoc5mmLo3W3Dy4mO9XSeS/d99VSr6jmWGPMjv5dGBGywWe21Nj17saWN4qZl3/KvUsLFw/HB4Kh53VDvtNdBYq+vt0A8hdxuXKH1APQdjUQC43GXxTksmAQY+vz4zsQmSNkq8aL4SNSMMA6uXSlhaxzbF+fGW+zA5HG82C+LEei9Se3/728qI1jZ76gEM5wC6fmdiR2mVI2b0cpALMxtLtF17ea5K+UsqCwZUleh+QWBSANHOlzJvotfXeFV514Se1kJBGfcNxs4lDi6icsbSM+D0DbmUDcMNfA==-MIIElTCCAn2gAwIBAgIBCTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE4MTEwMTEyMjk0NloXDTIwMTEwMjEyMjk0NlowaDELMAkGA1UEBhMCQ1oxDjAMBgNVBAgMBU51c2xlMQ8wDQYDVQQHDAZQcmFndWUxGTAXBgNVBAoMEEpldEJyYWlucyBzLnIuby4xHTAbBgNVBAMMFHByb2QzeS1mcm9tLTIwMTgxMTAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcQkq+zdxlR2mmRYBPzGbUNdMN6OaXiXzxIWtMEkrJMO/5oUfQJbLLuMSMK0QHFmaI37WShyxZcfRCidwXjot4zmNBKnlyHodDij/78TmVqFl8nOeD5+07B8VEaIu7c3E1N+e1doC6wht4I4+IEmtsPAdoaj5WCQVQbrI8KeT8M9VcBIWX7fD0fhexfg3ZRt0xqwMcXGNp3DdJHiO0rCdU+Itv7EmtnSVq9jBG1usMSFvMowR25mju2JcPFp1+I4ZI+FqgR8gyG8oiNDyNEoAbsR3lOpI7grUYSvkB/xVy/VoklPCK2h0f0GJxFjnye8NT1PAywoyl7RmiAVRE/EKwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQAF8uc+YJOHHwOFcPzmbjcxNDuGoOUIP+2h1R75Lecswb7ru2LWWSUMtXVKQzChLNPn/72W0k+oI056tgiwuG7M49LXp4zQVlQnFmWU1wwGvVhq5R63Rpjx1zjGUhcXgayu7+9zMUW596Lbomsg8qVve6euqsrFicYkIIuUu4zYPndJwfe0YkS5nY72SHnNdbPhEnN8wcB2Kz+OIG0lih3yz5EqFhld03bGp222ZQCIghCTVL6QBNadGsiN/lWLl4JdR3lJkZzlpFdiHijoVRdWeSWqM4y0t23c92HXKrgppoSV18XMxrWVdoSM3nuMHwxGhFyde05OdDtLpCv+jlWf5REAHHA201pAU6bJSZINyHDUTB+Beo28rRXSwSh3OUIvYwKNVeoBY+KwOJ7WnuTCUq1meE6GkKc4D/cXmgpOyW/1SmBz3XjVIi/zprZ0zf3qH5mkphtg6ksjKgKjmx1cXfZAAX6wcDBNaCL+Ortep1Dh8xDUbqbBVNBL4jbiL3i3xsfNiyJgaZ5sX7i8tmStEpLbPwvHcByuf59qJhV/bZOl8KqJBETCDJcY6O2aqhTUy+9x93ThKs1GKrRPePrWPluud7ttlgtRveit/pcBrnQcXOl1rHq7ByB8CFAxNotRUYL9IF5n3wJOgkPojMy6jetQA5Ogc8Sm7RG6vg1yow==
1
7PNLXJPODN-eyJsaWNlbnNlSWQiOiI3UE5MWEpQT0ROIiwibGljZW5zZWVOYW1lIjoi6aOe6LGhIOeggeWGnCIsImFzc2lnbmVlTmFtZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaWNlbnNlUmVzdHJpY3Rpb24iOiIiLCJjaGVja0NvbmN1cnJlbnRVc2UiOmZhbHNlLCJwcm9kdWN0cyI6W3siY29kZSI6IklJIiwiZmFsbGJhY2tEYXRlIjoiMjAyMC0wMS0xNSIsInBhaWRVcFRvIjoiMjAyMS0wMS0xNCJ9LHsiY29kZSI6IkFDIiwiZmFsbGJhY2tEYXRlIjoiMjAyMC0wMS0xNSIsInBhaWRVcFRvIjoiMjAyMS0wMS0xNCJ9LHsiY29kZSI6IkRQTiIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMTUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMTQifSx7ImNvZGUiOiJQUyIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMTUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMTQifSx7ImNvZGUiOiJHTyIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMTUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMTQifSx7ImNvZGUiOiJETSIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMTUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMTQifSx7ImNvZGUiOiJDTCIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMTUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMTQifSx7ImNvZGUiOiJSUzAiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiUkMiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiUkQiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiUEMiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiUk0iLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiV1MiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiREIiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiREMiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTE1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTE0In0seyJjb2RlIjoiUlNVIiwiZmFsbGJhY2tEYXRlIjoiMjAyMC0wMS0xNSIsInBhaWRVcFRvIjoiMjAyMS0wMS0xNCJ9XSwiaGFzaCI6IjE2MjYyNDE0LzAiLCJncmFjZVBlcmlvZERheXMiOjcsImF1dG9Qcm9sb25nYXRlZCI6ZmFsc2UsImlzQXV0b1Byb2xvbmdhdGVkIjpmYWxzZX0=-PPKBrTimCndddUn6boFzGrhkBW8JU7D4lQuuOxKq4rdA4U3IQix9gM+8UYYUaJCQMg8zPmE42QPSkSWneE5VAShaAwhfdu5/D2KbG9jv2uoy8deXu4YWYRHRmn6TdU1/fBhOsbI4EbqYoRDjQ6R+ibYQBanurdcdySH8wDx2kiEBOEbbHJ9ekkGG4YZysbxWVdnFDX3+s+3IanmZKqK/Lih/+XGK5rwp1QGr3+fFX6yAuI5gK78BOajkkEAq6RR9lzvaMDGt7t5wpYxSnEzN9UgkIhdf1zpg/OG1CB4hRsrQU9IG39r2W2IxqHXdipGkPDag+4MTEkwMuofgXFF9NQ==-MIIElTCCAn2gAwIBAgIBCTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE4MTEwMTEyMjk0NloXDTIwMTEwMjEyMjk0NlowaDELMAkGA1UEBhMCQ1oxDjAMBgNVBAgMBU51c2xlMQ8wDQYDVQQHDAZQcmFndWUxGTAXBgNVBAoMEEpldEJyYWlucyBzLnIuby4xHTAbBgNVBAMMFHByb2QzeS1mcm9tLTIwMTgxMTAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcQkq+zdxlR2mmRYBPzGbUNdMN6OaXiXzxIWtMEkrJMO/5oUfQJbLLuMSMK0QHFmaI37WShyxZcfRCidwXjot4zmNBKnlyHodDij/78TmVqFl8nOeD5+07B8VEaIu7c3E1N+e1doC6wht4I4+IEmtsPAdoaj5WCQVQbrI8KeT8M9VcBIWX7fD0fhexfg3ZRt0xqwMcXGNp3DdJHiO0rCdU+Itv7EmtnSVq9jBG1usMSFvMowR25mju2JcPFp1+I4ZI+FqgR8gyG8oiNDyNEoAbsR3lOpI7grUYSvkB/xVy/VoklPCK2h0f0GJxFjnye8NT1PAywoyl7RmiAVRE/EKwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQAF8uc+YJOHHwOFcPzmbjcxNDuGoOUIP+2h1R75Lecswb7ru2LWWSUMtXVKQzChLNPn/72W0k+oI056tgiwuG7M49LXp4zQVlQnFmWU1wwGvVhq5R63Rpjx1zjGUhcXgayu7+9zMUW596Lbomsg8qVve6euqsrFicYkIIuUu4zYPndJwfe0YkS5nY72SHnNdbPhEnN8wcB2Kz+OIG0lih3yz5EqFhld03bGp222ZQCIghCTVL6QBNadGsiN/lWLl4JdR3lJkZzlpFdiHijoVRdWeSWqM4y0t23c92HXKrgppoSV18XMxrWVdoSM3nuMHwxGhFyde05OdDtLpCv+jlWf5REAHHA201pAU6bJSZINyHDUTB+Beo28rRXSwSh3OUIvYwKNVeoBY+KwOJ7WnuTCUq1meE6GkKc4D/cXmgpOyW/1SmBz3XjVIi/zprZ0zf3qH5mkphtg6ksjKgKjmx1cXfZAAX6wcDBNaCL+Ortep1Dh8xDUbqbBVNBL4jbiL3i3xsfNiyJgaZ5sX7i8tmStEpLbPwvHcByuf59qJhV/bZOl8KqJBETCDJcY6O2aqhTUy+9x93ThKs1GKrRPePrWPluud7ttlgtRveit/pcBrnQcXOl1rHq7ByB8CFAxNotRUYL9IF5n3wJOgkPojMy6jetQA5Ogc8Sm7RG6vg1yow==
1
7NYXX5E2OU-eyJsaWNlbnNlSWQiOiI3TllYWDVFMk9VIiwibGljZW5zZWVOYW1lIjoi5qe/5p6XIOWVhuWfjiIsImFzc2lnbmVlTmFtZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaWNlbnNlUmVzdHJpY3Rpb24iOiIiLCJjaGVja0NvbmN1cnJlbnRVc2UiOmZhbHNlLCJwcm9kdWN0cyI6W3siY29kZSI6IklJIiwiZmFsbGJhY2tEYXRlIjoiMjAyMC0wMS0wNSIsInBhaWRVcFRvIjoiMjAyMS0wMS0wNCJ9LHsiY29kZSI6IkFDIiwiZmFsbGJhY2tEYXRlIjoiMjAyMC0wMS0wNSIsInBhaWRVcFRvIjoiMjAyMS0wMS0wNCJ9LHsiY29kZSI6IkRQTiIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMDUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMDQifSx7ImNvZGUiOiJQUyIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMDUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMDQifSx7ImNvZGUiOiJHTyIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMDUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMDQifSx7ImNvZGUiOiJETSIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMDUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMDQifSx7ImNvZGUiOiJDTCIsImZhbGxiYWNrRGF0ZSI6IjIwMjAtMDEtMDUiLCJwYWlkVXBUbyI6IjIwMjEtMDEtMDQifSx7ImNvZGUiOiJSUzAiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTA0In0seyJjb2RlIjoiUkMiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTA0In0seyJjb2RlIjoiUkQiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTA0In0seyJjb2RlIjoiUEMiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTA0In0seyJjb2RlIjoiUk0iLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTA0In0seyJjb2RlIjoiV1MiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTA0In0seyJjb2RlIjoiREIiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTA0In0seyJjb2RlIjoiREMiLCJmYWxsYmFja0RhdGUiOiIyMDIwLTAxLTA1IiwicGFpZFVwVG8iOiIyMDIxLTAxLTA0In0seyJjb2RlIjoiUlNVIiwiZmFsbGJhY2tEYXRlIjoiMjAyMC0wMS0wNSIsInBhaWRVcFRvIjoiMjAyMS0wMS0wNCJ9XSwiaGFzaCI6IjE2MDk0OTY4LzAiLCJncmFjZVBlcmlvZERheXMiOjcsImF1dG9Qcm9sb25nYXRlZCI6ZmFsc2UsImlzQXV0b1Byb2xvbmdhdGVkIjpmYWxzZX0=-MqE/Rk6NYDhRo5AKqUGrvFc1MErGZz0v6PERjwOUFg7bg7Cv4N8wxmx1msUXdEZVbeNJyZB2YmhRuzFz82lFQlxJV9hhawyuwVl93pKOvj6udHeP1cOtPSL3GcePvnMk61QNwggu9g7zvjC3q24pzP1S6UHQTTBNXjV3qzosfyjgzVEsJeuu4wCy+cdiXE65wjULvFjlYRAzU725Mb7j5v2pcD7bfTmDVgkQ2VRqCeTpUo90N5wT0LwF79ideE04eezlbna/5uih/adBbWhChcVL2cWUf0TH0jKPblwhLG1IzCiX8vPIRy2NfpSURMIwRxg6X7yd1EE955rIa19pxA==-MIIElTCCAn2gAwIBAgIBCTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE4MTEwMTEyMjk0NloXDTIwMTEwMjEyMjk0NlowaDELMAkGA1UEBhMCQ1oxDjAMBgNVBAgMBU51c2xlMQ8wDQYDVQQHDAZQcmFndWUxGTAXBgNVBAoMEEpldEJyYWlucyBzLnIuby4xHTAbBgNVBAMMFHByb2QzeS1mcm9tLTIwMTgxMTAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcQkq+zdxlR2mmRYBPzGbUNdMN6OaXiXzxIWtMEkrJMO/5oUfQJbLLuMSMK0QHFmaI37WShyxZcfRCidwXjot4zmNBKnlyHodDij/78TmVqFl8nOeD5+07B8VEaIu7c3E1N+e1doC6wht4I4+IEmtsPAdoaj5WCQVQbrI8KeT8M9VcBIWX7fD0fhexfg3ZRt0xqwMcXGNp3DdJHiO0rCdU+Itv7EmtnSVq9jBG1usMSFvMowR25mju2JcPFp1+I4ZI+FqgR8gyG8oiNDyNEoAbsR3lOpI7grUYSvkB/xVy/VoklPCK2h0f0GJxFjnye8NT1PAywoyl7RmiAVRE/EKwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQAF8uc+YJOHHwOFcPzmbjcxNDuGoOUIP+2h1R75Lecswb7ru2LWWSUMtXVKQzChLNPn/72W0k+oI056tgiwuG7M49LXp4zQVlQnFmWU1wwGvVhq5R63Rpjx1zjGUhcXgayu7+9zMUW596Lbomsg8qVve6euqsrFicYkIIuUu4zYPndJwfe0YkS5nY72SHnNdbPhEnN8wcB2Kz+OIG0lih3yz5EqFhld03bGp222ZQCIghCTVL6QBNadGsiN/lWLl4JdR3lJkZzlpFdiHijoVRdWeSWqM4y0t23c92HXKrgppoSV18XMxrWVdoSM3nuMHwxGhFyde05OdDtLpCv+jlWf5REAHHA201pAU6bJSZINyHDUTB+Beo28rRXSwSh3OUIvYwKNVeoBY+KwOJ7WnuTCUq1meE6GkKc4D/cXmgpOyW/1SmBz3XjVIi/zprZ0zf3qH5mkphtg6ksjKgKjmx1cXfZAAX6wcDBNaCL+Ortep1Dh8xDUbqbBVNBL4jbiL3i3xsfNiyJgaZ5sX7i8tmStEpLbPwvHcByuf59qJhV/bZOl8KqJBETCDJcY6O2aqhTUy+9x93ThKs1GKrRPePrWPluud7ttlgtRveit/pcBrnQcXOl1rHq7ByB8CFAxNotRUYL9IF5n3wJOgkPojMy6jetQA5Ogc8Sm7RG6vg1yow==
1
88IY3BPJSM-eyJsaWNlbnNlSWQiOiI4OElZM0JQSlNNIiwibGljZW5zZWVOYW1lIjoiamV0YiBzdG8iLCJhc3NpZ25lZU5hbWUiOiIiLCJhc3NpZ25lZUVtYWlsIjoiIiwibGljZW5zZVJlc3RyaWN0aW9uIjoiIiwiY2hlY2tDb25jdXJyZW50VXNlIjpmYWxzZSwicHJvZHVjdHMiOlt7ImNvZGUiOiJJSSIsInBhaWRVcFRvIjoiMjAyMC0wMi0wOCJ9LHsiY29kZSI6IkFDIiwicGFpZFVwVG8iOiIyMDIwLTAyLTA4In0seyJjb2RlIjoiRFBOIiwicGFpZFVwVG8iOiIyMDIwLTAyLTA4In0seyJjb2RlIjoiUFMiLCJwYWlkVXBUbyI6IjIwMjAtMDItMDgifSx7ImNvZGUiOiJHTyIsInBhaWRVcFRvIjoiMjAyMC0wMi0wOCJ9LHsiY29kZSI6IkRNIiwicGFpZFVwVG8iOiIyMDIwLTAyLTA4In0seyJjb2RlIjoiQ0wiLCJwYWlkVXBUbyI6IjIwMjAtMDItMDgifSx7ImNvZGUiOiJSUzAiLCJwYWlkVXBUbyI6IjIwMjAtMDItMDgifSx7ImNvZGUiOiJSQyIsInBhaWRVcFRvIjoiMjAyMC0wMi0wOCJ9LHsiY29kZSI6IlJEIiwicGFpZFVwVG8iOiIyMDIwLTAyLTA4In0seyJjb2RlIjoiUEMiLCJwYWlkVXBUbyI6IjIwMjAtMDItMDgifSx7ImNvZGUiOiJSTSIsInBhaWRVcFRvIjoiMjAyMC0wMi0wOCJ9LHsiY29kZSI6IldTIiwicGFpZFVwVG8iOiIyMDIwLTAyLTA4In0seyJjb2RlIjoiREIiLCJwYWlkVXBUbyI6IjIwMjAtMDItMDgifSx7ImNvZGUiOiJEQyIsInBhaWRVcFRvIjoiMjAyMC0wMi0wOCJ9LHsiY29kZSI6IlJTVSIsInBhaWRVcFRvIjoiMjAyMC0wMi0wOCJ9XSwiaGFzaCI6IjE2MTcxODM0LzAiLCJncmFjZVBlcmlvZERheXMiOjcsImF1dG9Qcm9sb25nYXRlZCI6ZmFsc2UsImlzQXV0b1Byb2xvbmdhdGVkIjpmYWxzZX0=-I0nPZMTtOm+Wsf5FYHtTpFkKtGAuVMXzcCf68dr5xKu0tv482VpMFwqa23dFuQx0kH5JCKzZNYxM/C5Qd2mHyuQtUalgcbDmLe8iD/bETUv49rF3eALn8MSjOc2VnfrZgFbPJby7hW26mLv0gD4hKkLSpXP2TBZyHfsYN8JEYt6mJP9BRBJ/FoiRNn7+SBqZpe1CkpGmh0+YA1uy75/eGMLRz1pbSrVdISWfJFs64+rZQKdOF6y1BuuEh2eobYNNGrUGkrMWmZixuyrInjMBVZWgktRTeZpdStkmQzXqxRz4gIK66ng70FgtCQZ8DMoIQhIOf/+dFxV9x2NkJom2+A==-MIIElTCCAn2gAwIBAgIBCTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE4MTEwMTEyMjk0NloXDTIwMTEwMjEyMjk0NlowaDELMAkGA1UEBhMCQ1oxDjAMBgNVBAgMBU51c2xlMQ8wDQYDVQQHDAZQcmFndWUxGTAXBgNVBAoMEEpldEJyYWlucyBzLnIuby4xHTAbBgNVBAMMFHByb2QzeS1mcm9tLTIwMTgxMTAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcQkq+zdxlR2mmRYBPzGbUNdMN6OaXiXzxIWtMEkrJMO/5oUfQJbLLuMSMK0QHFmaI37WShyxZcfRCidwXjot4zmNBKnlyHodDij/78TmVqFl8nOeD5+07B8VEaIu7c3E1N+e1doC6wht4I4+IEmtsPAdoaj5WCQVQbrI8KeT8M9VcBIWX7fD0fhexfg3ZRt0xqwMcXGNp3DdJHiO0rCdU+Itv7EmtnSVq9jBG1usMSFvMowR25mju2JcPFp1+I4ZI+FqgR8gyG8oiNDyNEoAbsR3lOpI7grUYSvkB/xVy/VoklPCK2h0f0GJxFjnye8NT1PAywoyl7RmiAVRE/EKwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQAF8uc+YJOHHwOFcPzmbjcxNDuGoOUIP+2h1R75Lecswb7ru2LWWSUMtXVKQzChLNPn/72W0k+oI056tgiwuG7M49LXp4zQVlQnFmWU1wwGvVhq5R63Rpjx1zjGUhcXgayu7+9zMUW596Lbomsg8qVve6euqsrFicYkIIuUu4zYPndJwfe0YkS5nY72SHnNdbPhEnN8wcB2Kz+OIG0lih3yz5EqFhld03bGp222ZQCIghCTVL6QBNadGsiN/lWLl4JdR3lJkZzlpFdiHijoVRdWeSWqM4y0t23c92HXKrgppoSV18XMxrWVdoSM3nuMHwxGhFyde05OdDtLpCv+jlWf5REAHHA201pAU6bJSZINyHDUTB+Beo28rRXSwSh3OUIvYwKNVeoBY+KwOJ7WnuTCUq1meE6GkKc4D/cXmgpOyW/1SmBz3XjVIi/zprZ0zf3qH5mkphtg6ksjKgKjmx1cXfZAAX6wcDBNaCL+Ortep1Dh8xDUbqbBVNBL4jbiL3i3xsfNiyJgaZ5sX7i8tmStEpLbPwvHcByuf59qJhV/bZOl8KqJBETCDJcY6O2aqhTUy+9x93ThKs1GKrRPePrWPluud7ttlgtRveit/pcBrnQcXOl1rHq7ByB8CFAxNotRUYL9IF5n3wJOgkPojMy6jetQA5Ogc8Sm7RG6vg1yow==

最后,发这份注册码,真的顶着不小的压力,望大家低调用就好!!!

常见问题

1、certificate used to sign the license is not signed by jetbrains root certificate 解决办法: https://youtrack.jetbrains.com/issue/WEB-38698

注入 Filter 解决 Spring Boot 2.x 前后端分离开发 CORS 跨域问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.gioov.nimrodbackend.common;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
* @author godcheese [[email protected]]
* @date 2019-04-03
*/
@Configuration
public class CorsConfiguration {

@Bean
public FilterRegistrationBean<CorsFilter> corsConfig() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
org.springframework.web.cors.CorsConfiguration corsConfiguration = new org.springframework.web.cors.CorsConfiguration();
// 是否发送 Cookie
corsConfiguration.setAllowCredentials(true);
// 允许跨域访问的源
corsConfiguration.addAllowedOrigin(org.springframework.web.cors.CorsConfiguration.ALL);
// 允许头部设置
corsConfiguration.addAllowedHeader(org.springframework.web.cors.CorsConfiguration.ALL);
// 允许请求方法
corsConfiguration.addAllowedMethod(org.springframework.web.cors.CorsConfiguration.ALL);
// 预检间隔时间,单位:秒
corsConfiguration.setMaxAge(1800L);
// 允许跨域访问的路径
source.registerCorsConfiguration("/**", corsConfiguration);
// 注入 Filter
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new CorsFilter(source));
bean.setName("corsFilter");
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}

}

Java 实现无限层级树形结构遍历部门

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/**
* 部门实体类
*/
public class Department {

public Department(Integer id, String name, Integer parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
}

private Integer id;
private String name;

/**
* 上级部门 id
*/
private Integer parentId;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getParentId() {
return parentId;
}

public void setParentId(Integer parentId) {
this.parentId = parentId;
}
}

/**
* 树形节点实体类
*/
public class TreeNode {

public TreeNode(Integer id, String name, Integer parentId, List<TreeNode> children) {
this.id = id;
this.name = name;
this.parentId = parentId;
this.children = children;
}

private Integer id;
private String name;

/**
* 父级节点 id
*/
private Integer parentId;

/**
* 子级节点
*/
private List<TreeNode> children;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getParentId() {
return parentId;
}

public void setParentId(Integer parentId) {
this.parentId = parentId;
}

public List<TreeNode> getChildren() {
return children;
}

public void setChildren(List<TreeNode> children) {
this.children = children;
}
}

/**
* 循环遍历出子节点
* @param parentId
* @param treeNodeList
* @return
*/
public List<TreeNode> forEachChildrenTreeNode(int parentId, List<TreeNode> treeNodeList) {
List<TreeNode> children = new ArrayList<>(0);
for(TreeNode treeNode : treeNodeList) {
if(treeNode.getParentId() != null && treeNode.getParentId().equals(parentId)) {
children.add(treeNode);
}
}

for(TreeNode child : children) {
List<TreeNode> childChildren = forEachChildrenTreeNode(child.getId(), treeNodeList);
if(childChildren == null) {
childChildren = new ArrayList<>(0);
}
child.setChildren(childChildren);
}

if(children.size() == 0) {
return null;
}
return children;
}

/**
* 测试代码
*/
public void testApp() {

List<Department> departmentList = new ArrayList<>(6);
departmentList.add(new Department(1,"测试集团公司1", null));
departmentList.add(new Department(2,"测试分公司1", 1));
departmentList.add(new Department(3,"测试分公司2", 1));
departmentList.add(new Department(4,"测试子部门1", 3));
departmentList.add(new Department(5,"测试项目室1", 4));
departmentList.add(new Department(6,"测试项目组1", 5));
departmentList.add(new Department(7,"测试项目室2", 4));
departmentList.add(new Department(8,"测试子部门2", 3));
departmentList.add(new Department(9,"测试分公司3", 1));
departmentList.add(new Department(10,"测试集团公司2", null));

/**
* 将部门数据转成树形节点
*/
List<TreeNode> treeNodeList = new ArrayList<>(10);
for(Department department : departmentList) {
treeNodeList.add(new TreeNode(department.getId(), department.getName(), department.getParentId(), new ArrayList<>()));
}

/**
* 最终输出的树形结构类结果数据
*/
List<TreeNode> treeNodeResultList = new ArrayList<>(0);

/**
* 将 parentId 为空的顶层节点首先写入结果数据
*/
for(TreeNode treeNode : treeNodeList) {
if(treeNode.getParentId() == null) {
treeNodeResultList.add(treeNode);
}
}

/**
* 循环所有在结果数据中的顶层节点,并将子级节点装载进顶层节点的 children 属性
*/
for(TreeNode treeNode : treeNodeResultList) {
treeNode.setChildren(forEachChildrenTreeNode(treeNode.getId(), treeNodeList));
}

/**
* 将结果数据以 JSON 格式输出
*/
ObjectMapper objectMapper = new ObjectMapper();
try {
System.out.println(objectMapper.writeValueAsString(treeNodeResultList));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}

输出结果如下图:

Spring Boot 2.x properties 配置文件中引用 Maven pom.xml 中的属性值

配置方法

在 Maven pom.xml 文件 properties 中加入:

1
<resource.delimiter>${}</resource.delimiter>

然后在 Maven pom.xml 文件 build-resources 中加入:

1
2
3
4
5
6
7
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include> <!-- 你要替换的 properties 文件,如 application.properties、application-dev.properties,我的是匹配所有 .properties 扩展结尾的文件 -->
</includes>
</resource>

项目 src/main/resources 下的 application.properties 文件属性配置中包含一项 Maven pom.xml 的属性值: 最后打包看效果:

1
maven clean package

值替换成功,问题解决。

Java 数据字典设计之加载字典到内存(二)

本文以 Spring Boot 应用、MySQL 数据库为例。 新建 DictionaryService.java、DictionaryServiceImpl.java,新增借口方法:addDictionaryToServletContext,用于调用加载字典到内存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
* @author godcheese
*/
@Service
public class DictionaryServiceImpl implements DictionaryService {

@Autowired
private DictionaryMapper dictionaryMapper;

@Autowired
private WebApplicationContext webApplicationContext;

private static final Logger LOGGER = LoggerFactory.getLogger(DictionaryServiceImpl.class);

@Override
public void addDictionaryToServletContext() {
ServletContext servletContext = webApplicationContext.getServletContext();
if (servletContext != null) {

List<DictionaryEntity> dictionaryEntityList = dictionaryMapper.listAll();
for (DictionaryEntity dictionaryEntity : dictionaryEntityList) {
servletContext.setAttribute(dictionaryEntity.getKey().toUpperCase() + "." + dictionaryEntity.getValueSlug().toUpperCase(), dictionaryEntity.getValue());
}

Map<String, List<DictionaryEntity>> dictionaryEntityMap = new HashMap<>(6);
for (DictionaryEntity dictionaryEntity : dictionaryEntityList) {
String key = dictionaryEntity.getKey().toUpperCase();
if (dictionaryEntityMap.containsKey(key)) {
List<DictionaryEntity> dictionaryEntityList1 = dictionaryEntityMap.get(key);
if (!dictionaryEntityList1.contains(dictionaryEntity)) {
dictionaryEntityList1.add(dictionaryEntity);
dictionaryEntityMap.put(key, dictionaryEntityList1);
}
} else {
List<DictionaryEntity> dictionaryEntityList2 = new ArrayList<>(1);
dictionaryEntityList2.add(dictionaryEntity);
dictionaryEntityMap.put(key, dictionaryEntityList2);
}
}

for (Map.Entry entry : dictionaryEntityMap.entrySet()) {
servletContext.setAttribute((String) entry.getKey(), entry.getValue());
}

}
}
}

新建 ApplicationStartupRunner.java,用于程序启动时进行的操作,此处调用 DictionaryService 的 addDictionaryToServletContext 方法,执行将字典加载到内存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* @author godcheese
* @date 2018/2/22 16:19
*/
@Component
@Order
public class ApplicationStartupRunner implements CommandLineRunner {

private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationStartupRunner.class);

@Autowired
private DictionaryService dictionaryService;

@Override
public void run(String... strings) throws Exception {

// 首次启动加载数据字典到 ServletContext 内存
dictionaryService.addDictionaryToServletContext();

}
}

Java 数据字典设计之数据库设计(一)

本文以 Spring Boot 应用、MySQL 数据库为例。

数据字典表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
-- 数据字典表
DROP TABLE
IF EXISTS `dictionary`;

CREATE TABLE `dictionary` (
`id` BIGINT(20) UNSIGNED AUTO_INCREMENT COMMENT 'id',
`key` VARCHAR(255) NOT NULL COMMENT '字典键',
`key_name` VARCHAR(255) NOT NULL COMMENT '字典键名',
`value_name` VARCHAR(255) NOT NULL COMMENT '字典值名',
`value_slug` VARCHAR(255) NOT NULL COMMENT '字典值别名',
`value` TEXT COMMENT '字典值',
`editable` TINYINT(1) UNSIGNED DEFAULT NULL COMMENT '是否可编辑(0=不可编辑,1=可编辑,默认=1)',
`dictionary_category_id` BIGINT(20) UNSIGNED NOT NULL COMMENT '字典分类 id',
`sort` BIGINT(20) UNSIGNED DEFAULT 0 COMMENT '排序',
`remark` VARCHAR(255) DEFAULT '' COMMENT '备注',
`gmt_modified` DATETIME DEFAULT NOW() COMMENT '更新时间',
`gmt_created` DATETIME DEFAULT NOW() COMMENT '创建时间',
PRIMARY KEY (`id`)
)
ENGINE = INNODB
DEFAULT CHARACTER
SET = utf8mb4
COLLATE = utf8mb4_general_ci
AUTO_INCREMENT = 1
ROW_FORMAT = DYNAMIC
COMMENT = '数据字典表';

数据字典分类表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-- 数据字典分类表
DROP TABLE
IF EXISTS `dictionary_category`;

CREATE TABLE `dictionary_category` (
`id` BIGINT(20) UNSIGNED AUTO_INCREMENT COMMENT 'id',
`name` VARCHAR(255) NOT NULL COMMENT '分类名称',
`parent_id` BIGINT(20) UNSIGNED DEFAULT NULL COMMENT '父级分类 id',
`sort` BIGINT(20) DEFAULT 0 COMMENT '排序',
`remark` VARCHAR(255) DEFAULT '' COMMENT '备注',
`gmt_modified` DATETIME DEFAULT NOW() COMMENT '更新时间',
`gmt_created` DATETIME DEFAULT NOW() COMMENT '创建时间',
PRIMARY KEY (`id`)
)
ENGINE = INNODB
DEFAULT CHARACTER
SET = utf8mb4
COLLATE = utf8mb4_general_ci
AUTO_INCREMENT = 1
ROW_FORMAT = DYNAMIC
COMMENT = '数据字典分类表';

数据字典表对应的实体类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package com.gioov.spiny.system.entity;

import java.io.Serializable;
import java.util.Date;

/**
* @author godcheese
* @date 2018/4/23 20:44
*/
public class DictionaryEntity implements Serializable {

private static final long serialVersionUID = -4000696333938261490L;

/**
* id
*/
private Long id;

/**
* 字典键
*/
private String key;

/**
* 字典键名
*/
private String keyName;

/**
* 字典值名
*/
private String valueName;

/**
* 字典值别名
*/
private String valueSlug;

/**
* 字典值
*/
private String value;

/**
* 是否可编辑
*/
private Integer editable;

/**
* 字典分类 id
*/
private Long dictionaryCategoryId;

/**
* 排序
*/
private Long sort;

/**
* 备注
*/
private String remark;

/**
* 更新时间
*/
private Date gmtModified;

/**
* 创建时间
*/
private Date gmtCreated;


public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public String getKeyName() {
return keyName;
}

public void setKeyName(String keyName) {
this.keyName = keyName;
}

public String getValueName() {
return valueName;
}

public void setValueName(String valueName) {
this.valueName = valueName;
}

public String getValueSlug() {
return valueSlug;
}

public void setValueSlug(String valueSlug) {
this.valueSlug = valueSlug;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

public Integer getEditable() {
return editable;
}

public void setEditable(Integer editable) {
this.editable = editable;
}

public Long getDictionaryCategoryId() {
return dictionaryCategoryId;
}

public void setDictionaryCategoryId(Long dictionaryCategoryId) {
this.dictionaryCategoryId = dictionaryCategoryId;
}

public Long getSort() {
return sort;
}

public void setSort(Long sort) {
this.sort = sort;
}

public String getRemark() {
return remark;
}

public void setRemark(String remark) {
this.remark = remark;
}

public Date getGmtModified() {
return gmtModified;
}

public void setGmtModified(Date gmtModified) {
this.gmtModified = gmtModified;
}

public Date getGmtCreated() {
return gmtCreated;
}

public void setGmtCreated(Date gmtCreated) {
this.gmtCreated = gmtCreated;
}

}

数据字典分类表对应的实体类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package com.gioov.spiny.system.entity;

import java.io.Serializable;
import java.util.Date;

/**
* @author godcheese
* @date 2018/5/23
*/
public class DictionaryCategoryEntity implements Serializable {

private static final long serialVersionUID = -5867777461580679038L;

private Long id;

/**
* 分类名称
*/
private String name;

/**
* 父级分类 id
*/
private Long parentId;

/**
* 排序
*/
private Long sort;

/**
* 备注
*/
private String remark;

/**
* 更新时间
*/
private Date gmtModified;

/**
* 创建时间
*/
private Date gmtCreated;


public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Long getParentId() {
return parentId;
}

public void setParentId(Long parentId) {
this.parentId = parentId;
}

public Long getSort() {
return sort;
}

public void setSort(Long sort) {
this.sort = sort;
}

public String getRemark() {
return remark;
}

public void setRemark(String remark) {
this.remark = remark;
}

public Date getGmtModified() {
return gmtModified;
}

public void setGmtModified(Date gmtModified) {
this.gmtModified = gmtModified;
}

public Date getGmtCreated() {
return gmtCreated;
}

public void setGmtCreated(Date gmtCreated) {
this.gmtCreated = gmtCreated;
}

}

CentOS 7 安装 Oracle 11gR2 数据库

系统:CentOS 7 软件选择:最小安装

配置系统环境

切换成 root 用户

1
su root

下载工具

1
2
3
4
5
6
# wget 
# 解压工具,用于解压Oracle安装文件
# unzip
# 网络工具,用语查看本机网络情况,如:netstat
# net-tools
yum install -y wget unzip net-tools

使用 Oracle 提供的环境配置工具,这个工具会调整内核参数,建立一些必要的Linux用户和组

1
2
wget http://public-yum.oracle.com/public-yum-ol7.repo -O /etc/yum.repos.d/public-yum-ol7.repo
wget http://public-yum.oracle.com/RPM-GPG-KEY-oracle-ol7 -O /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle

1
yum install -y oracle-rdbms-server-11gR2-preinstall

以上工具安装完成后建议备份存放修改系统后日志和原本的内核配置备份这个目录

1
/var/log/oracle-rdbms-server-11gR2-preinstall

备份好后,执行以下命令加载内核参数(sysctl –p 等效)

1
sysctl –f

创建一些目录,配置oracle系统配置文件和授权

1
2
3
4
5
cat >> /etc/oraInst.loc <<EOF
inventory_loc=/home/oracle/ora11g/oraInventory
inst_group=oinstall
EOF
chmod 664 /etc/oraInst.loc

创建 oracle 安装目录和授权

1
2
3
4
5
mkdir -p /u01/app/
mkdir /u01/tmp
chown -R oracle:oinstall /u01/app/
chmod -R 775 /u01/app/
chmod a+wr /u01/tmp

设置oracle用户密码(123456),oracle是安装工具自己创建的,参考我之前讲的

1
passwd oracle

配置用户环境和上传 Oracle 压缩包

切换成 oracle 用户

1
su oracle

为 oracle 用户添加一些必要的环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
cat >> /home/oracle/.bash_profile <<EOF
TMP=/u01/tmp
TMPDIR=/u01/tmp
export TMP TMPDIR

ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1
ORACLE_SID=orcl
PATH=/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin
export ORACLE_BASE ORACLE_SID ORACLE_HOME PATH
PATH=$PATH:$ORACLE_HOME/bin
export PATH
EOF

生效用户环境变量

1
cd ~ && source .bash_profile

使用 Xftp 的上传 linux.x64_11gR2_database_1of2.zip、linux.x64_11gR2_database_2of2.zip 2 个压缩包到 /home/oracle/

解压2个压缩包,解压后文件会在 /home/oracle/database/

1
2
unzip linux.x64_11gR2_database_1of2.zip 
unzip linux.x64_11gR2_database_2of2.zip

解压完成,如图:

配置 Oracle 数据库安装响应文件(db_install.rsp)

切换成 oracle 用户

1
su oracle

备份 /home/oracle/database/response 下文件到 /home/oracle/rsp/

1
cp -r /home/oracle/database/response /home/oracle/rsp

配置安装响应文件 /home/oracle/rsp/db_install.rsp文件,这里建议先用 Xftp 下载到本地配置参数,再上传,db_install.rsp文件配置示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
oracle.install.responseFileVersion=/oracle/install/rspfmt_dbinstall_response_schema_v11_2_0
# INSTALL_DB_AND_CONFIG 安装并自动配置数据库实例和监听,建议首次安装用这个,不然配置另外两个文件,新建实例和监听
oracle.install.option=INSTALL_DB_AND_CONFIG
ORACLE_HOSTNAME=localhost
UNIX_GROUP_NAME=oinstall
INVENTORY_LOCATION=/home/oracle/ora11g/oraInventory
SELECTED_LANGUAGES=zh_CN,en
ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1
ORACLE_BASE=/u01/app/oracle
oracle.install.db.InstallEdition=EE
oracle.install.db.isCustomInstall=true
oracle.install.db.customComponents=oracle.server:11.2.0.1.0,oracle.sysman.ccr:10.2.7.0.0,oracle.xdk:11.2.0.1.0,oracle.rdbms.oci:11.2.0.1.0,oracle.network:11.2.0.1.0,oracle.network.listener:11.2.0.1.0,oracle.rdbms:11.2.0.1.0,oracle.options:11.2.0.1.0,oracle.rdbms.partitioning:11.2.0.1.0,oracle.oraolap:11.2.0.1.0,oracle.rdbms.dm:11.2.0.1.0,oracle.rdbms.dv:11.2.0.1.0,orcle.rdbms.lbac:11.2.0.1.0,oracle.rdbms.rat:11.2.0.1.0
oracle.install.db.DBA_GROUP=dba
oracle.install.db.OPER_GROUP=oinstall
oracle.install.db.config.starterdb.type=GENERAL_PURPOSE
# 这个是服务名
oracle.install.db.config.starterdb.globalDBName=orcl.lan
# 实例 sid
oracle.install.db.config.starterdb.SID=orcl
oracle.install.db.config.starterdb.characterSet=AL32UTF8
oracle.install.db.config.starterdb.memoryOption=true
# 最小 256M 我是学习就选择最小了
oracle.install.db.config.starterdb.memoryLimit=256
# 是否安装学习的scott和hr
oracle.install.db.config.starterdb.installExampleSchemas=false
oracle.install.db.config.starterdb.enableSecuritySettings=true
# 全局密码设置成 123456 (安装时会提示密码简单问题,可忽略)
oracle.install.db.config.starterdb.password.ALL=123456
oracle.install.db.config.starterdb.control=DB_CONTROL
oracle.install.db.config.starterdb.dbcontrol.enableEmailNotification=false
oracle.install.db.config.starterdb.automatedBackup.enable=false
oracle.install.db.config.starterdb.storageType=FILE_SYSTEM_STORAGE
oracle.install.db.config.starterdb.fileSystemStorage.dataLocation=/u01/app/oracle/oradata
DECLINE_SECURITY_UPDATES=true

修改完成保存并上传到 /home/oracle /rsp ,覆盖 db_install.rsp。

静默安装 Oracle 数据库

切换成 oracle 用户

1
su oracle

安装,会出现密码不规范的警告,可忽略

1
/home/oracle/database/runInstaller -silent -ignorePrereq -responseFile /home/oracle/rsp/db_install.rsp

带有图形界面的系统可能会出现如下报错,无报错可忽略:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 [[email protected] rsp]$ Exception in thread "main" java.lang.NoClassDefFoundError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at java.awt.Toolkit$2.run(Toolkit.java:821)
at java.security.AccessController.doPrivileged(Native Method)
at java.awt.Toolkit.getDefaultToolkit(Toolkit.java:804)
at javax.swing.UIManager.initialize(UIManager.java:1262)
at javax.swing.UIManager.maybeInitialize(UIManager.java:1245)
at javax.swing.UIManager.getUI(UIManager.java:851)
at javax.swing.JPanel.updateUI(JPanel.java:104)
at javax.swing.JPanel.<init>(JPanel.java:64)
at javax.swing.JPanel.<init>(JPanel.java:87)
at javax.swing.JPanel.<init>(JPanel.java:95)
at oracle.sysman.oii.oiif.oiifo.OiifoOCMUI.<init>(OiifoOCMUI.java:125)
at oracle.sysman.oii.oiif.oiifo.OiifoOCMInterfaceManager.<init>(OiifoOCMInterfaceManager.java:79)
at oracle.sysman.oii.oiif.oiifo.OiifoOCMInterfaceManager.getInstance(OiifoOCMInterfaceManager.java:124)
at oracle.install.ivw.db.driver.DBInstaller.run(DBInstaller.java:123)
at oracle.install.commons.util.Application.startup(Application.java:869)
at oracle.install.commons.flow.FlowApplication.startup(FlowApplication.java:164)
at oracle.install.commons.flow.FlowApplication.startup(FlowApplication.java:181)
at oracle.install.commons.base.driver.common.Installer.startup(Installer.java:265)
at oracle.install.ivw.db.driver.DBInstaller.startup(DBInstaller.java:114)
at oracle.install.ivw.db.driver.DBInstaller.main(DBInstaller.java:132)

出现如上报错是因为系统中设置了DISPLAY环境变量,执行以下命令即可:

1
unset DISPLAY

再次执行 oracle 数据库安装命令

1
/home/oracle/database/runInstaller -silent -ignorePrereq -responseFile /home/oracle/rsp/db_install.rsp

查看安装过程建议另开一个shell 执行如下命令查看

1
tail -f /home/oracle/ora11g/oraInventory/logs/ installActions2018-06-29_09-57-41AM.log

安装完成。

切换成 root 用户

1
su root

执行以下脚本

1
/u01/app/oracle/product/11.2.0/dbhome_1/root.sh

切换成 oracle 用户

1
su oracle

sqlplus 登录

1
sqlplus / as sysdba

查看状态

1
select status from v$instance;

配置防火墙(可忽略)

切换成 root 用户

1
su root

查看 1521 数据库远程连接端口

1
netstat -angrep 1521

1521 端口监听中。

防火墙  添加 1521 端口永久开放公共连接规则

1
firewall-cmd --zone=public --add-port=1521/tcp --permanent

重新加载防火墙规则

1
firewall-cmd --reload

数据库/实例启动及关闭

切换成 root 用户

1
su root

修改 oracle 服务启动配置,使启动数据库服务也会同时启动实例

1
vi /etc/oratab

1
Orcl:/u01/app/oracle/product/11.2.0/dbhome_1:N

改成

1
Orcl:/u01/app/oracle/product/11.2.0/dbhome_1:Y

保存后,重启数据库使配置生效:

关闭数据库

1
dbshut $ORACLE_HOME

启动数据库

1
dbstart $ORACLE_HOME

远程连接 oracle 数据库

SID 连接:

1
sqlplus sys/[email protected]:1521/orcl as sysdba

1
conn sys/[email protected]:1521/orcl as sysdba

服务名连接:

1
sqlplus sys/[email protected]:1521/orcl.lan as sysdba

1
conn sys/[email protected]:1521/orcl.lan as sysdba