Skip to content

Commit

Permalink
Merge pull request #31 from stick-i/docs
Browse files Browse the repository at this point in the history
docs: 完善在线文档
  • Loading branch information
stick-i authored Sep 6, 2024
2 parents 63ff407 + aaab1fa commit f8175f5
Show file tree
Hide file tree
Showing 13 changed files with 136 additions and 35 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ jobs:
- name: 部署文档
uses: JamesIves/github-pages-deploy-action@v4
with:
# 这是文档部署到的分支名称
branch: gh-pages
folder: document/web-docs/docs/.vuepress/dist
repository-name: stick-i/spel-validator-gh-pages
branch: gh-pages
token: ${{ secrets.GH_PAGES_TOKEN }}
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ JDK8+
- `vX.Y.Z`:版本分支,用于汇总及验证新版本的功能,已经发布的版本会将分支删除。
- `dev-num-desc`:开发分支,用于开发新功能,每个dev分支都应当对应一个issue,功能开发完成后通过PR合入 `vX.Y.Z` 分支,并删除当前分支。
- `docs`:文档分支,修改文档的内容将提交到这里。
- `gh-pages`:GitHub Pages 分支,用于发布在线文档。

## License

Expand Down
8 changes: 4 additions & 4 deletions document/web-docs/docs/.vuepress/configs/head.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ export const head: HeadConfig[] = [
},
],
['link', {rel: 'manifest', href: '/manifest.webmanifest'}],
['meta', {name: 'application-name', content: 'VuePress'}],
['meta', {name: 'apple-mobile-web-app-title', content: 'VuePress'}],
['meta', {name: 'application-name', content: 'SpEL Validator'}],
['meta', {name: 'apple-mobile-web-app-title', content: 'SpEL Validator'}],
['meta', {name: 'apple-mobile-web-app-status-bar-style', content: 'black'}],
[
'link',
{rel: 'apple-touch-icon', href: `/images/icons/apple-touch-icon.png`},
{rel: 'apple-touch-icon', href: `/images/logo.png`},
],
[
'link',
{
rel: 'mask-icon',
href: '/images/icons/safari-pinned-tab.svg',
href: '/images/logo.png',
color: '#3eaf7c',
},
],
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
102 changes: 77 additions & 25 deletions document/web-docs/docs/guide/custom.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,106 @@
# 自定义约束注解

如果你使用过 `javax.validation` 的自定义约束注解,那么你会发现 `SpEL Validator` 的自定义约束注解几乎与 `javax.validation`
一致。
::: tip
如果你使用过 `javax.validation` 的自定义约束注解,那么你会发现 `SpEL Validator` 的自定义约束注解几乎与 `javax.validation` 一致。
:::

下面以 `@SpelNotNull` 为例,展示如何实现自定义约束注解。

**以下内容还没写完**
下面以 `@SpelNotBlank` 为例,展示如何实现自定义约束注解。

## 创建约束注解类

每个约束注释必须包含以下属性:
- `String message() default "";` 用于指定约束校验失败时的错误消息。
- `String condition() default "";` 用于指定约束开启条件的SpEL表达式。
- `String[] group() default {};` 用于指定分组条件的SpEL表达式。

```java
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = SpelNotNullValidator.class)
public @interface SpelNotNull {
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Repeatable(SpelNotBlank.List.class)
public @interface SpelNotBlank {

String message() default "{javax.validation.constraints.NotNull.message}";
String message() default "不能为空字符串";

Class<?>[] groups() default {};
String condition() default "";

Class<? extends Payload>[] payload() default {};
String[] group() default {};

String condition() default "";
@Target(FIELD)
@Retention(RUNTIME)
@Documented
@interface List {

SpelNotBlank[] value();

}

}
```

## 创建约束验证器

创建类 `SpelNotBlankValidator`,实现 `SpelConstraintValidator<T>` 接口,其中泛型 `T` 为要校验的约束注解类,在这里是 `SpelNotBlank`

实现 `isValid` 方法,校验逻辑在该方法中实现。

`isValid` 方法的参数说明如下:
- `annotation`:当前约束注解的实例。
- `obj`:当前校验的根对象。
- `field`:当前校验的字段。

```java
public class SpelNotNullValidator implements ConstraintValidator<SpelNotNull, Object> {
public class SpelNotBlankValidator implements SpelConstraintValidator<SpelNotBlank> {

@Override
public FieldValidResult isValid(SpelNotBlank annotation, Object obj, Field field) throws IllegalAccessException {
CharSequence fieldValue = (CharSequence) field.get(obj);
return new FieldValidResult(StringUtils.hasText(fieldValue));
}

}
```

一般情况下,只需要校验当前字段的值,通过 `field.get(obj)` 即可获取。

有些约束注解可能仅支持特定类型的字段,可以通过重写 `supportType()` 方法来指定支持的类型。默认情况下,支持所有类型。

private String condition;
```java
public class SpelNotBlankValidator implements SpelConstraintValidator<SpelNotBlank> {

@Override
public void initialize(SpelNotNull constraintAnnotation) {
this.condition = constraintAnnotation.condition();
public FieldValidResult isValid(SpelNotBlank annotation, Object obj, Field field) throws IllegalAccessException {
CharSequence fieldValue = (CharSequence) field.get(obj);
return new FieldValidResult(StringUtils.hasText(fieldValue));
}

private static final Set<Class<?>> SUPPORT_TYPE = Collections.singleton(CharSequence.class);

@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
if (value == null) {
return false;
}
if (StringUtils.hasText(condition)) {
return SpelUtils.evaluate(condition, value, Boolean.class);
}
return true;
public Set<Class<?>> supportType() {
return SUPPORT_TYPE;
}

}
```

## 关联注解和验证器

`SpelNotBlank` 注解上添加 `@SpelConstraint` 注解,指定该注解的验证器为 `SpelNotBlankValidator`

```java
@Documented
@Retention(RUNTIME)
@Target(FIELD)
@Repeatable(SpelNotBlank.List.class)
@SpelConstraint(validatedBy = SpelNotBlankValidator.class) // 关联验证器
public @interface SpelNotBlank {
// ...
}
```

## 使用自定义约束注解

完成上面的步骤,就可以在需要校验的字段上使用 `@SpelNotBlank` 注解了,使用方法就和内置的约束注解一样,[使用指南](user-guide.md)

已经大功告成了,这里我就不举例了。
4 changes: 3 additions & 1 deletion document/web-docs/docs/guide/getting-started.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# 快速开始

- 支持JDK8+
:::tip
本章仅介绍如何快速上手 SpEL Validator 的基本使用,更详细的使用说明请参考 [使用指南](user-guide.md)
:::

## 添加依赖

Expand Down
47 changes: 45 additions & 2 deletions document/web-docs/docs/guide/spel.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,57 @@

本章只介绍一些重要的 SpEL 表达式用法,更详细的使用说明请参考官方文档。

官方文档:[Spring Expression Language (SpEL)](https://docs.spring.io/spring-framework/reference/core/expressions.html)
官方文档:[Spring Expression Language (SpEL)](https://docs.spring.io/spring-framework/reference/core/expressions/language-ref.html)

::: tip

如果你的 IDEA 版本比较新,那么不出意外的话,IDEA 能够识别到表达式,并且会给出提示,也具备引用的功能。
如果你的 IDEA 版本比较新,理论上来说,IDEA 应该能够识别到表达式,并且会给出提示,也具备引用的功能。

:::

## 基本操作符

> 此部分由GPT生成,进行了部分删减。
1. **算术操作符**
- `+` 加法
- `-` 减法
- `*` 乘法
- `/` 除法
- `%` 取模

2. **关系操作符**
- `==` 等于
- `!=` 不等于
- `<` 小于
- `<=` 小于等于
- `>` 大于
- `>=` 大于等于

3. **逻辑操作符**
- `&&` 逻辑与
- `||` 逻辑或
- `!` 逻辑非

4. **条件操作符(三元操作符)**
- `? :` 条件表达式,类似于 Java 中的 `? :`

5. **成员访问**
- `.` 属性访问
- `[]` 属性访问(使用字符串键)

6. **集合操作符**
- `in` 判断元素是否在集合中
- `!in` 判断元素是否不在集合中

7. **空安全操作符**
- `?.` 空安全属性访问
- `:?` 空安全方法调用

8. **空合并操作符**
- `?:` 当左侧表达式为 null 时,返回右侧表达式的值


## 调用静态方法

调用静态方法的语法为:`T(全类名).方法名(参数)`
Expand Down
4 changes: 4 additions & 0 deletions document/web-docs/docs/guide/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

:::

## 支持的版本

- JDK8+

## 添加依赖

Latest Version:
Expand Down

0 comments on commit f8175f5

Please sign in to comment.