From 99c691426e02f71a29ddcd49139fc5fc28e9026a Mon Sep 17 00:00:00 2001 From: "yong.teng" Date: Fri, 8 Nov 2024 16:50:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=203.0.x=20=E6=89=8B?= =?UTF-8?q?=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/installation.md | 2 +- src/docs/module.md | 6 +- src/index.jsx | 2 +- src/manual/3.0/aop/index.md | 21 ++ src/manual/3.0/beans/index.md | 106 ++++++++ src/manual/3.0/core/builder.md | 109 ++++++++ src/manual/3.0/core/codec.md | 89 +++++++ src/manual/3.0/core/collect.md | 232 ++++++++++++++++++ src/manual/3.0/core/context.md | 81 ++++++ src/manual/3.0/core/converter.md | 132 ++++++++++ src/manual/3.0/core/datetime.md | 31 +++ src/manual/3.0/core/exception.md | 24 ++ src/manual/3.0/core/id.md | 69 ++++++ src/manual/3.0/core/index.md | 86 +++++++ src/manual/3.0/core/math.md | 54 ++++ src/manual/3.0/core/other.md | 118 +++++++++ src/manual/3.0/core/serializer.md | 31 +++ src/manual/3.0/core/utils.md | 203 +++++++++++++++ src/manual/3.0/core/validator.md | 204 +++++++++++++++ src/manual/3.0/dao/index.md | 57 +++++ src/manual/3.0/dao/mongodb.md | 17 ++ src/manual/3.0/dao/mybatis.md | 78 ++++++ src/manual/3.0/geoip/index.md | 98 ++++++++ src/manual/3.0/git/index.md | 18 ++ src/manual/3.0/httpclient/configuration.md | 30 +++ .../3.0/httpclient/connectionmanager.md | 17 ++ src/manual/3.0/httpclient/index.md | 126 ++++++++++ src/manual/3.0/httpclient/method.md | 117 +++++++++ src/manual/3.0/httpclient/response.md | 31 +++ src/manual/3.0/index.md | 25 ++ src/manual/3.0/io/index.md | 115 +++++++++ src/manual/3.0/jdbc/index.md | 24 ++ src/manual/3.0/json/index.md | 37 +++ src/manual/3.0/lang/index.md | 21 ++ src/manual/3.0/net/index.md | 35 +++ src/manual/3.0/redis/datasource.md | 75 ++++++ src/manual/3.0/redis/index.md | 49 ++++ src/manual/3.0/redis/method.md | 44 ++++ src/manual/3.0/thesaurus/index.md | 35 +++ src/manual/3.0/velocity/index.md | 23 ++ src/manual/3.0/web/annotation.md | 20 ++ src/manual/3.0/web/filter.md | 21 ++ src/manual/3.0/web/index.md | 23 ++ src/manual/3.0/web/restful.md | 38 +++ src/manual/3.0/web/utils.md | 42 ++++ src/manual/SUMMARY.md | 66 +++++ src/manual/overview.md | 1 + 47 files changed, 2878 insertions(+), 5 deletions(-) create mode 100644 src/manual/3.0/aop/index.md create mode 100644 src/manual/3.0/beans/index.md create mode 100644 src/manual/3.0/core/builder.md create mode 100644 src/manual/3.0/core/codec.md create mode 100644 src/manual/3.0/core/collect.md create mode 100644 src/manual/3.0/core/context.md create mode 100644 src/manual/3.0/core/converter.md create mode 100644 src/manual/3.0/core/datetime.md create mode 100644 src/manual/3.0/core/exception.md create mode 100644 src/manual/3.0/core/id.md create mode 100644 src/manual/3.0/core/index.md create mode 100644 src/manual/3.0/core/math.md create mode 100644 src/manual/3.0/core/other.md create mode 100644 src/manual/3.0/core/serializer.md create mode 100644 src/manual/3.0/core/utils.md create mode 100644 src/manual/3.0/core/validator.md create mode 100644 src/manual/3.0/dao/index.md create mode 100644 src/manual/3.0/dao/mongodb.md create mode 100644 src/manual/3.0/dao/mybatis.md create mode 100644 src/manual/3.0/geoip/index.md create mode 100644 src/manual/3.0/git/index.md create mode 100644 src/manual/3.0/httpclient/configuration.md create mode 100644 src/manual/3.0/httpclient/connectionmanager.md create mode 100644 src/manual/3.0/httpclient/index.md create mode 100644 src/manual/3.0/httpclient/method.md create mode 100644 src/manual/3.0/httpclient/response.md create mode 100644 src/manual/3.0/index.md create mode 100644 src/manual/3.0/io/index.md create mode 100644 src/manual/3.0/jdbc/index.md create mode 100644 src/manual/3.0/json/index.md create mode 100644 src/manual/3.0/lang/index.md create mode 100644 src/manual/3.0/net/index.md create mode 100644 src/manual/3.0/redis/datasource.md create mode 100644 src/manual/3.0/redis/index.md create mode 100644 src/manual/3.0/redis/method.md create mode 100644 src/manual/3.0/thesaurus/index.md create mode 100644 src/manual/3.0/velocity/index.md create mode 100644 src/manual/3.0/web/annotation.md create mode 100644 src/manual/3.0/web/filter.md create mode 100644 src/manual/3.0/web/index.md create mode 100644 src/manual/3.0/web/restful.md create mode 100644 src/manual/3.0/web/utils.md diff --git a/src/docs/installation.md b/src/docs/installation.md index ce5e6ab1..e6412ad6 100644 --- a/src/docs/installation.md +++ b/src/docs/installation.md @@ -3,7 +3,7 @@ ### Maven 中央仓库搜索 * [https://mvnrepository.com/search?q=com.buession](https://mvnrepository.com/search?q=com.buession) -* [https://search.maven.org/search?q=g:com.buession](https://search.maven.org/search?q=g:com.buession) +* [https://central.sonatype.com/search?q=g:com.buession](https://central.sonatype.com/search?q=g:com.buession) ### 手动编译 ```shell diff --git a/src/docs/module.md b/src/docs/module.md index 21efb946..299fc3b7 100644 --- a/src/docs/module.md +++ b/src/docs/module.md @@ -21,9 +21,6 @@ * ID 生成器 * Manager 层注解 -### buession-cron -* 对 quartz 的二次封装 - ### buession-dao * 对 mybatis、spring-data-mongo 常用方法(如:根据条件获取单条记录、根据主键获取单条记录、分页、根据条件删除数据、根据主键删除数据)进行了二次封装 * 从代码层面上支持数据库一主多从实现读写分离,insert、update、delete 操作主库,select 操作从库 @@ -31,6 +28,9 @@ ### buession-geoip * 对 com.maxmind.geoip2:geoip2 进行二次封装,实现支持根据 IP 地址获取所属 ISP、所属国家、所属城市等等信息 +### buession-git +* 项目中 Git 信息解析 + ### buession-httpclient * 对 apache httpcomponents、okhttp3 进行封装,屏蔽了 apache httpcomponents 和 okhttp3 的不同技术细节 * 屏蔽了对 post form、post json 等等的技术细节 diff --git a/src/index.jsx b/src/index.jsx index 496a66e5..f100ca3c 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -5,7 +5,7 @@ banner: btns: - { name: '开 始', href: '/docs/quickstart.html', primary: true } - { name: 'Github >', href: 'https://github.com/buession/buessionframework' } - caption: '当前版本: v2.3.2' + caption: '当前版本: v3.0.0' features: - { name: '优雅', desc: '经过精雕细琢,我们带给大家一个精心设计的、标准的、高内聚低耦合的通用类库' } - { name: '灵活', desc: '非重复造车轮,我们是整合市面上开源的类库,以标准的接口暴露给上层用户,用户可替换或自行封装同类组件。在此基础上,封装了大量的常用的类库。' } diff --git a/src/manual/3.0/aop/index.md b/src/manual/3.0/aop/index.md new file mode 100644 index 00000000..a9fb2601 --- /dev/null +++ b/src/manual/3.0/aop/index.md @@ -0,0 +1,21 @@ +# buession-aop 参考手册 + + +AOP 封装,方便实现自定义注解 + + +--- + + +### 安装 + +```xml + + com.buession + buession-aop + x.x.x + +``` + + +### [API 参考手册>>](https://javadoc.io/doc/com.buession/buession-aop/3.0.0/index.html) \ No newline at end of file diff --git a/src/manual/3.0/beans/index.md b/src/manual/3.0/beans/index.md new file mode 100644 index 00000000..c7a212b3 --- /dev/null +++ b/src/manual/3.0/beans/index.md @@ -0,0 +1,106 @@ +# buession-beans 参考手册 + + +该类库提供了基于 commons-beanutils 和 cglib(spring-core 包中,名称空间:org.springframework.cglib.beans) 的 bean 工具的二次封装。包括了属性拷贝和属性映射,以及对象属性转换为 Map。 + + +--- + + +### 安装 + +```xml + + com.buession + buession-beans + x.x.x + +``` + + +### 属性拷贝 + +使用此方法,可以实现两个对象之间的属性拷贝,该方式基于 BeanCopier 实现属性的拷贝。如果 source 对象是 Map 接口的实现,则会将 Map 的 key 和 target 的属性做映射,实现同名拷贝。 + +```java +import com.buession.beans.BeanUtils; + +BeanUtils.copyProperties(target, source) +``` + +* 注:该方式只会对同类型的属性进行拷贝。即假设,source 中有数据类型为 int 名称为 id 的属性,target 中有数据类型为 long 名称为 id 的属性,是不会将 source 属性 id 的值拷贝到 target 的 id 属性上。 + + +我们可以指定 Converter 实现自定义规则进行属性拷贝。该方式的缺点是:BeanCopier 只使用 Converter 定义的规则去拷贝属性,所以在 convert 方法中要考虑所有的属性 + +```java +import com.buession.beans.BeanUtils; +import org.springframework.cglib.core.Converter; + +BeanUtils.copyProperties(target, source, new Converter() { + + @Override + public Object convert(Object sourceFieldValue, Class targetFieldType, Object targetSetter){ + if(sourceFieldValue instanceof Short || sourceFieldValue instanceof Integer){ + if(targetFieldType.isAssignableFrom(Long.class) || targetFieldType.isAssignableFrom(long.class)){ + return sourceFieldValue; + } + }else if(sourceFieldValue.getClass().isAssignableFrom(targetFieldType)){ + return sourceFieldValue; + } + + return null; + } + +}); +``` + +### 属性映射 + +使用此方法,可以实现两个对象之间的属性拷贝,该方式基于 BeanCopier 实现属性的拷贝。如果 source 对象是 Map 接口的实现,则会将 Map 的 key 转换为驼峰格式后和 target 的属性做映射,实现拷贝,这是 populate 和 copyProperties 的唯一区别。 + +```java +import com.buession.beans.BeanUtils; + +BeanUtils.populate(target, source) +``` + +* 注:该方式只会对同类型的属性进行拷贝。即假设,source 中有数据类型为 int 名称为 id 的属性,target 中有数据类型为 long 名称为 id 的属性,是不会将 source 属性 id 的值拷贝到 target 的 id 属性上。 + + +我们可以指定 Converter 实现自定义规则进行属性拷贝。该方式的缺点是:BeanCopier 只使用 Converter 定义的规则去拷贝属性,所以在 convert 方法中要考虑所有的属性 + +```java +import com.buession.beans.BeanUtils; +import org.springframework.cglib.core.Converter; + +BeanUtils.populate(target, source, new Converter() { + + @Override + public Object convert(Object sourceFieldValue, Class targetFieldType, Object targetSetter){ + if(sourceFieldValue instanceof Short || sourceFieldValue instanceof Integer){ + if(targetFieldType.isAssignableFrom(Long.class) || targetFieldType.isAssignableFrom(long.class)){ + return sourceFieldValue; + } + }else if(sourceFieldValue.getClass().isAssignableFrom(targetFieldType)){ + return sourceFieldValue; + } + + return null; + } + +}); +``` + +### Bean 转换为 Map + +使用此方法,可以实现将一个 bean 对象转换为 Map,bean 的属性作为 Map 的 Key + +```java +import com.buession.beans.BeanUtils; + +Map result = BeanUtils.toMap(bean) +``` + + +### [API 参考手册>>](https://javadoc.io/doc/com.buession/buession-beans/3.0.0/index.html) \ No newline at end of file diff --git a/src/manual/3.0/core/builder.md b/src/manual/3.0/core/builder.md new file mode 100644 index 00000000..3d59774b --- /dev/null +++ b/src/manual/3.0/core/builder.md @@ -0,0 +1,109 @@ +# buession-core 参考手册 + + +## 构建器 + + +Map、集合的便捷式构建,减少您的代码行数。 + + +您需要往 Map、List 中添加元素的传统写法是: + +```java +import java.util.ArrayList; +import java.util.List; +import java.util.HashMap; +import java.util.Map; + +List list = new ArrayList<>(); +list.add("A"); +list.add("B"); +list.add("C"); + +Map map = new HashMap<>(); +map.put("a", "A"); +map.put("b", "B"); +map.put("c", "C"); +``` + +而当您使用 buession framework 可以这么写: + +```java +import com.buession.core.builder.ListBuilder; +import com.buession.core.builder.MapBuilder; +import java.util.List; +import java.util.Map; + +List list = ListBuilder.create().add("A").add("B").add("C").build(); + +Map map = MapBuilder.create().put("a", "A").put("b", "B").put("c", "C"); +``` + +此时的 List、Map 的实现类是 java.util.ArrayList、java.util.HashMap;您可以通过 create 指定其实现类。 + +```java +import com.buession.core.builder.ListBuilder; +import com.buession.core.builder.MapBuilder; +import java.util.List; +import java.util.LinkedList; +import java.util.Map; +import java.util.LinkedHashMap; + +List list = ListBuilder.create(LinkedList.class).add("A").add("B").add("C").build(); + +Map map = MapBuilder.create(LinkedHashMap.class).put("a", "A").put("b", "B").put("c", "C"); +``` + +* 注:实现类必须为 public,且必须有无参数的访问权限为 public 的构造函数 + + +当您有 value 为 null 时,不添加到 List 时,传统写法: + +```java +import java.util.ArrayList; +import java.util.List; + +String value = null; +List list = new ArrayList<>(); + +if(value != null){ + list.add(value); +} +``` + +而当您使用 buession framework 可以这么写: + +```java +import com.buession.core.builder.ListBuilder; +import java.util.List; + +String value = null; +List list = ListBuilder.create().addIfPresent(value).build(); +``` + +Map、Set、Queue 同理。 + + +### 便捷方法 + + +| 方法 | 说明 | +| ---- | ---- | +| List ListBuilder.epmty() | 创建空的 V 类型的 List 对象 | +| List ListBuilder.of() | 创建空的 V 类型的 List 对象 | +| List ListBuilder.of(V value) | 创建仅有一个元素的 V 类型的 List 对象 | +| Queue QueueBuilder.epmty() | 创建空的 V 类型的 Queue 对象 | +| Queue QueueBuilder.of() | 创建空的 V 类型的 Queue 对象 | +| Queue QueueBuilder.of(V value) | 创建仅有一个元素的 V 类型的 Queue 对象 | +| Set SetBuilder.epmty() | 创建空的 V 类型的 Set 对象 | +| Set SetBuilder.of() | 创建空的 V 类型的 Set 对象 | +| Set SetBuilder.of(V value) | 创建仅有一个元素的 V 类型的 Set 对象 | +| Map MapBuilder.epmty() | 创建空的 Key 为 K 类型,值为 V 类型的 Map 对象 | +| Map MapBuilder.of() | 创建空的 Key 为 K 类型,值为 V 类型的 Map 对象 | +| Map MapBuilder.of(V value) | 创建仅有一个元素的 Key 为 K 类型,值为 V 类型的 Map 对象 | + + +empty 与 jdk Collections.emptyList()、Collections.emptySet()、Collections.emptyMap() 的本质区别是返回的 List 实例不同,该方法创建的 List、Set、Map 实例是允许对 List、Set、Map 做操作,而 jdk Collections 创建的 List、Set、Map 则是不允许的。两个 of 方法均同理。 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-core/3.0.0/com/buession/core/builder/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/core/codec.md b/src/manual/3.0/core/codec.md new file mode 100644 index 00000000..e5404dc8 --- /dev/null +++ b/src/manual/3.0/core/codec.md @@ -0,0 +1,89 @@ +# buession-core 参考手册 + + +## 编码器 + + +目前,仅包含消息构建器,您可以通过注解 @Message 将您环境中的错误码、错误消息的配置注入到 MessageObject 类型的属性中。 + + +我们在当前现代应用中,通常会在业务上定义业务错误信息。且我们返回给前端的可能是更模糊或通用的、人为可读性更强的错误信息,而且可能两种不同原因引起的错误,但是我们在返回给前端时的错误信息是一模一样的,这时我们就需要更精确的标识来定义错误,通常为错误码。 + +此时,我们在应用中,通常会定义错误码和错误信息的映射关系。我们可用的方法大致是,第一代码里面写死;第二,定义错误枚举或者常量。无论哪种方式的都与代码高度耦合,可读性和可维护性都差。 + +此时此刻,您可以通过 buession framework 的注解 @Message 来简化和解耦您的错误信息配置和代码。在传统 springmvc 应用中,您可以通过 `context:property-placeholder` 或者 `util:properties` 标签将错误信息 properties 配置文件加载到当前应用环境中。 + +```properties +USER_NOT_FOUND.code = 10404 +USER_NOT_FOUND.message = 用户不存在 + +USER_LOGIN_FAILURE.code = 10405 +USER_LOGIN_FAILURE.message = 登录失败 +``` + +```xml + + + +``` + + +```java +import com.buession.core.codec.Message; +import com.buession.core.codec.MessageObject; + +public UserServiceImpl implements UserService { + + @Message("USER_NOT_FOUND") + private MessageObject userNotFound; + + @Override + public User update(User user) throws Exception{ + User dbUser = get(user.getId()); + + if(dbUser == null){ + throw new Exception(userNotFound.getMessage() + "(code: " + userNotFound.getCode() + ")"); + // 用户不存在(code: 10404) + } + + } + +} +``` + + +您可以自定义错误代码和错误消息的 key,默认分别为:code、message。此时您需要在注解 `@Message` 上显示指定错误代码和错误消息的 key。 + +```properties +USER_NOT_FOUND.errorCode = 10404 +USER_NOT_FOUND.errorMessage = 用户不存在 + +USER_LOGIN_FAILURE.errorCode = 10405 +USER_LOGIN_FAILURE.errorMessage = 登录失败 +``` + +```java +import com.buession.core.codec.Message; +import com.buession.core.codec.MessageObject; + +public UserServiceImpl implements UserService { + + @Message(value = "USER_NOT_FOUND", code = "errorCode", message = "errorMessage") + private MessageObject userNotFound; + + @Override + public User update(User user) throws Exception{ + User dbUser = get(user.getId()); + + if(dbUser == null){ + throw new Exception(userNotFound.getMessage() + "(code: " + userNotFound.getCode() + ")"); + // 用户不存在(code: 10404) + } + + } + +} +``` + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-core/3.0.0/com/buession/core/codec/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/core/collect.md b/src/manual/3.0/core/collect.md new file mode 100644 index 00000000..ab67ac62 --- /dev/null +++ b/src/manual/3.0/core/collect.md @@ -0,0 +1,232 @@ +# buession-core 参考手册 + + +## 收集器 + +数组、Map、集合的工具类 + + +### 数组 + +数组工具类 `Arrays` 继承自 `org.apache.commons.lang3.ArrayUtils` 封装了元素是否存在检测、元素索引位置获取、拼接成字符串、转换为 `List`、`Set` 以及字符串类型的数组、数组合并、数组元素操作等方法。 + + +检测数组 array 中是否存在元素 element: + +```java +import com.buession.core.collect.Arrays; + +boolean result = Arrays.contains(array, element); +``` + + +返回元素 element 在数组 array 中第一次出现的位置的索引,不存在返回 -1: + +```java +import com.buession.core.collect.Arrays; + +int result = Arrays.indexOf(array, element); +``` + + +返回元素 element 在数组 array 中最后一次出现的位置的索引,不存在返回 -1: + +```java +import com.buession.core.collect.Arrays; + +int result = Arrays.lastIndexOf(array, element); +``` + + +将字符串拼接会字符串: + +```java +import com.buession.core.collect.Arrays; + +int[] array = {1, 2, 3}; +String result = Arrays.toString(array); +// 1, 2, 3 +``` + +可以通过参数 `glue` 指定连接符,默认为:`", "` + +```java +import com.buession.core.collect.Arrays; + +int[] array = {1, 2, 3}; +String glue = "-"; +String result = Arrays.toString(array, glue); +// 1-2-3 +``` + + +可以通过方法 toList、toSet 转换为 List 和 Set: + +```java +import com.buession.core.collect.Arrays; +import java.util.List; +import java.util.Set; + +int[] array = {1, 2, 3}; +List list = Arrays.toList(array); +Set set = Arrays.toSet(array); +``` + + +将数组转换为字符串类型的数组: + +```java +import com.buession.core.collect.Arrays; + +int[] array = {1, 2, 3}; +String[] result = Arrays.toStringArray(array); +``` + + +将数组进行合并: + +```java +import com.buession.core.collect.Arrays; + +String[] result = Arrays.toStringArray(array1, array2, array3); +``` + + +对数组元素进行操作: + +```java +import com.buession.core.collect.Arrays; + +String[] array = {"A", "B", "C"}; +String[] result = Arrays.map(array, String.class, fn); +``` + +第二个参数为数组元素类型,第三个参数为 `java.util.function.Function` 的实现 + + +### Lists + +List 工具类 `Lists` 实现了将元素拼接成字符串、转换为 Set 操作。 + + +将字符串拼接会字符串: + +```java +import com.buession.core.collect.Lists; +import com.buession.core.builder.ListBuilder; + +List list = ListBuilder.create().add(1).add(2).add(3).build(); +String result = Lists.toString(list); +// 1, 2, 3 +``` + +可以通过参数 `glue` 指定连接符,默认为:`", "` + +```java +import com.buession.core.collect.Lists; +import com.buession.core.builder.ListBuilder; + +List list = ListBuilder.create().add(1).add(2).add(3).build(); +String glue = "-"; +String result = Lists.toString(list); +// 1-2-3 +``` + + +可以通过方法 toSet 将 List 转换为 Set: + +```java +import com.buession.core.collect.Lists; +import com.buession.core.builder.ListBuilder; +import java.util.List; +import java.util.Set; + +List list = ListBuilder.create().add(1).add(2).add(3).build(); +Set set = Lists.toSet(list); +``` + + +### Sets + +Sett 工具类 `Sets` 实现了将元素拼接成字符串、转换为 List 操作。 + + +将字符串拼接会字符串: + +```java +import com.buession.core.collect.Sets; +import com.buession.core.builder.SetBuilder; + +Set set = SetBuilder.create().add(1).add(2).add(3).build(); +String result = Sets.toString(set); +// 1, 2, 3 +``` + +可以通过参数 `glue` 指定连接符,默认为:`", "` + +```java +import com.buession.core.collect.Sets; +import com.buession.core.builder.SetBuilder; + +Set set = SetBuilder.create().add(1).add(2).add(3).build(); +String glue = "-"; +String result = Sets.toString(list); +// 1-2-3 +``` + + +可以通过方法 toList 将 Set 转换为 List: + +```java +import com.buession.core.collect.Lists; +import com.buession.core.builder.ListBuilder; +import java.util.List; +import java.util.Set; + +Set set = SetBuilder.create().add(1).add(2).add(3).build(); +List list = Sets.toList(set); +``` + + +### Maps + +Map 工具类 `Maps` 实现了对 key 和 value 进行操作,实现了将 value 转换为 List 和 Set。 + + +对 Map 进行操作: + +```java +import com.buession.core.collect.Maps; +import java.util.Map; +import java.util.HashMap; + +Map maps = new HashMap<>(); +Map result = Maps.map(maps, (key)->key, (value)->value == null ? null : value.toString()); +``` + +第二个、第三参数为 `java.util.function.Function` 的实现 + + +可以通过方法 toList 将 Map 的 value 转换为 List: + +```java +import com.buession.core.collect.Maps; +import com.buession.core.builder.ListBuilder; +import java.util.List; + +List list = Maps.toList(maps); +``` + + +可以通过方法 toSet 将 Map 的 value 转换为 Set: + +```java +import com.buession.core.collect.Maps; +import com.buession.core.builder.ListBuilder; +import java.util.Set; + +Set set = Maps.toSet(maps); +``` + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-core/3.0.0/com/buession/core/collect/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/core/context.md b/src/manual/3.0/core/context.md new file mode 100644 index 00000000..b98cf25d --- /dev/null +++ b/src/manual/3.0/core/context.md @@ -0,0 +1,81 @@ +# buession-core 参考手册 + + +## 上下文 + +注解 `com.buession.core.context.stereotype.Manager` 用于在分层应用中,标记当前类是一个 manager 类。类似于 `org.springframework.stereotype.Service` 加上该注解会将当前类自动注入到 spring 容器中,用法和 `@Service` 一样。 + +在多层应用架构中 Manager 层通常为:通用业务处理层,处于 Dao 层之上,Service 层之下。主要特征如下: +* 逻辑少 +* 与 Dao 层进行交互,多个 Dao 层的复用 +* Service 通用底层逻辑的下沉,如:缓存方案、中间件通用处理、以及对第三方平台封装的层 + +```java +import com.buession.core.context.stereotype.Manager; +import org.springframework.stereotype.Service; + +public interface UserManager { + + User getByPrimary(int id); + +} + +@Manager +public class UserManagerImpl implements UserManager { + + @Autowired + private UserDao userDao; + + @Autowired + private UserProfileDao userProfileDao; + + @Autowired + private RedisTemplate redisTemplate; + + + @Override + public User getByPrimary(int id){ + User user = redisTemplate.hGetObject("user", Integer.toString(id), User.class); + + if(user == null){ + user = userDao.getByPrimary(id); + if(user != null){ + user.setProfile(userProfileDao.getByUserId(id)); + redisTemplate.hSet("user", Integer.toString(id), user); + }else{ + throw new RuntimeException("用户不存在"); + } + } + + return user; + } + +} + +public interface UserService { + + User getByPrimary(int id); + +} + +@Service +public class UserServiceImpl implements UserService { + + @Autowired + private UserManager userManager; + + + @Override + public User getByPrimary(int id){ + User user = userManager.getByPrimary(id); + + ... + + return user; + } + +} +``` + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-core/3.0.0/com/buession/core/context/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/core/converter.md b/src/manual/3.0/core/converter.md new file mode 100644 index 00000000..b166c914 --- /dev/null +++ b/src/manual/3.0/core/converter.md @@ -0,0 +1,132 @@ +# buession-core 参考手册 + + +## 构建器 + + +数据转化器,基于 mapstruct 的 POJO 类映射接口定义。定义了常用的数据转化器。 + +接口定义: + +```java +@FunctionalInterface +public interface Converter { + + T convert(final S source); + +} +``` + +将类似为 S 的对象转换为类型为 T 的对象。 + + +### 内置转换器 + + +| 转换器 | 说明 | +| ---- | ---- | +| ArrayConverter | 将 S 类型的数组转换为 T 类型的数组 | +| EnumConverter> | 枚举转换器,将字符串转换为枚举 E | +| BinaryEnumConverter> | 枚举转换器,将 byte 数组转换为枚举 E | +| BooleanStatusConverter | 将布尔值转换为 `com.buession.lang.Status` | +| StatusBooleanConverter | 将 `com.buession.lang.Status` 转换为布尔值 | +| PredicateStatusConverter | 通过 `java.util.function.Predicate` 对某种数据类型的数据进行判断结果转换为 `com.buession.lang.Status` | +| ListConverter | 将 S 类型的 List 对象转换为 T 类型的 List 对象 | +| SetConverter | 将 S 类型的 Set 对象转换为 T 类型的 Set 对象 | +| MapConverter | 将 Key 为 SK 类型、值为 SV 类型的 Map 对象转换为 Key 为 TK 类型、值为 TV 类型的 Map | + +将 key 为 Integer 类型,value 为 Object 类型的 Map 转换成 key 为 String 类型,value 为 String 类型的 Map 对象 + +```java +import com.buession.core.converter.MapConverter; +import java.util.Map; + +Map source; +Map target; +MapConverter converter = new MapConverter<>(); + +target = converter.convert(source); +``` + +将字符串转换为枚举 + +```java +import com.buession.core.converter.EnumConverter; +import com.buession.lang.Gender; + +Gender target; +EnumConverter converter = new EnumConverter<>(Gender.class); + +target = converter.convert("FEMALE"); +// Gender.FEMALE + +target = converter.convert("F"); +// null +``` + + +### POJO 类映射 + +我们通过 `com.buession.core.converter.mapper.Mapper` 接口约定了,基于 [mapstruct](https://mapstruct.org/) POJO 类的映射接口规范。关于 mapstruct 的更多文章,可通过搜索引擎自行搜索。 + +```java +public interface Mapper { + + /** + * 将源对象映射到目标对象 + * + * @param object + * 源对象 + * + * @return 目标对象实例 + */ + T mapping(S object); + + /** + * 将源对象数组映射到目标对象数组 + * + * @param object + * 源对象数组 + * + * @return 目标对象实例数组 + */ + T[] mapping(S[] object); + + /** + * 将源 list 对象映射到目标 list 对象 + * + * @param object + * 源 list 对象 + * + * @return 目标对象 list 实例 + */ + List mapping(List object); + + /** + * 将源 set 对象映射到目标 set 对象 + * + * @param object + * 源 set 对象 + * + * @return 目标对象 set 实例 + */ + Set mapping(Set object); + +} +``` + +我们还可以使用工具类 `com.buession.core.converter.mapper.PropertyMapper` 将值从提供的源映射到目标,此方法来拷贝并简单修改于:`springboot` 中的 `org.springframework.boot.context.properties.PropertyMapper`,和原生 `springboot` 中的用法一样。 + +```java +import com.buession.core.converter.mapper.PropertyMapper; + +User source = new User(); +User target = new User(); + +PropertyMapper propertyMapper = PropertyMapper.get().alwaysApplyingWhenNonNull(); +propertyMapper.form(source::getId).to(target:setId) +// null +``` + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-core/3.0.0/com/buession/core/converter/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/core/datetime.md b/src/manual/3.0/core/datetime.md new file mode 100644 index 00000000..77e2aae1 --- /dev/null +++ b/src/manual/3.0/core/datetime.md @@ -0,0 +1,31 @@ +# buession-core 参考手册 + + +## 日期时间 + + +日期、时间工具。目前,仅有少量的 API,参考 PHP 中的日期时间函数而来。 + +获取当前 Unix 时间戳(秒): + +```java +import com.buession.core.datetime.DateTime; + +DateTime.unixtime(); +``` + +该方法我们在实际业务中经常用到。 + +以 "msec sec" 的格式返回当前 Unix 时间戳和微秒数: + +```java +import com.buession.core.datetime.DateTime; + +DateTime.microtime(); +// 1657171717 948000 +``` + +该方法参考 PHP 的 microtime 函数而来。 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-core/3.0.0/com/buession/core/datetime/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/core/exception.md b/src/manual/3.0/core/exception.md new file mode 100644 index 00000000..5d072a44 --- /dev/null +++ b/src/manual/3.0/core/exception.md @@ -0,0 +1,24 @@ +# buession-core 参考手册 + + +## 异常 + + +通用异常的定义。 + + +| 异常 | 说明 | +| ---- | ---- | +| AccessException | 拒绝访问异常 | +| ClassInstantiationException | 类实例化异常 | +| ConversionException | 数据类型转换异常 | +| DataAlreadyExistException | 数据已存在异常 | +| DataNotFoundException | 数据不存在或未找到异常 | +| InsteadException | 类方法废弃后,需要使用其它类库方法来替代 | +| NestedRuntimeException | 嵌套运行时异常 | +| OperationException | 运算异常 | +| PresentException | -- | +| SerializationException | 序列化异常 | + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-core/3.0.0/com/buession/core/exception/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/core/id.md b/src/manual/3.0/core/id.md new file mode 100644 index 00000000..49f0f4a6 --- /dev/null +++ b/src/manual/3.0/core/id.md @@ -0,0 +1,69 @@ +# buession-core 参考手册 + + +## ID 生成器 + + +基于 UUID、jnanoid ID、雪花算法等等的 ID 生成器。 + +您可以通过 buession framework 提供的 ID 生成器,生成唯一 ID。 + + +接口规范。 + +```java +public interface IdGenerator { + + /** + * 获取下一个 ID + * + * @return ID + */ + T nextId(); + +} +``` + + +### ID 生成器 + + +| 生成器 | 说明 | +| ---- | ---- | +| AtomicSimpleIdGenerator | 基于 AtomicLong 递增的,简单 ID 生成器,基于 UUID 生成,将 UUID 结果中的 "-" 过滤掉 | +| AtomicUUIDIdGenerator | 基于 AtomicLong 递增的,UUID ID 生成器 | +| NanoIDIdGenerator | jnanoid ID 生成器,可通过构造函数指定字符范围、长度 | +| RandomDigitIdGenerator | 随机数 ID 生成器,返回指定范围内的随机数,默认为 1L ~ Long.MAX_VALUE,可通过构造函数指定 | +| RandomIdGenerator | 随机字符 ID 生成器,可通过构造函数指定生成长度,默认 16 位 | +| SimpleIdGenerator | 简单 ID 生成器,基于 UUID 生成,将 UUID 结果中的 "-" 过滤掉 | +| SnowflakeIdGenerator | 雪花算法 ID 生成器,此处不解决时钟回拨的问题,您可以通过构造函数指定开始时间、数据中心 ID、数据中心 ID 所占的位数等等值 | +| UUIDIdGenerator | UUID ID 生成器 | + +```java +import com.buession.core.id.AtomicUUIDIdGenerator; +import com.buession.core.id.NanoIDIdGenerator; +import com.buession.core.id.SnowflakeIdGenerator; +import com.buession.core.id.UUIDIdGenerator; +import com.buession.core.id.SimpleIdGenerator; + +AtomicUUIDIdGenerator idGenerator = new AtomicUUIDIdGenerator(); +idGenerator.nextId(); // 00000000-0000-0000-0000-000000000001 +idGenerator.nextId(); // 00000000-0000-0000-0000-000000000002 + +NanoIDIdGenerator idGenerator = new NanoIDIdGenerator(); +idGenerator.nextId(); // omRdTPCug5z_Uk1E_x3ozu3Avyyl3XSK + +SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(); +idGenerator.nextId(); // 170602258864545792 + +UUIDIdGenerator idGenerator = new UUIDIdGenerator(); +idGenerator.nextId(); // 8634a166-e7d6-4160-85eb-3433107de5a4 + +SimpleIdGenerator idGenerator = new SimpleIdGenerator(); +idGenerator.nextId(); // 26d9ed57fdad443894b988eeabc69c05 +``` + +* 注:关于雪花算法、jnanoid 算法的可自行搜索。 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-core/3.0.0/com/buession/core/id/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/core/index.md b/src/manual/3.0/core/index.md new file mode 100644 index 00000000..449d1256 --- /dev/null +++ b/src/manual/3.0/core/index.md @@ -0,0 +1,86 @@ +# buession-core 参考手册 + + +该类库为核心包,包括构建器、工具类、数据验证、ID 生成器、转换器、序列化、数学方法、消息注入、Manager 层注解、日期时间类和各通用接口定义。 + + +--- + + +### 安装 + +```xml + + com.buession + buession-core + x.x.x + +``` + + +#### [构建器](builder.md) + +Map、集合的便捷式构建,减少您的代码行数 + + +#### [编码器](codec.md) + +目前,仅包含消息构建器,您可以通过注解 @Message 将您环境中的错误码、错误消息的配置注入到 MessageObject 类型的属性中 + + +#### [收集器](collect.md) + +数组、Map、集合的工具类 + + +#### [上下文](context.md) + +定义应用上下文的类库、注解 + + +#### [转换器](converter.md) + +数据转化器,基于 mapstruct 的 POJO 类映射接口定义。定义了常用的数据转化器。 + + +#### [日期时间](datetime.md) + +日期、时间工具 + + +#### [ID 生成器](id.md) + +基于 UUID、jnanoid ID、雪花算法等等的 ID 生成器。 + + +#### [数学函数](math.md) + +定义了实用的数学函数 + + +#### [序列化和反序列化](serializer.md) + +对象的序列化和反序列化,包括二进制和 JSON。 + + +#### [验证器](validator.md) + +数据验证器及其注解 + + +#### [工具类](utils.md) + +常用通用性工具类 + + +#### [其它](other.md) + +通用的接口定义,框架自身类 + + +#### [异常](exception.md) + +通用异常的定义 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-core/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/core/math.md b/src/manual/3.0/core/math.md new file mode 100644 index 00000000..7499e453 --- /dev/null +++ b/src/manual/3.0/core/math.md @@ -0,0 +1,54 @@ +# buession-core 参考手册 + + +## 数学函数 + + +定义了实用的数学函数。 + + + +| 方法 | 说明 | +| ---- | ---- | +| continuousSum | 计算两个数之间连续相加之和 | +| rangeValue | 获取合法范围内的值,如果 value 小于 min,则返回 min;如果 value 大于 max,则返回 max;否则返回 value 本身 | + +```java +import com.buession.core.math.Math; + +long result = Math.continuousSum(1, 100); +// 5050 +``` + +```java +import com.buession.core.math.Math; + +long value = 3; +long min = 4; +long max = 10; +long result = Math.rangeValue(value, min, max); +// 4 +``` + +```java +import com.buession.core.math.Math; + +long value = 5; +long min = 4; +long max = 10; +long result = Math.rangeValue(value, min, max); +// 5 +``` + +```java +import com.buession.core.math.Math; + +long value = 11; +long min = 4; +long max = 10; +long result = Math.rangeValue(value, min, max); +// 10 +``` + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-core/3.0.0/com/buession/core/math/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/core/other.md b/src/manual/3.0/core/other.md new file mode 100644 index 00000000..8f6c633f --- /dev/null +++ b/src/manual/3.0/core/other.md @@ -0,0 +1,118 @@ +# buession-core 参考手册 + + +## 其它 + + +通用的接口定义,框架自身类,以及其它杂项。 + + +### 框架自身工具 + +获取 Buession Framework 版本: + +```java +import com.buession.core.Framework; +import com.buession.core.BuesssionFrameworkVersion; + +BuesssionFrameworkVersion.getVersion(); // 3.0.0 +Framework.VERSION; // 3.0.0 +``` + +获取 Buession Framework 框架名称: + +```java +import com.buession.core.Framework; + +Framework.NAME; // "Buession" +``` + + +### 命令执行器 + +命令执行器接口: + +```java +/** + * 命令执行器 + * + * @param + * 命令上下文 + * @param + * 命令执行返回值 + */ +@FunctionalInterface +public interface Executor { + + /** + * 命令执行 + * + * @param context + * 命令执行器上下文 + * + * @return 命令执行返回值,R 类型的实例 + */ + R execute(C context); + +} +``` + +您可以通过,该接口执行一个命令上下文的方法,并返回一个值。该方法有些类似代理模式的代理类。 + + +### 销毁接口 + +功能类似 `java.io.Closeable`。 + +```java +public interface Destroyable { + + /** + * 销毁相关资源 + * + * @throws IOException + * IO 错误时抛出 + */ + void destroy() throws IOException; + +} +``` + +### Rawable + +原始的,约定实现该接口的类,必须返回原始字节数组。 + +```java +public interface Rawable { + + /** + * 返回原始的字节数组 + * + * @return 原始的字节数组 + */ + byte[] getRaw(); + +} +``` + +### 名称节点 + +名称节点,约定实现该接口的类应该返回一个名称 + +```java +public interface NamedNode { + + /** + * 返回节点名称 + * + * @return 节点名称 + */ + @Nullable + String getName(); + +} +``` + +### 分页 + +`com.buession.core.Pagination` 为一个分页 POJO 类,包括了当前页码、每页大小、上一页、下一页、总页数、总记录数、数据列表。能够根据设定的其中一个值,计算另外的值。 \ No newline at end of file diff --git a/src/manual/3.0/core/serializer.md b/src/manual/3.0/core/serializer.md new file mode 100644 index 00000000..1d63e2c1 --- /dev/null +++ b/src/manual/3.0/core/serializer.md @@ -0,0 +1,31 @@ +# buession-core 参考手册 + + +## 构建器 + + +对象的序列化和反序列化,包括二进制和 JSON。 + +您可以通过该 API,实现将对象序列化成二进制或 JSON 字符串;或将二进制、JSON 字符串反序列化为对象。 + + +### 序列化、反序列化类 + + +| 类 | 说明 | +| ---- | ---- | +| DefaultByteArraySerializer | 将对象序列化为二进制,或将二进制反序列化为对象 | +| FastJsonJsonSerializer | 基于 FastJSON 的对象与 JSON 之间的序列化和反序列化 | +| GsonJsonSerializer | 基于 Gson 的对象与 JSON 之间的序列化和反序列化 | +| JacksonJsonSerializer | 基于 Jackson2 的对象与 JSON 之间的序列化和反序列化 | + + +1. 通用标准方法是,将对象序列化为字符串,或将字符串反序列化为对象 +2. `DefaultByteArraySerializer` 序列化成字符串,逻辑是在对象序列化为 `byte` 数组后,通过 `URLEncoder.encode` 进行编码;反序列化,则先通过 `URLDecoder.decode` 进行解码成 `byte` 数组,在反序列化为对象 +3. `DefaultByteArraySerializer` 支持对象与 `byte` 数组数组之间的序列化和反序列化 +4. 在将 JSON 字符串反序列化为对象时,默认返回类型依据 fastjson、jackson 等原生逻辑 +5. `FastJsonJsonSerializer`、`GsonJsonSerializer`、`JacksonJsonSerializer` 可以通过参数 `Class`、`TypeReference` 指定返回的对象类型 +6. `com.buession.core.serializer.type.TypeReference` 是某类型的一个指向或者引用,用于屏蔽 fastjson、gson、jackson 中通过 JDK `Type` 指定反序列化的类型;在 fastjson、gson 中是直接指定 `Type`,在 jackson 中是通过 `com.fasterxml.jackson.core.type.TypeReference` 类返回 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-core/3.0.0/com/buession/core/serializer/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/core/utils.md b/src/manual/3.0/core/utils.md new file mode 100644 index 00000000..ddbbe628 --- /dev/null +++ b/src/manual/3.0/core/utils.md @@ -0,0 +1,203 @@ +# buession-core 参考手册 + + +## 工具类 + + +常用通用性工具类。 + + +### Byte 数组比较 + +`ByteArrayComparable` 类为 java `Comparable` 的实现,实现了 byte 数组的比较。 + + +### 注解工具 + +`AnnotationUtils` 继承 `org.springframework.core.annotation.AnnotationUtils` ,在此基础上新增了方法 `hasClassAnnotationPresent(final Class clazz, final Class[] annotations)`、`hasMethodAnnotationPresent(Method method, final Class[] annotations)` 判断类或者方法上是否有待检测的注解中的其中一个注解。 + + +### 断言 + +`Assert` 和 springframework 中的注解类似,不过逻辑有些相反。 + + +### Byte 工具 + +`ByteUtils` 可以将 byte 数组转换为 char 或者 char 数组。 + +```java +import com.buession.core.utils.ByteUtils; + +byte[] bytes; +char c = ByteUtils.toChar(bytes); + +char[] chars = ByteUtils.toChar(bytes); +``` + +byte 数组连接。 + +```java +import com.buession.core.utils.ByteUtils; + +byte[] dest; +byte[] source +byte[] result = ByteUtils.concat(dest, source); +``` + + +### Character 工具 + +`CharacterUtils` 继承 `org.apache.commons.lang3.CharUtils`,可以将 char、char 数组转换为 byte 数组。 + +```java +import com.buession.core.utils.CharacterUtils; + +char c; +byte[] bytes = ByteUtils.toBytes(c); + +char[] chars; +byte[] bytes = ByteUtils.toBytes(chars); +``` + + +### 数字工具 + +`NumberUtils` 提供了对数字相关的操作。 + +| 方法 | 说明 | +| ---- | ---- | +| int2bytes | 将 int 转换为 byte[] | +| bytes2int | 将 byte[] 转换为 int | +| long2bytes | 将 long 转换为 byte[] | +| bytes2long | 将 byte[] 转换为 long | +| float2bytes | 将 float 转换为 byte[] | +| bytes2float | 将 byte[] 转换为 float | +| double2bytes | 将 double 转换为 byte[] | +| bytes2double | 将 byte[] 转换为 double | + +### 字符串工具 + +`StringUtils` 继承了 `org.apache.commons.lang3.StringUtils`,封装了多字符串更多的操作。 + + +截取字符串 + +```java +import com.buession.core.utils.StringUtils; + +String result = StringUtils.substr("abcde", 1); // bcde +String result = StringUtils.substr("abcde", 1, 2); // bc +``` + +生成随机字符串 + +```java +import com.buession.core.utils.StringUtils; + +String result = StringUtils.random(length); +``` + +比较两个 CharSequence 前 length 位是否相等 + +```java +import com.buession.core.utils.StringUtils; + +boolean result = StringUtils.equals("abcd", "abce", 3); // true +boolean result = StringUtils.equals("abcd", "abce", 4); // false +``` + +忽略大小写比较两个 CharSequence 前 length 位是否相等 + +```java +import com.buession.core.utils.StringUtils; + +boolean result = StringUtils.equalsIgnoreCase("abcd", "Abce", 3); // true +boolean result = StringUtils.equalsIgnoreCase("abcd", "aBce", 4); // false +``` + + +### 拼音工具 + +`PinyinUtils` 封装了获取中文拼音、拼音首字母的方法。 + +```java +import com.buession.core.utils.PinyinUtils; + +String result = PinyinUtils.getPinyin("中国"); // zhongguo +String result = PinyinUtils.getPinYinFirstChar("中国"); // zg +``` + +### 随机数工具 + +`RandomUtils` 封装了随机数的生成。 + +| 方法 | 说明 | +| ---- | ---- | +| nextBoolean | 随机布尔值 | +| nextBytes | 随机字节数组 | +| nextInt | 生成指定范围内的 int 值,默认:0 到 Integer.MAX_VALUE | +| nextLong | 生成指定范围内的 long 值,默认:0 到 Long.MAX_VALUE | +| nextFloat | 生成指定范围内的 float 值,默认:0 到 Float.MAX_VALUE | +| nextDouble | 生成指定范围内的 double 值,默认:0 到 Double.MAX_VALUE | + + +### Properties 工具 + +`PropertiesUtils` 封装了对 `Properties` 的操作,主要是 `Properties.getProperty` 的值为字符串,而我们在实际场景中,很多时候其值可能为 int、double。传统方法是,我们在代码中通过 `Properties.getProperty` 获取其值后,对其进行转换;而 `PropertiesUtils` 简化了操作。 + +```java +import com.buession.core.utils.SystemPropertyUtils; + +Integer result = PropertiesUtils.getInteger(properties, key); +Boolean result = PropertiesUtils.getBoolean(properties, key); +``` + + +### System Property 工具 + +`SystemPropertyUtils` 封装了系统属性或系统环境变量的操作。 + +设置属性方法 `setProperty` 对 `System.setProperty` 的封装,唯一区别是:`SystemPropertyUtils.setProperty` 的值可以为非字符串,该方法类会将非字符串值转换为字符串再调用 `System.setProperty`。 + +```java +import com.buession.core.utils.SystemPropertyUtils; + +SystemPropertyUtils.setProperty("http.port", 8080); +SystemPropertyUtils.setProperty("http.ssl.enable", false); +``` + +获取属性方法 `getProperty` 会先通过 `System.getProperty` 进行获取,若未获取到值,再调用 `System.getenv` 进行获取。 + +```java +String value = System.getProperty(name); + +if(Validate.hasText(value) == false){ + value = System.getenv(name); +} +``` + + +### 版本工具 + +`VersionUtils` 提供了对两个版本值的比较方法和获取类、jar 对应的版本。 + +```java +import com.buession.core.utils.VersionUtils; + +VersionUtils.compare("1.0.0", "1.0.1-beta"); // -1 +VersionUtils.compare("1.0.0", "1.0.0r"); // -1 +``` + +规则:dev < alpha = a < beta = b < rc < release < pl = p < 纯数字版本 + +获取类的版本值 + +```java +import com.buession.core.utils.VersionUtils; + +ByteUtils.determineClassVersion(com.buession.core.utils.VersionUtils.class); // 3.0.0 +``` + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-core/3.0.0/com/buession/core/utils/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/core/validator.md b/src/manual/3.0/core/validator.md new file mode 100644 index 00000000..ffc8043a --- /dev/null +++ b/src/manual/3.0/core/validator.md @@ -0,0 +1,204 @@ +# buession-core 参考手册 + + +## 验证器 + + +数据验证器及其注解。 + +该 API 提供了大量通用的适用于本土化的常用验证方法,如:判断是否为 null、判断是否不为 null、判断(字符串、数组、集合、Map等)是否为空、判断(字符串、数组、集合、Map等)是否不为空、IP 地址合法性验证、ISBN 合法性验证、身份证号码验证、QQ 验证。 + +并提供对应的基于 `javax.validation` 的校验注解。 + + +#### 验证是否为 null + +判断任意对象是否为 null + +```java +import com.buession.core.validator.Validate; + +boolean result = Validate.isNull(obj); +``` + +#### 验证是否不为 null + +判断任意对象是否不为 null + +```java +import com.buession.core.validator.Validate; + +boolean result = Validate.isNotNull(obj); +``` + +#### 判断字符串是否为空白字符串 + +判断字符串是否为空白字符串,为 null 或长度为 0 时也返回 true;其余情况,字符串中含有任意可打印字符串则为 false + +```java +import com.buession.core.validator.Validate; + +String str = null; +boolean result = Validate.isBlank(str); // true + +String str = ""; +boolean result = Validate.isBlank(str); // true + +String str = "\\r\\n"; +boolean result = Validate.isBlank(str); // true + +String str = "\\r\\na"; +boolean result = Validate.isBlank(str); // false +``` + +* 注:`isNotBlank` 与之相反 + + +#### 判断是否为空 + +`isEmpty` 可判断字符串、数组、集合、Map 是否为空,即:为 null 或长度/大小为 0 时,表示为空 + +```java +import com.buession.core.validator.Validate; + +String str = null; +boolean result = Validate.isEmpty(str); // true + +String str = " "; +boolean result = Validate.isEmpty(str); // false + +boolean result = Validate.isEmpty(new String[]{}); // true + +boolean result = Validate.isEmpty(new Integer[]{1}); // false +``` + +* 注:`isNotEmpty` 与之相反 + + +#### 判断是否在两个数之间 + +`isBetween` 可判断一个整型或浮点型,是否在两个整型或者浮点型数字之间 + +```java +import com.buession.core.validator.Validate; + +boolean result = Validate.isBetween(2, 1, 3); // true + +boolean result = Validate.isBetween(2, 2, 3); // false +``` + +可通过参数设置是否包含边界值 + +```java +import com.buession.core.validator.Validate; + +boolean result = Validate.isBetween(2, 1, 3, true); // true + +boolean result = Validate.isBetween(2, 2, 3, true); // true +``` + + +#### 判断是否为电话号码 + +`isTel` 可判断一个字符串是否为电话号码,仅支持普通座机号码,不支持 110、400、800等特殊号码。格式,需符合:86-区号-电话号码、区号-电话号码、(区号)电话号码、(区号)电话号码、电话号码。可通过参数 `com.buession.core.validator.routines.TelValidator.AreaCodeType` 指定区号的控制策略。仅支持中国的电话号码。 + +```java +import com.buession.core.validator.Validate; + +boolean result = Validate.isTel("028-12345678"); // true + +boolean result = Validate.isTel("028-02345678"); // false +``` + + +#### 判断是否为手机号码 + +`isMobile` 可判断一个字符串是否为手机号码。仅支持中国的手机号码。 + +```java +import com.buession.core.validator.Validate; + +boolean result = Validate.isMobile("028-12345678"); // false + +boolean result = Validate.isMobile("13800138000"); // true +``` + + +#### 判断是否为邮政编码 + +`isPostCode` 可判断一个字符串是否为邮政编码。仅支持中国的邮政编码。 + +```java +import com.buession.core.validator.Validate; + +boolean result = Validate.isPostCode("043104"); // false + +boolean result = Validate.isPostCode("643104"); // true +``` + + +#### 判断是否为 QQ 号码 + +`isQQ` 可判断一个字符串是否为 QQ 号码。 + +```java +import com.buession.core.validator.Validate; + +boolean result = Validate.isQQ("043104"); // false + +boolean result = Validate.isQQ("251329041"); // true +``` + + +#### 判断是否为身份证号码 + +`isIDCard` 可判断一个字符串是否合法的身份证号码。仅支持 18 位的身份证号码。身份证号码需符合其[身份证号码编排规律](https://baijiahao.baidu.com/s?id=1553065522587070&wfr=spider&for=pc)。 + +```java +import com.buession.core.validator.Validate; + +boolean result = Validate.isIDCard("xxxxxxxxxxxxxxxxx"); + +boolean result = Validate.isIDCard("xxxxxxxxxxxxxxxxx"); +``` + +可以和身份证号码进行比对,其实该方法的实际作用不是很大,只是在业务系统里面有需要填写身份证号码和出生日期时,简化验证出生日期和身份证号码中的出生日期是否一致。 + +```java +import com.buession.core.validator.Validate; + +boolean result = Validate.isIDCard("xxxxxxxxxxxxxxxxx", true, "2000-01-01"); +``` + +其它,更多方法可以[参考手册](https://javadoc.io/static/com.buession/buession-core/3.0.0/com/buession/core/validator/Validate.html)。 + + +### 注解 + +javax 的 validation 是 Java 定义的一套基于注解的数据校验规范,buession framework 基于 javax.validation 实现了 `Validate` 中所有验证方法的校验注解。 + + +| 注解 | 验证的数据类型 | 说明 | +| ---- | ---- | ---- | +| @Alnum | CharSequence 的子类型,Character | 验证注解的元素值是否为数字 | +| @Alpha | CharSequence 的子类型,Character | 验证注解的元素值是否为数字 | +| @Numeric | CharSequence 的子类型,Character | 验证注解的元素值是否为数字 | +| @Between | short、int、double 等任何 Number 的子类型 | 验证注解的元素值是否为在两个数之间 | +| @Empty | CharSequence、Map、Collection、Iterator、Enumeration 的子类型和数组 | 验证注解的元素值是否为空 | +| @NotEmpty | CharSequence、Map、Collection、Iterator、Enumeration 的子类型和数组 | 验证注解的元素值是否不为空 | +| @HasText | CharSequence 的子类型 | 验证注解的元素值是否有非空字符 | +| @IDCard | CharSequence 的子类型 | 验证注解的元素值是否有非空字符 | +| @Ip | CharSequence 的子类型 | 验证注解的元素值是否有非空字符 | +| @Isbn | CharSequence 的子类型 | 验证注解的元素值是否有非空字符 | +| @MimeType | CharSequence 的子类型 | 验证注解的元素值是否有非空字符 | +| @Mobile | CharSequence 的子类型 | 验证注解的元素值是否有非空字符 | +| @Null | 任意类型 | 验证注解的元素值是否为 null | +| @NotNull | 任意类型 | 验证注解的元素值是否为 null | +| @Port | Integer | 验证注解的元素值是否为 null | +| @PostCode | CharSequence 的子类型 | 验证注解的元素值是否为 null | +| @QQ | CharSequence 的子类型 | 验证注解的元素值是否为 null | +| @Tel | CharSequence 的子类型 | 验证注解的元素值是否为 null | +| @Xdigit | CharSequence 的子类型 | 验证注解的元素值是否为 null | + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-core/3.0.0/com/buession/core/validator/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/dao/index.md b/src/manual/3.0/dao/index.md new file mode 100644 index 00000000..817b04ae --- /dev/null +++ b/src/manual/3.0/dao/index.md @@ -0,0 +1,57 @@ +# buession-dao 参考手册 + + +对 mybatis、spring-data-mongo 常用方法(如:根据条件获取单条记录、根据主键获取单条记录、分页、根据条件删除数据、根据主键删除数据)进行了二次封装。从代码层面实现了数据库的读写分离,insert、update、delete 操作主库,select 操作从库。 + + +--- + + +### 安装 + +```xml + + com.buession + buession-dao + x.x.x + +``` + +我们咋众多项目中,基本有常见的重复的对数据库的 CURD 操作,比如:根据主键查询数据、根据主键删除数据、获取一条记录。MyBatis 是一款优秀的持久层框架,应用广泛。MongoDB 是一款优秀的文档数据库。我自己根据从业多年的经验,从实际场合出发,将在业务层对数据库的常用操作进行了封装。对关系型数据库基于 MyBatis 二次封装,对 MongoDB 基于 spring-data-mongodb;在未来也许会考虑,增加 jpa 和 JdbcTemplate 对关系型数据库的二次封装。 + +同时,我们在代码层面实现了数据库的读写分离。 + +我们没有改变 MyBatis 和 spring-data-mongodb 的任何底层逻辑,本质就是 MyBaits 和 spring-data-mongodb;我们唯一做了的就是,定义和是了大家在应用程序中常用的方法,让您不在重复去编写该部分代码;以及在代码层面实现了数据的读写分离。 + + +### Dao 接口 + +接口定义,可见:[https://javadoc.io/static/com.buession/buession-dao/2.0.2/com/buession/dao/Dao.html](https://javadoc.io/static/com.buession/buession-dao/3.0.0/com/buession/dao/Dao.html) + +```java +public interface Dao { +} +``` + +* `P`:主键类型 +* `E`:实体类 + + +分页对象 `com.buession.dao.Pagination` 继承自 `com.buession.core.Pagination`,增加了偏移量属性 `offset`。 + +条件为 `Map` 类型,允许为 null。 + +排序为 `Map` 类型,允许为 null。 + + +#### [MyBatis](mybatis.md) + +Buession Framework 扩展 MyBatis 的文档。 + + +#### [MongoDB](mongodb.md) + +Buession Framework 扩展 spring-data-mongodb 的文档。 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-dao/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/dao/mongodb.md b/src/manual/3.0/dao/mongodb.md new file mode 100644 index 00000000..51793ebe --- /dev/null +++ b/src/manual/3.0/dao/mongodb.md @@ -0,0 +1,17 @@ +# buession-dao 参考手册 + + +## MongoDB + +Buession Framework 扩展 spring-data-mongodb 的文档。 + + +### 读写分离 + +要从代码层面实现读写分离,必须继承 `AbstractMongoDBDao`;且存在 bean 名为 `masterMongoTemplate`、`slaveMongoTemplates` 的 bean 实例。masterMongoTemplate 操作主库,实现插入、更新、删除操作;slaveMongoTemplates 操作从库,实现查询操作。默认查询操作,会通过方法 `getSlaveMongoTemplate()` 在所有的 slave templates 中随机返回一个 MongoTemplate bean 实例。当然,您也可以通过 `getSlaveMongoTemplate(final int index)` 指定索引的 slave MongoTemplate bean 实例(当然,我们不建议您这么做)。如果没有指定 slave MongoTemplate bean 实例列表,将会返回 master MongoTemplate bean 实例,buession framework 屏蔽了这些技术细节。 + +`AbstractMongoDBDao` 的 `replace` 执行的也是 `insert`。 +在对 MongoDB 的操作条件中 value 可以为 `com.buession.dao.MongoOperation`,可以通过该类的方法控制条件等于值、大于值、小于值、LIKE值 等等运算。 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-dao/3.0.0/com/buession/dao/AbstractMongoDBDao.html) \ No newline at end of file diff --git a/src/manual/3.0/dao/mybatis.md b/src/manual/3.0/dao/mybatis.md new file mode 100644 index 00000000..409ffb9b --- /dev/null +++ b/src/manual/3.0/dao/mybatis.md @@ -0,0 +1,78 @@ +# buession-dao 参考手册 + + +## MyBatis + +Buession Framework 扩展 MyBatis 的文档。 + + +### 读写分离 + +要从代码层面实现读写分离,必须继承 `AbstractMyBatisDao`;且存在 bean 名为 `masterSqlSessionTemplate`、`slaveSqlSessionTemplates` 的 bean 实例。masterSqlSessionTemplate 操作主库,实现插入、更新、删除操作;slaveSqlSessionTemplates 操作从库,实现查询操作。默认查询操作,会通过方法 `getSlaveSqlSessionTemplate()` 在所有的 slave templates 中随机返回一个 slave SqlSessionTemplate bean 实例。当然,您也可以通过 `getSlaveSqlSessionTemplate(final int index)` 指定索引的 slave SqlSessionTemplate bean 实例(当然,我们不建议您这么做)。如果没有指定 slave SqlSessionTemplate bean 实例列表,将会返回 master SqlSessionTemplate bean 实例,buession framework 屏蔽了这些技术细节。 + + +### Mybatis 约定 + +1. 如果集成 `AbstractMyBatisDao` 类,必须重写方法 `getStatement()`,通过此方法返回每个 Mapper namespace + + +```java +namespace com.buession.dao.test.dao; + +public class UserDaoImpl extends AbstractMyBatisDao { + + @Override + protected String getStatement(){ + return "com.buession.dao.test.dao.UserMapper"; + } + +} +``` + +```xml + + + +``` + +2. Mapper 的 SQL ID 和方法名保持一致 + + +| SQL ID | 说明 | 返回值 | +| ---- | ---- | ---- | +| insert | 插入数据 | 影响的行数 | +| batchInsert | 批量插入数据,默认循环插入;您可以重写该方法实现 SQL 批量插入 | 每次插入影响的行数列表 | +| replace | 替换数据,即:REPLACE 语句 | 影响的行数 | +| batchReplace | 批量替换数据,即:REPLACE 语句 | 每次替换数据影响的行数列表 | +| update | 更新数据 | 更新条数 | +| updateByPrimary | 根据主键更新数据,注:主键参数值是会覆盖实体类主键参数对应的类属性的值 | 更新条数 | +| getByPrimary | 根据主键查询数据,SQL 层面需要保证最多只会返回一条数据 | 一条数据结果 | +| selectOne | (根据条件)获取一条数据,SQL 层面需要保证最多只会返回一条数据 | 一条数据结果 | +| select | 查询数据 | 数据结果列表 | +| getAll | 查询所有数据 | 数据结果列表 | +| count | 获取记录数 | 记录数 | +| deleteByPrimary | 根据主键删除数据 | 影响条数 | +| delete | 删除数据 | 影响条数 | +| clear | 清除数据 | 影响条数 | +| truncate | 截断数据 | 影响条数 | + +* 注:要实现分页,必须实现 count,且和 select 的查询条件必须一致。因为,在分页方法中,首先会执行 count ,查询指定条件的记录数;如果记录数大于 0 时,才会执行 select 查询数据。在后续的开发中,我们将会使用拦截器实现。 + 以上 SQL ID,只是一种约定,具体会呈现一种什么样的效果,还是完全屈居于您的 SQL 语句。 + + +### Mybatis 类型处理器 + +MyBatis 自身提供大量优秀的类型处理器 `TypeHandler`,但任然不足。我们在此基础上扩展了一些 `TypeHandler`。名称空间为 `org.apache.ibatis.type`,不是 `com.buession.dao`。 + + +| TypeHandler | 说明 | +| ---- | ---- | +| DefaultEnumTypeHandler | 默认 Enum 类型处理器,将值直接转换为枚举字段 | +| IgnoreCaseEnumTypeHandler | 忽略大小写 Enum 类型处理器,将值忽略大小写转换为枚举字段 | +| DefaultJsonTypeHandler | JSON 处理器,将 JSON 格式的字符串值和类型 <E> 进行转换 | +| DefaultSetEnumTypeHandler | 默认 Enum 型 Set 类型处理器,将值直接转换为枚举字段作为 Set 的元素 | +| IgnoreCaseSetEnumTypeHandler | 忽略大小写 Enum 型 Set 类型处理器,将值忽略大小写转换为枚举字段作为 Set 的元素 | +| DefaultSetTypeHandler | 默认 Set 类型处理器,将值以 "," 拆分转换为 Set<String> | + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-dao/3.0.0/com/buession/dao/AbstractMyBatisDao.html) \ No newline at end of file diff --git a/src/manual/3.0/geoip/index.md b/src/manual/3.0/geoip/index.md new file mode 100644 index 00000000..b567e07f --- /dev/null +++ b/src/manual/3.0/geoip/index.md @@ -0,0 +1,98 @@ +# buession-geoip 参考手册 + + +对 com.maxmind.geoip2:geoip2 进行二次封装,实现支持根据 IP 地址获取所属 ISP、所属国家、所属城市等等信息。 + + +--- + + +### 安装 + +```xml + + com.buession + buession-geoip + x.x.x + +``` + +通常我们在应用中对用户注册、登录、以及其它操作记录 IP,我们更希望知道用户在什么城市进行的操作,如:微信公众号的内容发表于、微博的发布于等等,对于用户行为的安全审计等等有着极高的作用。 + +`geoip` 在基于 `maxmind geoip2` 的基础上进行了二次封装,可以根据 IP(字符串形式的 IP,如:114.114.114.114、2001:0DB8:0000:0023:0008:0800:200C:417A ,IPV4 的数字表示:3739974408,java `InetAddress`)获取其 IP 地址的国家信息、城市信息、位置信息。 + + +### 获取国家信息 + +```java +import com.buession.geoip.model.Country; +import com.buession.geoip.model.DatabaseResolver; + +DatabaseResolver resolver = new DatabaseResolver(DatabaseResolver.class.getResourceAsStream("/maxmind/City.mmdb")); +Country country = resolver.country("114.114.114.114"); +// Country{geoNameId=1814991, confidence=null, code='CN', originalName='China', name='中国', fullName='中华人民共和国', isInEuropeanUnion=false} + +Country country = resolver.country(3739974408L); // 3739974408L => 222.235.123.8 +// Country{geoNameId=1835841, confidence=null, code='KR', originalName='Republic of Korea', name='大韩民国', fullName='大韩民国', isInEuropeanUnion=false} +``` + + +### 获取城市信息 + +```java +import com.buession.geoip.model.Country; +import com.buession.geoip.model.DatabaseResolver; + +DatabaseResolver resolver = new DatabaseResolver(DatabaseResolver.class.getResourceAsStream("/maxmind/City.mmdb")); +District district = resolver.district("114.114.114.114"); +// District{geoNameId=1799962, code=null, originalName='Nanjing', name='南京', fullName='江苏省南京', postal=Postal{code='null', confidence=null}, parent=District{geoNameId=1806260, code=null, originalName='Jiangsu', name='江苏省', fullName='江苏省江苏省', postal=null, parent=District{geoNameId=1806260, code=null, originalName='Jiangsu', name='江苏省', fullName='江苏省', postal=null, parent=null}}} + +District district = resolver.district(3739974408L); // 3739974408L => 222.235.123.8 +// District{geoNameId=1835848, code=null, originalName='Seoul', name='首尔特别市', fullName='首尔特别市首尔特别市', postal=Postal{code='null', confidence=null}, parent=District{geoNameId=1835847, code=null, originalName='Seoul', name='首尔特别市', fullName='首尔特别市首尔特别市', postal=null, parent=District{geoNameId=1835847, code=null, originalName='Seoul', name='首尔特别市', fullName='首尔特别市', postal=null, parent=null}}} +``` + + +### 获取位置信息 + +位置信息中包括了该 IP 比较全面的信息,包括:城市信息、国家信息、洲信息、经纬度、机构信息、时区等。 + +```java +import com.buession.geoip.model.Country; +import com.buession.geoip.model.DatabaseResolver; + +DatabaseResolver resolver = new DatabaseResolver(DatabaseResolver.class.getResourceAsStream("/maxmind/City.mmdb")); +Location location = resolver.location("114.114.114.114"); +// Location{continent=Continent{geoNameId=6255147, code='AS', originalName='Asia', name='亚洲'}, country=Country{geoNameId=1814991, confidence=null, code='CN', originalName='China', name='中国', fullName='中华人民共和国', isInEuropeanUnion=false}, district=District{geoNameId=1799962, code=null, originalName='Nanjing', name='南京', fullName='江苏省南京', postal=Postal{code='null', confidence=null}, parent=District{geoNameId=1806260, code=null, originalName='Jiangsu', name='江苏省', fullName='江苏省江苏省', postal=null, parent=District{geoNameId=1806260, code=null, originalName='Jiangsu', name='江苏省', fullName='江苏省', postal=null, parent=null}}}, traits=Traits{ipAddress='114.114.114.114', domain='null', isp='null', network=114.114.0.0/16, connectionType=null, organization=null, autonomousSystemOrganization=null, autonomousSystemNumber=null, isAnonymous=false, isAnonymousProxy=false, isAnonymousVpn=false, isHostingProvider=false, isLegitimateProxy=false, isPublicProxy=false, isSatelliteProvider=false, isTorExitNode=false, userType='false', userCount=null, staticIpScore=null}, geo=Geo{latitude=32.0617, longitude=118.7778, accuracyRadius=50}, timeZone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null]} + +Location location = resolver.location(3739974408L); // 3739974408L => 222.235.123.8 +// Location{continent=Continent{geoNameId=6255147, code='AS', originalName='Asia', name='亚洲'}, country=Country{geoNameId=1835841, confidence=null, code='KR', originalName='Republic of Korea', name='大韩民国', fullName='大韩民国', isInEuropeanUnion=false}, district=District{geoNameId=1835848, code=null, originalName='Seoul', name='首尔特别市', fullName='首尔特别市首尔特别市', postal=Postal{code='null', confidence=null}, parent=District{geoNameId=1835847, code=null, originalName='Seoul', name='首尔特别市', fullName='首尔特别市首尔特别市', postal=null, parent=District{geoNameId=1835847, code=null, originalName='Seoul', name='首尔特别市', fullName='首尔特别市', postal=null, parent=null}}}, traits=Traits{ipAddress='222.235.123.8', domain='null', isp='null', network=222.235.120.0/21, connectionType=null, organization=null, autonomousSystemOrganization=null, autonomousSystemNumber=null, isAnonymous=false, isAnonymousProxy=false, isAnonymousVpn=false, isHostingProvider=false, isLegitimateProxy=false, isPublicProxy=false, isSatelliteProvider=false, isTorExitNode=false, userType='false', userCount=null, staticIpScore=null}, geo=Geo{latitude=37.5111, longitude=126.9743, accuracyRadius=200}, timeZone=sun.util.calendar.ZoneInfo[id="Asia/Seoul",offset=32400000,dstSavings=0,useDaylight=false,transitions=30,lastRule=null]} +``` + + +### 缓存 + +为了提高数据的处理能力,可以将获取过的数据缓存起来,下次获取同一 IP 信息时,可以直接从缓存中返回。您可以通过 `DatabaseResolver` 构造函数中的参数 `cache` 设置为 `com.maxmind.db.NodeCache` 的实现类即可,或直接使用类 `CacheDatabaseResolver`解析。我们默认使用 `maxmind` 内置的 `CHMCache` 来实现缓存,它是基于 `ConcurrentHashMap` 的内存缓存。 + + +### Resolver 的 Spring Factory Bean + +我们内置了 geoip 的 `Resolver` spring factory bean 类 `GeoIPResolverFactoryBean`,您可以通过它在您的 spring 项目中,初始化 `Resolver` 的实现类为 spring bean 对象。 + +```xml + +``` + +1. `dbPath` 和 `stream` 二选一即可,一个是指定 IP 的文件路径,一个是指定已加载的 IP 库的文件流。都不设置的默认以流的形式加载 `buession-geoip` 中的 IP 库文件。 +2. `enableCache` 可以控制是否缓存。 + + +### 关于 IP 库 + +`buession-geoip` 中包含了 `maxmind` 免费的 IP 所属城市和国家的库。由于在 jar 包中该数据库无法做到及时更新,在实际应用中,我们建议您从 `maxmind` 官网下载 IP 方法您的应用中,通过 `DatabaseResolver` 的构造函数指定 IP 库路径,这么做的好处是:在您的应用程序中,可以去保证 IP 库是更新的。 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-geoip/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/git/index.md b/src/manual/3.0/git/index.md new file mode 100644 index 00000000..646ad968 --- /dev/null +++ b/src/manual/3.0/git/index.md @@ -0,0 +1,18 @@ +# buession-git 参考手册 + + +--- + + +### 安装 + +```xml + + com.buession + buession-git + x.x.x + +``` + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-git/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/httpclient/configuration.md b/src/manual/3.0/httpclient/configuration.md new file mode 100644 index 00000000..ccf4e1e4 --- /dev/null +++ b/src/manual/3.0/httpclient/configuration.md @@ -0,0 +1,30 @@ +# buession-httpclient 参考手册 + + +## 连接配置 + + +您可以通过连接配置类 `Configuration` 配置 `apache httpcomponents` 和 `okhttp3` 的链接配置属性,`buession-httpclient` 内部会自动将 `Configuration` 的配置信息,转换为 `apache httpcomponents` 或 `okhttp3` 的配置信息。 + + +### 配置属性说明 + + +| 属性名称 | 数据类型 | apache httpcomponents 对应配置 | okhttp3 对应配置 | 默认值 | 说明 | +| ---- | ---- | ---- | ---- | ---- | ---- | +| maxConnections | int | maxTotal | maxIdleConnections | 5000 | 最大连接数 | +| maxPerRoute | int | defaultMaxPerRoute | -- | 500 | 每个路由的最大连接数 | +| idleConnectionTime | int | closeIdleConnections | keepAliveDuration | 60000 | 空闲连接存活时长(单位:毫秒) | +| connectTimeout | int | connectTimeout | connectTimeout | 3000 | 连接超时时间(单位:毫秒) | +| connectionRequestTimeout | int | connectionRequestTimeout | -- | 5000 | 从连接池获取连接的超时时间(单位:毫秒) | +| readTimeout | int | socketTimeout | readTimeout | 5000 | 读取超时时间(单位:毫秒) | +| allowRedirects | Boolean | redirectsEnabled | followRedirects | -- | 是否允许重定向 | +| relativeRedirectsAllowed | Boolean | relativeRedirectsAllowed | -- | -- | 是否应拒绝相对重定向 | +| circularRedirectsAllowed | Boolean | circularRedirectsAllowed | -- | -- | 是否允许循环重定向 | +| maxRedirects | Integer | maxRedirects | -- | -- | 最大允许重定向次数 | +| authenticationEnabled | boolean | authenticationEnabled | -- | -- | 是否开启 Http Basic 认证 | +| contentCompressionEnabled | boolean | contentCompressionEnabled | -- | -- | 是否启用内容压缩 | +| normalizeUri | boolean | normalizeUri | -- | -- | 是否标准化 URI | + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-httpclient/3.0.0/com/buession/httpclient/core/Configuration.html) \ No newline at end of file diff --git a/src/manual/3.0/httpclient/connectionmanager.md b/src/manual/3.0/httpclient/connectionmanager.md new file mode 100644 index 00000000..70126663 --- /dev/null +++ b/src/manual/3.0/httpclient/connectionmanager.md @@ -0,0 +1,17 @@ +# buession-httpclient 参考手册 + + +## 连接管理器 + + +连接管理器是用来管理 HTTP 连接的,包括设置连接配置、控制连接池。关于更多的连接池,可以参考 `apache httpcomponents` 和 `okhttp3` 的文档。 + +您可以通过无参数的构造函数来创建连接管理器,也可以通过构造函数参数仅为 `com.buession.httpclient.core.Configuration` 来创建连接管理器,也可以构造函数通过 `apache httpcomponents` 或 `okhttp3` 原生的连接管理器类创建(此时,`Configuration` 的配置不任何意义,他不会修改您通过原生连接管理器实例中的参数配置)。 + + +### 关于 okhttp 连接管理器 + +okhttp3 本身是没有类似 apache httpcomponents 的链接管理器 `org.apache.http.conn.HttpClientConnectionManager` 的,我们为了在 `buession-httpclient` 的链接管理器实现 `com.buession.httpclient.conn.OkHttpClientConnectionManager` 保持一致,人为的加了一层 okhttp3 的链接管理器 `okhttp3.HttpClientConnectionManager`(注意:命名空间为 okhttp3),主要用于初始化连接池类 `okhttp3.ConnectionPool`。 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-httpclient/3.0.0/com/buession/httpclient/conn/ConnectionManager.html) \ No newline at end of file diff --git a/src/manual/3.0/httpclient/index.md b/src/manual/3.0/httpclient/index.md new file mode 100644 index 00000000..2d75df7d --- /dev/null +++ b/src/manual/3.0/httpclient/index.md @@ -0,0 +1,126 @@ +# buession-httpclient 参考手册 + + +对 `apache httpcomponents`、`okhttp3` 进行封装,屏蔽了 apache httpcomponents 和 okhttp3 的不同技术细节,屏蔽了对 post form、post json 等等的技术细节。 + + +--- + + +### 安装 + +```xml + + com.buession + buession-httpclient + x.x.x + +``` + +我们在应用中使用 Http Client 功能时,经常因为从 `apache httpcomponents` 切换为 `okhttp3`,或者从 `okhttp3` 切换为 `apache httpcomponents`,需要改动大量的代码而烦恼。而当您使用了 `buession-httpclient` 时,该类库为您解决了这些烦恼,通过顶层设计,屏蔽了 `apache httpcomponents` 和 `okhttp3` 的细节,当您需要从一个 http 库更换为另外一个 http 库时,您只需要在 pom.xml 中引用不同的包,修改一下 httpclient 的初始化类和连接管理器即可。 + +传统的方式: + +```xml + + org.apache.httpcomponents + httpcore + x.x.x + + + org.apache.httpcomponents + httpclient + x.x.x + +``` + +```java +import org.apache.http.HttpResponse; +import org.apache.http.conn.HttpClientConnectionManager; +import org.apache.http.client.HttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.client.methods.HttpPost; + +HttpClient httpClient = HttpClientBuilder.create().setConnectionManager(new HttpClientConnectionManager()).build(); + +HttpResponse response = httpClient.execute(new HttpPost("https://www.buession.com/")); +``` + +或者 + +```xml + + com.squareup.okhttp3 + okhttp + x.x.x + +``` + +```java +import okhttp3.HttpClientConnectionManager; +import okhttp3.OkHttpClient; +import okhttp3.ConnectionPool; +import okhttp3.Request; +import okhttp3.Request.Builder; +import okhttp3.Response; + +OkHttpClient.Builder builder = new OkHttpClient.Builder().connectionPool(new ConnectionPool()); +HttpClient httpClient = builder.build(); + +Builder requestBuilder = new Builder().post(); +requestBuilder.url("https://www.buession.com/"); +Request okHttpRequest = requestBuilder.build(); + +Response httpResponse = httpClient.newCall(okHttpRequest).execute(); +``` + +现在,您只需要通过 `buession-httpclient`,即可屏蔽其中的细节。 + +```xml + + com.buession + buession-httpclient + x.x.x + + + org.apache.httpcomponents + httpcore + x.x.x + + + org.apache.httpcomponents + httpclient + x.x.x + +``` + +或者 + +```xml + + com.buession + buession-httpclient + x.x.x + + + com.squareup.okhttp3 + okhttp + x.x.x + +``` + +```java +import com.buession.httpclient.HttpClient; +import com.buession.httpclient.ApacheHttpClient; +import com.buession.httpclient.OkHttpHttpClient; +import com.buession.httpclient.conn.ApacheClientConnectionManager; +import com.buession.httpclient.conn.OkHttpClientConnectionManager; +import com.buession.httpclient.core.Response; + +HttpClient httpClient = new ApacheHttpClient(new ApacheClientConnectionManager()); // 或者 new OkHttpHttpClient(new OkHttpClientConnectionManager()); + +Response response = httpClient.post("https://www.buession.com/"); +``` + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-httpclient/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/httpclient/method.md b/src/manual/3.0/httpclient/method.md new file mode 100644 index 00000000..40b55bb3 --- /dev/null +++ b/src/manual/3.0/httpclient/method.md @@ -0,0 +1,117 @@ +# buession-httpclient 参考手册 + + +## 方法 + + +`buession-httpclient` 提供了和 HTTP 请求方式同名的方法 API,您可以很方便的通过提供的方法发起 HTTP 请求。 + + +#### 示例: + +```java +import com.buession.httpclient.HttpClient; +import com.buession.httpclient.core.Response; + +// GET 请求 +Response response = httpClient.get("https://www.buession.com/"); + +// POST 请求 +Response response = httpClient.post("https://www.buession.com/"); + +// HEAD 请求 +Response response = httpClient.head("https://www.buession.com/"); +``` + +您可以自定义请求头: + +```java +import com.buession.httpclient.HttpClient; +import com.buession.httpclient.core.Response; +import com.buession.httpclient.core.Header; +import java.util.List; +import java.util.ArrayList; + +List
headers = new ArrayList<>(); + +headers.add(new Header("X-SDK-NAME", "Buession")); +headers.add(new Header("X-Timestamp", System.currentTimeMillis())); + +// GET 请求 +Response response = httpClient.get("https://www.buession.com/", headers); + +// POST 请求 +Response response = httpClient.post("https://www.buession.com/", headers); + +// HEAD 请求 +Response response = httpClient.head("https://www.buession.com/", headers); +``` + +您可以设置请求参数: + +```java +import com.buession.httpclient.HttpClient; +import com.buession.httpclient.core.Response; +import com.buession.httpclient.core.Header; +import java.util.Map; +import java.util.HashMap; + +Map parameters = new HashMap<>(); + +parameters.put("action", "edit"); +parameters.put("id", 1); + +// GET 请求 +Response response = httpClient.get("https://www.buession.com/", parameters); + +// POST 请求 +Response response = httpClient.post("https://www.buession.com/", parameters); + +// HEAD 请求 +Response response = httpClient.head("https://www.buession.com/", parameters); +``` + +您可以设置请求体: + +```java +import com.buession.httpclient.HttpClient; +import com.buession.httpclient.core.Response; +import com.buession.httpclient.core.Header; +import jcom.buession.httpclient.core.RequestBody; +import jcom.buession.httpclient.core.EncodedFormRequestBody; +import jcom.buession.httpclient.core.EncodedFormRequestBody; + +EncodedFormRequestBody requestBody = new EncodedFormRequestBody(); + +requestBody.addRequestBodyElement("username", "buession"); +requestBody.addRequestBodyElement("password", "buession"); + +// POST 请求 +Response response = httpClient.post("https://www.buession.com/", requestBody); + +JsonRawRequestBody requestBody = new JsonRawRequestBody(new User()); +// PUT 请求 +Response response = httpClient.put("https://www.buession.com/", requestBody); +``` + +不同的 `RequestBody`,决定了我们以什么样的 `Content-Type` 提交数据,`buession-httpclient` 中提供了大量的内置 `RequestBody`。 + + +### RequestBody + + +| RequestBody | Content-Type | 说明 | +| ---- | ---- | ---- | +| InputStreamRequestBody | application/octet-stream | 二进制请求体 | +| ChunkedInputStreamRequestBody | application/octet-stream | Chunked 二进制请求体 | +| RepeatableInputStreamRequestBody | application/octet-stream | Repeatable 二进制请求体 | +| EncodedFormRequestBody | application/x-www-form-urlencoded | 普通表单请求体 | +| MultipartFormRequestBody | multipart/form-data | 文件上传表单请求体 | +| HtmlRawRequestBody | text/html | HTML 请求体 | +| JavaScriptRawRequestBody | application/javascript | JavaScript 请求体 | +| JsonRawRequestBody | application/json | JSON 请求体 | +| TextRawRequestBody | text/plain | TEXT 请求体 | +| XmlRawRequestBody | text/xml | XML 请求体 | + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-httpclient/3.0.0/com/buession/httpclient/HttpClient.html) \ No newline at end of file diff --git a/src/manual/3.0/httpclient/response.md b/src/manual/3.0/httpclient/response.md new file mode 100644 index 00000000..dec5afd7 --- /dev/null +++ b/src/manual/3.0/httpclient/response.md @@ -0,0 +1,31 @@ +# buession-httpclient 参考手册 + + +## 响应 + + +当通过 `HttpClient` 发起任意请求后,将得到一个 `Response`。此结果,包括了:协议及其版本、状态码及其信息、响应头列表、响应体、以及响应体长度。 +`buession-httpclient` 会将 `apache httpcomponents` 或 `okhttp3` 的响应对象,转换为 `Response`。 + +需要注意的是,原生 `apache httpcomponents` 或 `okhttp3` 响应体流,一旦被使用过一次之后,将不能再使用;同时您只能以流或者字符串二选一的形式获取响应体。但是,在 `buession-httpclient` 中您将可以二者兼顾,当然这也同时会带来一些性能消耗和内存占用。 + +```java +import com.buession.httpclient.HttpClient; +import com.buession.httpclient.ApacheHttpClient; +import com.buession.httpclient.conn.ApacheClientConnectionManager; +import com.buession.httpclient.core.Response; +import java.io.InputStream; + +HttpClient httpClient = new ApacheHttpClient(new ApacheClientConnectionManager()); + +Response response = httpClient.post("https://www.buession.com/"); +InputStream stream = response.getInputStream(); // 以流的形式获取响应体 +String body = response.getBody(); // 以字符串的形式获取响应体 + +stream.close(); +``` + +`getInputStream`、`getBody` 二者可以重复调用,当时您需要始终手动关闭一下流,因为这将是拷贝的原生 `apache httpcomponents` 或 `okhttp3` 返回的流。 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-httpclient/3.0.0/com/buession/httpclient/core/Response.html) \ No newline at end of file diff --git a/src/manual/3.0/index.md b/src/manual/3.0/index.md new file mode 100644 index 00000000..b22a2107 --- /dev/null +++ b/src/manual/3.0/index.md @@ -0,0 +1,25 @@ +# API 参考手册 + + +Buession Framework API 包含以下目录: + + +| 模块 | 使用帮助 | 手册 | +| ---- | ---- | ---- | +| buession-aop | [使用帮助](aop/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-aop/2.0.2/) | +| buession-beans | [使用帮助](beans/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-bean/2.0.2/) | +| buession-core | [使用帮助](core/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-core/2.0.2/) | +| buession-cron | [使用帮助](cron/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-cron/2.0.2/) | +| buession-dao | [使用帮助](dao/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-dao/2.0.2/) | +| buession-geoip | [使用帮助](geoip/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-geoip/2.0.2/) | +| buession-httpclient | [使用帮助](httpclient/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-httpclient/2.0.2/) | +| buession-io | [使用帮助](io/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-io/2.0.2/) | +| buession-jdbc | [使用帮助](jdbc/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-jdbc/2.0.2/) | +| buession-json | [使用帮助](json/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-json/2.0.2/) | +| buession-lang | [使用帮助](lang/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-lang/2.0.2/) | +| buession-net | [使用帮助](net/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-net/2.0.2/) | +| buession-redis | [使用帮助](redis/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-redis/2.0.2/) | +| buession-session | [使用帮助](session/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-session/2.0.2/) | +| buession-thesaurus | [使用帮助](thesaurus/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-thesaurus/2.0.2/) | +| buession-velocity | [使用帮助](velocity/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-velocity/2.0.2/) | +| buession-web | [使用帮助](web/index.md) | [API 手册](https://javadoc.io/static/com.buession/buession-web/2.0.2/) | \ No newline at end of file diff --git a/src/manual/3.0/io/index.md b/src/manual/3.0/io/index.md new file mode 100644 index 00000000..c4265de9 --- /dev/null +++ b/src/manual/3.0/io/index.md @@ -0,0 +1,115 @@ +# buession-io 参考手册 + + +封装了对文件的操作 + + +--- + + +### 安装 + +```xml + + com.buession + buession-io + x.x.x + +``` + + +该模块二次封装了 java `java.io.File` 和 `java.nio.file.Files` 类,在此基础上扩展了大量的实用方法,如:文件读写、获取文件 MD5 和 SHA1 值,获取文件 MIME,设置文件所属用户和用户组,简化了我们在应用开发过程中对文件的操作。 + + +### 读取文件 + +```java +import com.buession.io.file.File; + +File file = new File("/tmp/debug.txt"); + +byte[] result = file.read(); +``` + + +### 写文件 + +```java +import com.buession.io.file.File; + +File file = new File("/tmp/debug.txt"); + +file.write("Buession"); +file.write("Buession".getBytes()); +file.write("Buession", true); // 追加写 +``` + + +### 获取文件 MD5、SHA-1值 + +```java +import com.buession.io.file.File; + +File file = new File("/tmp/debug.txt"); + +String md5 = file.getMd5(); // 获取文件 MD5 +String sha1 = file.getSha1(); // 获取文件 SHA-1 +``` + + +### 获取文件 MD5、SHA-1 值 + +```java +import com.buession.io.file.File; +import com.buession.io.MimeType; + +File file = new File("/tmp/debug.txt"); + +MimeType result = file.getMimeType(); +``` + + +### 设置文件权限 + +```java +import com.buession.io.file.Files; + +Files.chmod("/tmp/debug.txt", 0777); +``` + + +### 设置文件用户组 + +```java +import com.buession.io.file.Files; + +Files.chgrp("/tmp/debug.txt", "root"); +``` + + +### 设置文件用户 + +```java +import com.buession.io.file.Files; + +Files.chown("/tmp/debug.txt", "root"); +``` + + +### 注解 + +注解 `com.buession.io.json.annotation.MimeTypeString` 可以将类型为 `com.buession.io.MimeType` 的字段序列化为字符串和将字符串反序列化为 `com.buession.io.MimeType`,该功能是基于 jackson 实现的。 + +```java +import com.buession.io.json.annotation.MimeTypeString; + +class File { + + @MimeTypeString + private MimeType mime; + +} +``` + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-io/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/jdbc/index.md b/src/manual/3.0/jdbc/index.md new file mode 100644 index 00000000..e1f677e9 --- /dev/null +++ b/src/manual/3.0/jdbc/index.md @@ -0,0 +1,24 @@ +# buession-jdbc 参考手册 + + +JDBC 通用 POJO 类定义,对 Hikari、Dbcp2、Druid 等配置和数据源的封装。 + + +--- + + +### 安装 + +```xml + + com.buession + buession-jdbc + x.x.x + +``` + + +通过提供的 API,您可以简化对 `DBCP2`、`Druid`、`Hikari`、`Tomcat` 数据源的初始化,该类库基本不单独使用。 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-jdbc/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/json/index.md b/src/manual/3.0/json/index.md new file mode 100644 index 00000000..4b09f299 --- /dev/null +++ b/src/manual/3.0/json/index.md @@ -0,0 +1,37 @@ +# buession-json 参考手册 + + +主要实现了一些 jackson 的自定义注解及序列化、反序列化的实现。 + + +--- + + +### 安装 + +```xml + + com.buession + buession-json + x.x.x + +``` + + +封装了大量基于 `jackson` 的注解。 + + +### 注解 + + +| 注解 | 说明 | +| ---- | ---- | +| CalendarUnixTimestamp | java.util.Calendar 和 Unix 时间戳序列化、反序列化;通过该注解,可以将 java.util.Calendar 序列化为 Unix 时间戳;将 Unix 时间戳反序列化为 java.util.Calendar | +| DateUnixTimestamp | java.util.Date 和 Unix 时间戳序列化、反序列化;通过该注解,可以将 java.util.Date 序列化为 Unix 时间戳;将 Unix 时间戳反序列化为 java.util.Date | +| SqlDateUnixTimestamp | java.sql.Date 和 Unix 时间戳序列化、反序列化;通过该注解,可以将 java.sql.Date 序列化为 Unix 时间戳;将 Unix 时间戳反序列化为 java.sql.Date | +| TimestampUnixTimestamp | java.sql.Timestamp 和 Unix 时间戳序列化、反序列化;通过该注解,可以将 java.sql.Timestamp 序列化为 Unix 时间戳;将 Unix 时间戳反序列化为 java.sql.Timestamp | +| JsonEnum2Map | 枚举和 java.util.Map 序列化和反序列化;通过该注解,可以将枚举序列化为 java.util.Map;将 java.util.Map 反序列化为枚举 | +| Sensitive | 通过该注解可以实现数据的脱敏 | + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-json/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/lang/index.md b/src/manual/3.0/lang/index.md new file mode 100644 index 00000000..34b0c9d8 --- /dev/null +++ b/src/manual/3.0/lang/index.md @@ -0,0 +1,21 @@ +# buession-lang 参考手册 + + +常用 POJO 类和枚举的定义,详细查看 API 参考手册。 + + +--- + + +### 安装 + +```xml + + com.buession + buession-lang + x.x.x + +``` + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-lang/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/net/index.md b/src/manual/3.0/net/index.md new file mode 100644 index 00000000..2988d6c2 --- /dev/null +++ b/src/manual/3.0/net/index.md @@ -0,0 +1,35 @@ +# buession-net 参考手册 + + +网络相关工具类。 + + +--- + + +### 安装 + +```xml + + com.buession + buession-net + x.x.x + +``` + + +### IP 地址工具类 + +IP 地址工具类 `com.buession.net.utils.InetAddressUtis` 实现了,IPV4 地址和数字型 IP 相互转换。 + +```java +import com.buession.net.utils.InetAddressUtis; + +long result = InetAddressUtis.ip2long("127.0.0.1"); // 2130706433 +String ip = InetAddressUtis.long2ip(2130706433L); // 127.0.0.1 +``` + +URI 类或 URIBuilder 类,实现了 url 字符串的构建,详细查看 API 手册。 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-net/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/redis/datasource.md b/src/manual/3.0/redis/datasource.md new file mode 100644 index 00000000..712dfab2 --- /dev/null +++ b/src/manual/3.0/redis/datasource.md @@ -0,0 +1,75 @@ +# buession-redis 参考手册 + + +## 数据源 + +`buession-redis` 基于数据源 `DataSource` 连接 redis,其机制类似 JDBC 的 DataSource。 +通过,数据源可以配置,redis 的用户名、密码、连接超时、读取超时、连接池、SSL等等。 + +数据源 `DataSource` 包括三个子接口: + +* StandaloneDataSource:单机模式数据源 +* SentinelDataSource:哨兵模式数据源 +* ClusterDataSource:集群模式数据源 + +jedis 和后续的 lettuce 分别实现这三个接口,用于创建不通模式的数据源,数据源中实现了连接池的创建。 + +在原始的 jedis 或者 spring-data-redis 中,密码为空字符串时,会以空字符串密码进行登录 redis;我们修改了这一逻辑,不管您在程序中密码是设置的 null 还是空字符串,我们都会跳过认证。这样的好处就是,假设您的开发环境 redis 没有设置密码,生产环境设置了密码,我们可以通过一个 bean 初始化即可,不用写成两个 bean。 + +```xml + +``` + +测试环境 properties: + +```properties +redis.host=127.0.0.1 +redis.port=6379 +redis.password= +``` + +生产环境 properties: + +```properties +redis.host=192.168.100.131 +redis.port=6379 +redis.password=passwd +``` + + +### 连接池 + +通过连接池管理 redis 连接,能够大大的提高效率和节约资源的使用。jedis 和 lettuce 均使用 `apache commons-pool2` 来创建和维护连接池。但是,在 jedis 中,以 `JedisPoolConfig` 和 `ConnectionPoolConfig` 来管理单例模式连接池、哨兵模式连接池和集群模式连接池;为了简化配置,我们定义了 `com.buession.redis.core.PoolConfig` 来统一维护各种模式的连接池配置,然后在各 `DataSource` 中转换为原生的连接池配置,极大的简化了学习和替换成本。 + + +连接池配置 + +| 配置项 | 数据类型 | -- 默认值 | 说明 | +| ---- | ---- | -- | ---- | +| lifo | boolean | GenericObjectPoolConfig.DEFAULT_LIFO | 池模式,为 true 时,后进先出;为 false 时,先进先出 | +| fairness | boolean | GenericObjectPoolConfig.DEFAULT_FAIRNESS | 当从池中获取资源或者将资源还回池中时,是否使用 java.util.concurrent.locks.ReentrantLock 的公平锁机制 | +| maxWait | Duration | GenericObjectPoolConfig.DEFAULT_MAX_WAIT | 当连接池资源用尽后,调用者获取连接时的最大等待时间 | +| minEvictableIdleTime | Duration | 60000 | 连接的最小空闲时间,达到此值后且已达最大空闲连接数该空闲连接可能会被移除 | +| softMinEvictableIdleTime | Duration | GenericObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_DURATION | 连接空闲的最小时间,达到此值后空闲链接将会被移除,且保留 minIdle 个空闲连接数 | +| evictionPolicyClassName | String | GenericObjectPoolConfig.DEFAULT_EVICTION_POLICY_CLASS_NAME | 驱逐策略的类名 | +| evictorShutdownTimeout | Duration | GenericObjectPoolConfig.DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT | 关闭驱逐线程的超时时间 | +| numTestsPerEvictionRun | int | -1 | 检测空闲对象线程每次运行时检测的空闲对象的数量 | +| testOnCreate | boolean | GenericObjectPoolConfig.DEFAULT_TEST_ON_CREATE | 在创建对象时检测对象是否有效,配置 true 会降低性能 | +| testOnBorrow | boolean | GenericObjectPoolConfig.DEFAULT_TEST_ON_BORROW | 在从对象池获取对象时是否检测对象有效,配置 true 会降低性能 | +| testOnReturn | boolean | GenericObjectPoolConfig.DEFAULT_TEST_ON_RETURN | 在向对象池中归还对象时是否检测对象有效,配置 true 会降低性能 | +| testWhileIdle | boolean | true | 在检测空闲对象线程检测到对象不需要移除时,是否检测对象的有效性;建议配置为 true,不影响性能,并且保证安全性 | +| timeBetweenEvictionRuns | int | 30000 | 空闲连接检测的周期,如果为负值,表示不运行检测线程 | +| blockWhenExhausted | boolean | GenericObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED | 当对象池没有空闲对象时,新的获取对象的请求是否阻塞(true 阻塞,maxWaitMillis 才生效;false 连接池没有资源立马抛异常) | +| timeBetweenEvictionRuns | int | 30000 | 空闲连接检测的周期,如果为负值,表示不运行检测线程 | +| jmxEnabled | boolean | GenericObjectPoolConfig.DEFAULT_JMX_ENABLE | 是否注册 JMX | +| jmxNamePrefix | String | GenericObjectPoolConfig.DEFAULT_JMX_NAME_PREFIX | JMX 前缀 | +| jmxNameBase | String | GenericObjectPoolConfig.DEFAULT_JMX_NAME_BASE | 使用 base + jmxNamePrefix + i 来生成 ObjectName | +| maxTotal | int | GenericObjectPoolConfig.DEFAULT_MAX_TOTAL | 最大连接数 | +| minIdle | int | GenericObjectPoolConfig.DEFAULT_MIN_IDLE | 最小空闲连接数 | +| maxIdle | int | GenericObjectPoolConfig.DEFAULT_MAX_IDLE | 最大空闲连接数 | + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-redis/3.0.0/com/buession/redis/client/connection/datasource/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/redis/index.md b/src/manual/3.0/redis/index.md new file mode 100644 index 00000000..ae822694 --- /dev/null +++ b/src/manual/3.0/redis/index.md @@ -0,0 +1,49 @@ +# buession-redis 参考手册 + + +Redis 操作类,基于 jedis 实现,RedisTemplate 方法名、参数几乎同 redis 原生命令保持一致。同时,对对象读写 redis 进行了扩展,支持二进制、json方式序列化和反序列化,例如:通过 RedisTemplate.getObject(“key”, Object.class) 可以将 redis 中的数据读取出来后,直接反序列化成一个对象。 + + +--- + + +### 安装 + +```xml + + com.buession + buession-redis + x.x.x + +``` + + +### 介绍 + +`buession-redis` 是一款基于 jedis 的 redis 操作库,最大的优势就是封装了与 redis 同名、最大程度与 redis 原生参数顺序一致的 API。同时,我们在现代应用中,经常需要读写一个 pojo 对象,`buession-redis` 封装了 `xxxObject` 读写取 redis 中的二进制或 JSON 数据,并反序列化为 POJO 类。大大简化了,我们在代码中对象存取到 redis 中,让我们更专注业务功能的开。能够通过 `com.buession.redis.core.Options` 设置全局选项,如:统一的 Key 前缀,对象基于什么方式序列化和反序列化。 + + +```java +import com.buession.redis.RedisTemplate; +import com.buession.redis.core.Options; +import com.buession.core.serializer.type.TypeReference; +import java.utils.Map; +import java.utils.HashMap; + +RedisTemplate redisTemplate = new RedisTemplate(dataSource); + +redisTemplate.setOptions(new Options()); +redisTemplate.afterPropertiesSet(); + +// 将 User 对象写进 key 为 user hash 中 +redisTemplate.hSet("user", "1", new User()); + +// 获取 key 为 user ,field 为 1 的 hash 中的数据,并转换为 User +User user = redisTemplate.hGetObject("user", "1", User.class); + +// 获取 key 为 user 的 hash 的所有数据,并将值转换为 User +Map data = redisTemplate.hGetAllObject("user", "1", new TypeReference>{}); +``` + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-redis/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/redis/method.md b/src/manual/3.0/redis/method.md new file mode 100644 index 00000000..4a4b0171 --- /dev/null +++ b/src/manual/3.0/redis/method.md @@ -0,0 +1,44 @@ +# buession-redis 参考手册 + + +## 方法 + +`buession-redis` `BaseRedisTemplate` 的方法以及参数计划与原生 redis 命名保持一致。复杂的参数会通过 Builder 进行参数构建,在多个值中进行选择的将定义成枚举,规避出错的几率。 + +```java +import com.buession.redis.BaseRedisTemplate; + +BaseRedisTemplate redisTemplate = new BaseRedisTemplate(dataSource); + +redisTemplate.afterPropertiesSet(); + +// 删除哈希表 key 中的一个或多个指定域 +redisTemplate.hDel("user", "1", "2", "3"); + +// 检查给定 key 是否存在 +redisTemplate.exists("user"); + +// 获取列表 key 中,下标为 index 的元素 +redisTemplate.lIndex("user", 1); + +// 如果键 key 已经存在并且它的值是一个字符串,将 value 追加到键 key 现有值的末尾 +redisTemplate.append("key", "value 1"); +``` + +`BaseRedisTemplate` 实现了 redis 的原生操作,`RedisTemplate` 继承了 `BaseRedisTemplate` ,在此基础上实现了将 redis 中的二进制或者 JSON 格式的值,反序列化为一个类。 + +```java +import com.buession.redis.RedisTemplate; + +RedisTemplate redisTemplate = new RedisTemplate(dataSource); + +redisTemplate.afterPropertiesSet(); + +// 获取列表 key 中,下标为 index 的元素,并反序列化为 User 类 +User user = redisTemplate.lIndexObject("user", 1, User.class); +``` + +序列化和反序列化,基于 [`buession-core` 序列化和反序列化](/manual/3.0/core/serializer.html) 扩展而来,序列化或反序列化出错时会直接返回 null,而忽略异常,默认使用 `com.buession.redis.serializer.JacksonJsonSerializer` 序列化为 JSON。 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-redis/3.0.0/com/buession/redis/core/command/package-summary.html) \ No newline at end of file diff --git a/src/manual/3.0/thesaurus/index.md b/src/manual/3.0/thesaurus/index.md new file mode 100644 index 00000000..65b9aad2 --- /dev/null +++ b/src/manual/3.0/thesaurus/index.md @@ -0,0 +1,35 @@ +# buession-thesaurus 参考手册 + + +对词库的解析,目前仅支持搜狗词条。 + + +--- + + +### 安装 + +```xml + + com.buession + buession-thesaurus + x.x.x + +``` + +您可以通过该库解析搜狗拼音的词条库,包括词条、拼音信息。 + + +```java +import com.buession.thesaurus.SogouParser; +import com.buession.thesaurus.Parser; +import com.buession.thesaurus.core.Word; +import java.util.Set; + +Parser parser = new SogouParser(); + +Set words parser.parse("搜谱拼音词条文件路径"); +``` + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-thesaurus/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/velocity/index.md b/src/manual/3.0/velocity/index.md new file mode 100644 index 00000000..9076b49d --- /dev/null +++ b/src/manual/3.0/velocity/index.md @@ -0,0 +1,23 @@ +# buession-velocity 参考手册 + + +spring mvc 不再支持 velocity,这里主要是把原来 spring mvc 中关于 velocity 的实现迁移过来,让喜欢 velocity 的 coder 继续在高版本的 springframework 中继续使用 velocity。 + + +--- + + +### 安装 + +```xml + + com.buession + buession-velocity + x.x.x + +``` + +该类库,基本照搬了 springframework 集成 velocity 的代码和逻辑。 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-velocity/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/web/annotation.md b/src/manual/3.0/web/annotation.md new file mode 100644 index 00000000..6536a8fc --- /dev/null +++ b/src/manual/3.0/web/annotation.md @@ -0,0 +1,20 @@ +# buession-web 参考手册 + + +## 注解 + + +我们通过注解的形式封装了一些我们在日常应用开发过程中能用到的实用性功能,简化了您在代码开发中的便捷度,让您能够更专注业务的开发。 + + +### 注解 + +| 注解 | Request / Response | 作用域 | 说明 | +| ---- | ---- | ---- | ---- | +| @RequestClientIp | request | 方法参数 | 获取当前请求的客户端 IP 地址 | +| @ContentType | response | 类、方法 | 设置响应 Content-Type | +| @HttpCache | response | 类、方法 | 设置响应缓存头 Cache-Control、Expires、Pragma 值 | +| @DisableHttpCache | response | 类、方法 | 设置响应缓存头 Cache-Control、Expires、Pragma 值,禁止缓存 | +| @ResponseHeader | response | 类、方法 | 设置响应头 | +| @ResponseHeaders | response | 类、方法 | 批量设置响应头 | +| @DocumentMetaData | response | 类、方法 | 设置页面标题、页面编码、关键字、描述、版权等等元信息 | \ No newline at end of file diff --git a/src/manual/3.0/web/filter.md b/src/manual/3.0/web/filter.md new file mode 100644 index 00000000..8416b750 --- /dev/null +++ b/src/manual/3.0/web/filter.md @@ -0,0 +1,21 @@ +# buession-web 参考手册 + + +## 过滤器 + + +我们封装了一些使用的过滤器,简化了您的开发或者应用运行的跟踪。 + +servlet 包位于 `com.buession.web.servlet.filter`,webflux 包位于 `com.buession.web.reactive.filter`,均有同样类名的过滤器类。 + + +### 过滤器 + +| 过滤器 | 说明 | +| ---- | ---- | +| MobileFilter | 当前请求是否为移动设备 | +| PoweredByFilter | Powered By 过滤器 | +| PrintUrlFilter | 打印当前请求 URL 过滤器 | +| ResponseHeaderFilter | 响应头过滤器,设置响应头 | +| ResponseHeadersFilter | 响应头过滤器,批量设置响应头 | +| ServerInfoFilter | Server 信息过滤器,通过响应头的形式,输出当前服务器名称,可以用于集群环境定位出现问题的节点 | \ No newline at end of file diff --git a/src/manual/3.0/web/index.md b/src/manual/3.0/web/index.md new file mode 100644 index 00000000..cf2b164c --- /dev/null +++ b/src/manual/3.0/web/index.md @@ -0,0 +1,23 @@ +# buession-web 参考手册 + + +web 相关的功能封装,支持 servlet 和 reactive;封装了一些常用注解,简化了业务层方面的代码实现;封装了一些常用 filter。 + + +--- + + +### 安装 + +```xml + + com.buession + buession-web + x.x.x + +``` + +`buession-web` 扩展了 `spring-webmvc`、`spring-webflux`;在此基础上,提供了大量的实用的 filter 和注解,以及工具类。该模块无论封装的 filter、注解、工具类,均适用于 spring mvc,也适用于 spring webflux。当时,filter、工具类均为 servlet 和 webflux 各自独立的类,不是说同一个类,即能用于 servlet,也能用于 webflux,当然注解是通用的。 + + +### [API 参考手册>>](https://javadoc.io/static/com.buession/buession-web/3.0.0/) \ No newline at end of file diff --git a/src/manual/3.0/web/restful.md b/src/manual/3.0/web/restful.md new file mode 100644 index 00000000..677ddfb9 --- /dev/null +++ b/src/manual/3.0/web/restful.md @@ -0,0 +1,38 @@ +# buession-web 参考手册 + + +## RESTFUL + + +`Restful` 是当今比较流行的一种架构的规范与约束、原则,基于这个风格设计的软件可以更简洁、更有层次。 + +我们遵循 REST 规范,在代码层面规范好了新增、修改、详情、删除等基本的路由,您的控制器层只需要继承 [`com.buession.web.servlet.mvc.controller.AbstractBasicRestController`](https://javadoc.io/static/com.buession/buession-web/2.0.2/com/buession/web/servlet/mvc/controller/AbstractBasicRestController.html) 或者 [`com.buession.web.reactive.mvc.controller.AbstractBasicRestController`](https://javadoc.io/static/com.buession/buession-web/2.0.2/com/buession/web/reactive/mvc/controller/AbstractBasicRestController.html) 即可在 servlet 或 webflux 模式下,实现标准的 REST 风格的代码。简化了您的代码(主要是不用再写 @RequestMapping)和标准化了。 + +```java +@RestController +@RequestMapping(path = "/example") +public class ExampleController extends AbstractRestController { + + @Override + public Response add(HttpServletRequest request, HttpServletResponse response, @RequestBody ExampleDto example){ + + } + + @Override + public Response edit(HttpServletRequest request, HttpServletResponse response, @PathVariable(name = "id") Integer id, @RequestBody ExampleDto example){ + + } + + @Override + public Response detail(HttpServletRequest request, HttpServletResponse response, @PathVariable(name = "id") Integer id){ + + + } + + @Override + public Response delete(HttpServletRequest request, HttpServletResponse response, @PathVariable(name = "id") Integer id){ + + } + +} +``` \ No newline at end of file diff --git a/src/manual/3.0/web/utils.md b/src/manual/3.0/web/utils.md new file mode 100644 index 00000000..7bbdf920 --- /dev/null +++ b/src/manual/3.0/web/utils.md @@ -0,0 +1,42 @@ +# buession-web 参考手册 + + +## 工具 + + +我们封装了一些 web 相关的工具类,用于处理 request、response。 + +servlet 包位于 `com.buession.web.servlet.http`,webflux 包位于 `com.buession.web.reactive.http`,均有同样类名的过滤器类。 + + +获取客户端真实 IP 地址: + +```java +RequestUtils.getClientIp(request); +``` + +我们兼容了,通过微信和一些 CDN 厂商获取用户真实 IP 的头信息,我们优先获取从微信透传过来的用户的真实 IP,然后再是各 CDN 厂商的用户真实 IP 头,最后才是标准的真实 IP 头。当然,我们不能保证是否是伪造的。 + +优先顺序:X-Forwarded-For-Pound(微信) > Ali-Cdn-Real-Ip(阿里云 CDN) > Cdn-Src-Ip(网宿) > X-Cdn-Src-Ip(网宿) > X-Original-Forwarded-For(天翼云) > X-Forwarded-For > X-Real-Ip > Proxy-Client-IP > WL-Proxy-Client-IP > Real-ClientIP > remote addr + + +是否是 Ajax 请求: + +```java +RequestUtils.isAjaxRequest(request); +``` + + +是否是移动设备请求: + +```java +RequestUtils.isMobile(request); +``` + + +设置缓存: + +```java +ResponseUtils.httpCache(response, 5); // 缓存 5 秒 +ResponseUtils.httpCache(response, new Date()); // 缓存到指定的时间点 +``` \ No newline at end of file diff --git a/src/manual/SUMMARY.md b/src/manual/SUMMARY.md index b896d169..98ad9bd0 100644 --- a/src/manual/SUMMARY.md +++ b/src/manual/SUMMARY.md @@ -2,6 +2,72 @@ * [简介](index.md) * [参考指南](overview.md) + * [3.0.x](3.0/index.md) + * [buession-aop](3.0/aop/index.md) + * [安装](3.0/aop/index.md#安装) + * [buession-beans](3.0/beans/index.md) + * [安装](3.0/beans/index.md#安装) + * [buession-core](3.0/core/index.md) + * [安装](3.0/core/index.md#安装) + * [构建器](3.0/core/builder.md) + * [编码器](3.0/core/codec.md) + * [收集器](3.0/core/collect.md) + * [上下文](3.0/core/context.md) + * [配置器](3.0/core/configurer.md) + * [定制器](3.0/core/customizer.md) + * [转换器](3.0/core/converter.md) + * [日期时间](3.0/core/datetime.md) + * [ID 生成器](3.0/core/id.md) + * [数学函数](3.0/core/math.md) + * [序列化](3.0/core/serializer.md) + * [反序列化](3.0/core/deserializer.md) + * [验证器](3.0/core/validator.md) + * [工具类](3.0/core/utils.md) + * [其它](3.0/core/other.md) + * [异常](3.0/core/exception.md) + * [buession-dao](3.0/dao/index.md) + * [安装](3.0/dao/index.md#安装) + * [MyBatis](3.0/dao/mybatis.md) + * [MongoDB](3.0/dao/mongodb.md) + * [buession-geoip](3.0/geoip/index.md) + * [安装](3.0/geoip/index.md#安装) + * [buession-git](3.0/git/index.md) + * [安装](3.0/git/index.md#安装) + * [buession-httpclient](3.0/httpclient/index.md) + * [安装](3.0/httpclient/index.md#安装) + * [连接配置](3.0/httpclient/configuration.md) + * [连接管理器](3.0/httpclient/connectionmanager.md) + * [响应](3.0/httpclient/response.md) + * [方法](3.0/httpclient/method.md) + * [异步](3.0/httpclient/async.md) + * [buession-io](3.0/io/index.md) + * [安装](3.0/io/index.md#安装) + * [buession-jdbc](3.0/jdbc/index.md) + * [安装](3.0/jdbc/index.md#安装) + * [buession-json](3.0/json/index.md) + * [安装](3.0/json/index.md#安装) + * [buession-lang](3.0/lang/index.md) + * [安装](3.0/lang/index.md#安装) + * [buession-net](3.0/net/index.md) + * [安装](3.0/net/index.md#安装) + * [buession-redis](3.0/redis/index.md) + * [安装](3.0/redis/index.md#安装) + * [介绍](3.0/redis/index.md#介绍) + * [数据源](3.0/redis/datasource.md) + * [方法](3.0/redis/method.md) + * [展望](3.0/redis/index.md#展望) + * [buession-thesaurus](3.0/thesaurus/index.md) + * [安装](3.0/thesaurus/index.md#安装) + * [buession-velocity](3.0/velocity/index.md) + * [安装](3.0/velocity/index.md#安装) + * [buession-web](3.0/web/index.md) + * [安装](3.0/web/index.md#安装) + * [注解](3.0/web/annotation.md) + * [过滤器](3.0/web/filter.md) + * [Response](3.0/web/response.md) + * [Pagination](3.0/web/pagination.md) + * [RESTFUL](3.0/web/restful.md) + * [工具](3.0/web/utils.md) * [2.3.x](2.3/index.md) * [buession-aop](2.3/aop/index.md) * [安装](2.3/aop/index.md#安装) diff --git a/src/manual/overview.md b/src/manual/overview.md index b5597b01..360c3b86 100644 --- a/src/manual/overview.md +++ b/src/manual/overview.md @@ -5,6 +5,7 @@ | 版本 | 手册 | | ---- | ---- | +| 3.0.x | [API 手册](3.0/index.html) | | 2.3.x | [API 手册](2.3/index.html) | | 2.2.x | [API 手册](2.2/index.html) | | 2.1.x | [API 手册](2.1/index.html) |