├── .gitignore
├── README.md
├── pom.xml
├── rxjava-apikit
├── pom.xml
├── rxjava-apikit-core
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── rxjava
│ │ └── apikit
│ │ ├── annotation
│ │ └── Ignore.java
│ │ ├── client
│ │ ├── ApiType.java
│ │ ├── ApiUtils.java
│ │ └── ClientAdapter.java
│ │ └── core
│ │ └── HttpMethodType.java
├── rxjava-apikit-maven-plugin
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── rxjava
│ │ └── apikit
│ │ └── plugin
│ │ ├── ApikitMojo.java
│ │ ├── ApikitsMojo.java
│ │ ├── GenerateUtils.java
│ │ ├── MavenUtils.java
│ │ └── bean
│ │ ├── AbstractTask.java
│ │ ├── GitTask.java
│ │ ├── Group.java
│ │ ├── JavaClientTask.java
│ │ ├── JavaScriptClientTask.java
│ │ └── Task.java
└── rxjava-apikit-tool
│ ├── ReadMe.md
│ ├── pom.xml
│ └── src
│ └── main
│ ├── java
│ └── org
│ │ └── rxjava
│ │ └── apikit
│ │ └── tool
│ │ ├── ApiGenerateManager.java
│ │ ├── analyse
│ │ ├── Analyse.java
│ │ └── impl
│ │ │ ├── ControllerAnalyse.java
│ │ │ ├── EnumClassAnalyse.java
│ │ │ └── ParamClassAnalyse.java
│ │ ├── generator
│ │ ├── AbstractGenerator.java
│ │ ├── ApiContext.java
│ │ ├── ClassNameMapper.java
│ │ ├── Context.java
│ │ ├── Generator.java
│ │ ├── NameMaper.java
│ │ ├── PackageNameMapper.java
│ │ └── impl
│ │ │ ├── AbstractCommonGenerator.java
│ │ │ ├── AbstractHttlGenerator.java
│ │ │ ├── ApidocApiGenerator.java
│ │ │ ├── ApidocGenerator.java
│ │ │ ├── DefaultClassNameMapper.java
│ │ │ ├── DefaultPackageNameMapper.java
│ │ │ ├── GitGenerator.java
│ │ │ ├── JavaClientApiGenerator.java
│ │ │ ├── JavaScriptApiGenerator.java
│ │ │ └── PatternNameMaper.java
│ │ ├── info
│ │ ├── AnnotationInfo.java
│ │ ├── ApiClassInfo.java
│ │ ├── ApiInputClassInfo.java
│ │ ├── ApiMethodInfo.java
│ │ ├── ClassBaseInfo.java
│ │ ├── ClassInfo.java
│ │ ├── ClassTypeInfo.java
│ │ ├── ControllerInfo.java
│ │ ├── ControllerMethodInfo.java
│ │ ├── EnumConstantInfo.java
│ │ ├── EnumParamClassInfo.java
│ │ ├── FieldInfo.java
│ │ ├── Import.java
│ │ ├── InputParamInfo.java
│ │ ├── JavaDocInfo.java
│ │ ├── PackageInfo.java
│ │ ├── ParamClassInfo.java
│ │ ├── ParamInfo.java
│ │ ├── PropertyInfo.java
│ │ ├── TestInfo.java
│ │ └── TestSuperInfo.java
│ │ ├── type
│ │ └── ApiType.java
│ │ ├── utils
│ │ ├── ClassAnalyseUtils.java
│ │ ├── CommentUtils.java
│ │ ├── DateTimeUtils.java
│ │ ├── HttlUtils.java
│ │ ├── JavaFileFormat.java
│ │ ├── JdtClassWrapper.java
│ │ ├── JsonUtils.java
│ │ ├── LocalPathUtils.java
│ │ ├── NameUtils.java
│ │ └── OrderStatus.java
│ │ └── wrapper
│ │ ├── ApidocApiWrapper.java
│ │ ├── ApidocParamClassWrapper.java
│ │ ├── BuilderWrapper.java
│ │ ├── JavaApiWrapper.java
│ │ ├── JavaEnumParamClassWrapper.java
│ │ ├── JavaParamClassWrapper.java
│ │ ├── JavaScriptApiWrapper.java
│ │ ├── JavaScriptParamClassWrapper.java
│ │ ├── JavaScriptWrapper.java
│ │ └── JavaWrapper.java
│ └── resources
│ └── org
│ └── rxjava
│ └── apikit
│ └── tool
│ ├── generator
│ ├── apidoc
│ │ ├── api.httl
│ │ ├── index.httl
│ │ ├── package.json
│ │ ├── paramClass.httl
│ │ └── test.httl
│ ├── es2015
│ │ ├── Api.d.httl
│ │ ├── Api.httl
│ │ ├── ParamClass.d.httl
│ │ ├── ParamClass.httl
│ │ ├── index.d.httl
│ │ ├── index.httl
│ │ └── package.json
│ └── java
│ │ ├── .gitignore
│ │ ├── ApiClass.httl
│ │ ├── EnumParamClass.httl
│ │ └── ParamClass.httl
│ └── httl.properties
├── rxjava-example
├── README.md
├── rxjava-gateway-example
│ ├── pom.xml
│ └── src
│ │ ├── assembly
│ │ ├── bin.xml
│ │ └── config
│ │ │ └── release
│ │ │ ├── Dockerfile
│ │ │ ├── bootstrap.yml
│ │ │ └── startup.sh
│ │ └── main
│ │ ├── java
│ │ └── org
│ │ │ └── rxjava
│ │ │ └── gateway
│ │ │ └── example
│ │ │ ├── CustomDiscoveryClientRouteDefinitionLocator.java
│ │ │ ├── CustomGatewayDiscoveryClientAutoConfiguration.java
│ │ │ ├── LoginInfoServiceImpl.java
│ │ │ ├── RxGatewayExampleApplication.java
│ │ │ └── RxGatewayExampleMain.java
│ │ └── resources
│ │ ├── META-INF
│ │ └── spring.factories
│ │ └── bootstrap.yml
└── rxjava-service-example
│ ├── build.sh
│ ├── k8s
│ └── rxjava-service-example.yaml
│ ├── pom.xml
│ └── src
│ ├── assembly
│ ├── bin.xml
│ └── config
│ │ └── release
│ │ ├── Dockerfile
│ │ ├── bootstrap.yml
│ │ └── startup.sh
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── rxjava
│ │ │ └── service
│ │ │ └── example
│ │ │ ├── RxApiBuildApplication.java
│ │ │ ├── RxServiceExampleApplication.java
│ │ │ ├── RxServiceExampleMain.java
│ │ │ ├── entity
│ │ │ └── Example.java
│ │ │ ├── form
│ │ │ ├── TestForm.java
│ │ │ └── TestSuperForm.java
│ │ │ ├── model
│ │ │ └── TestModel.java
│ │ │ ├── person
│ │ │ └── TestController.java
│ │ │ ├── repository
│ │ │ └── ExampleRepository.java
│ │ │ └── type
│ │ │ └── TestEnumType.java
│ └── resources
│ │ ├── bootstrap.yml
│ │ └── exceptions
│ │ └── exception_zh_CN.xml
│ └── test
│ └── java
│ └── org
│ └── rxjava
│ └── api
│ └── example
│ └── test
│ ├── TestApplication.java
│ └── TestContext.java
├── rxjava-gateway
└── pom.xml
├── rxjava-service
├── README.md
└── pom.xml
└── rxjava-spring
├── pom.xml
├── rxjava-spring-boot-core
├── pom.xml
└── src
│ └── main
│ └── java
│ └── org
│ └── rxjava
│ └── common
│ └── core
│ ├── RxJavaCoreAutoConfiguration.java
│ ├── annotation
│ ├── Check.java
│ ├── EnumValue.java
│ └── Login.java
│ ├── api
│ └── ReactiveHttpClientAdapter.java
│ ├── entity
│ ├── BaseEntity.java
│ ├── Image.java
│ ├── KeyValue.java
│ ├── LoginInfo.java
│ └── Video.java
│ ├── exception
│ ├── DefaultError.java
│ ├── ErrorMessage.java
│ ├── ErrorMessageException.java
│ ├── FieldError.java
│ ├── ForbiddenException.java
│ ├── JsonResponseStatusExceptionHandler.java
│ └── UnauthorizedException.java
│ ├── form
│ └── PageForm.java
│ ├── mongo
│ └── PageAgent.java
│ ├── service
│ ├── DefaultLoginInfoServiceImpl.java
│ └── LoginInfoService.java
│ ├── status
│ └── Status.java
│ ├── tools
│ └── RequestTool.java
│ └── utils
│ ├── ErrorMessageUtils.java
│ ├── FileRenameUtils.java
│ ├── JavaTimeModuleUtils.java
│ ├── JsonUtils.java
│ ├── KeyUtils.java
│ └── UUIDUtils.java
├── rxjava-spring-boot-starter-service
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── rxjava
│ │ └── service
│ │ └── starter
│ │ ├── RxJavaServiceAutoConfiguration.java
│ │ └── boot
│ │ ├── LoginInfoArgumentResolver.java
│ │ ├── RxJavaWebFluxConfigurer.java
│ │ ├── SecurityRequestMappingHandlerAdapter.java
│ │ └── ServiceDelegatingWebFluxConfiguration.java
│ └── resources
│ ├── META-INF
│ └── spring.factories
│ ├── application.yml
│ └── defaultExceptions
│ └── exception_zh_CN.xml
├── rxjava-spring-cloud-starter-bus
├── pom.xml
└── src
│ └── main
│ └── java
│ └── org
│ └── rxjava
│ └── common
│ └── bus
│ ├── BusEmitter.java
│ ├── BusEvent.java
│ ├── BusEventType.java
│ ├── BusReceiver.java
│ ├── EnableBus.java
│ ├── MessageReceiver.java
│ └── RxBusConfiguration.java
├── rxjava-spring-cloud-starter-gateway
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── rxjava
│ │ └── gateway
│ │ └── starter
│ │ ├── RxJavaGatewayAutoConfiguration.java
│ │ └── config
│ │ ├── AuthenticationToken.java
│ │ ├── CustomServerAuthenticationFailureHandler.java
│ │ ├── CustomServerAuthenticationSuccessHandler.java
│ │ └── RxJavaWebFluxSecurityConfig.java
│ └── resources
│ └── META-INF
│ └── spring.factories
└── rxjava-spring-mock-starter
├── pom.xml
└── src
└── main
├── java
└── org
│ └── rxjava
│ └── mock
│ └── starter
│ ├── RxJavaMockAutoConfiguration.java
│ └── config
│ └── MockProperties.java
└── resources
└── META-INF
└── spring.factories
/README.md:
--------------------------------------------------------------------------------
1 | #### 如果你觉得还行,请给个star,感谢你的支持🙏
2 | ## QQ交流群:828300414,加群答案:taro-jd
3 |
4 | ### 项目已发布到maven中央仓库,当前最新正式版本号为1.0.8,快照版本1.0.9
5 |
6 | ## rxjava项目说明
7 |
8 | ### 一、模块说明
9 |
10 | - [rxjava-apikit](https://mvnrepository.com/artifact/org.rxjava/rxjava-apikit):Api生成器(包括生成java客户端代码,JavaScript客户端代码)
11 | - [rxjava-example](https://mvnrepository.com/artifact/org.rxjava/rxjava-example):例子工程
12 | - [rxjava-gateway](https://mvnrepository.com/artifact/org.rxjava/rxjava-gateway):网关项目pom
13 | - [rxjava-service](https://mvnrepository.com/artifact/org.rxjava/rxjava-service):微服务项目pom
14 | - [rxjava-spring](https://mvnrepository.com/artifact/org.rxjava/rxjava-spring):对spring的一些整合
15 | - [rxjava](https://mvnrepository.com/artifact/org.rxjava/rxjava):依赖管理pom
16 |
17 | ### 二、Api生成器说明
18 |
19 | - [rxjava-apikit-core](https://mvnrepository.com/artifact/org.rxjava/rxjava-apikit-core):一些默认约定,如适配器
20 | - [rxjava-apikit-maven-plugin](https://mvnrepository.com/artifact/org.rxjava/rxjava-apikit-maven-plugin):maven插件,可直接执行命令生成api
21 | - [rxjava-apikit-tool](https://mvnrepository.com/artifact/org.rxjava/rxjava-apikit-tool):Api生成器实现代码
22 |
23 | - api插件maven生成器命令:进入微服务目录,执行命令 mvn clean rxjava-apikit:apis
24 |
25 | #### ssh方式有时候会出现Auth fail问题,建议暂时使用https方式
26 |
27 | ### 三、例子工程说明
28 |
29 | - rxjava-gateway-example:主要示例了如何创建api网关,以及演示了如何使用token换取loginInfo,并注入到router的微服务请求参数中
30 | - rxjava-service-example:主要示例了如何创建微服务,以及一些基础性的配置,并演示了如何手动创建api到test文件夹,并示例了k8s的一些基本配置
31 | - rxjava-security-example:主要示例了如何使用security创建授权微服务,并演示如何认证和授权
32 |
33 | ### 四、网关项目pom
34 |
35 | - pom暂时行只依赖了spring-cloud-gateway,此pom主要是将一些网关的依赖整合到一起
36 |
37 | ### 五、微服务项目pom
38 |
39 | - pom主要是整合依赖,并且演示了如何配置api生成器maven插件,以及一些包的命名规范
40 |
41 | ### 六、rxjava-spring
42 |
43 | - rxjava-spring-boot-core:主要是一些注解,常用实体类,异常处理,包装了mongo分页,以及一些帮助类
44 | - rxjava-spring-boot-starter-service:整合了spring自动配置,时间格式统一处理,登陆请求拦截,异常统一处理
45 | - rxjava-spring-cloud-starter-bus:做了一些消息总线的基础约定
46 | - rxjava-spring-cloud-starter-gateway:做了一些网关的一些基础配置
47 |
--------------------------------------------------------------------------------
/rxjava-apikit/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | org.rxjava
5 | rxjava
6 | 1.0.9-SNAPSHOT
7 |
8 | 4.0.0
9 | rxjava-apikit
10 | pom
11 |
12 | rxjava-apikit-core
13 | rxjava-apikit-tool
14 | rxjava-apikit-maven-plugin
15 |
16 |
17 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-core/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | org.rxjava
6 | rxjava-apikit
7 | 1.0.9-SNAPSHOT
8 |
9 | rxjava-apikit-core
10 | jar
11 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-core/src/main/java/org/rxjava/apikit/annotation/Ignore.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * 忽略生成Api
7 | * 默认为需要登陆
8 | */
9 | @Target(ElementType.METHOD)
10 | @Retention(RetentionPolicy.RUNTIME)
11 | @Documented
12 | public @interface Ignore {
13 | }
14 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-core/src/main/java/org/rxjava/apikit/client/ApiType.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.client;
2 |
3 |
4 | import java.lang.reflect.ParameterizedType;
5 | import java.lang.reflect.Type;
6 |
7 | /**
8 | * @author happy
9 | */
10 | public class ApiType implements ParameterizedType {
11 | private final Type[] types;
12 | private final Type raw;
13 |
14 | ApiType(Type raw, Type... types) {
15 | this.raw = raw;
16 | this.types = types;
17 | }
18 |
19 | @Override
20 | public Type[] getActualTypeArguments() {
21 | return this.types;
22 | }
23 |
24 | @Override
25 | public Type getRawType() {
26 | return this.raw;
27 | }
28 |
29 | @Override
30 | public Type getOwnerType() {
31 | return null;
32 | }
33 | }
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-core/src/main/java/org/rxjava/apikit/client/ApiUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.client;
2 |
3 | /**
4 | * @author happy
5 | */
6 |
7 | import java.io.UnsupportedEncodingException;
8 | import java.lang.reflect.Type;
9 | import java.net.URLEncoder;
10 | import java.util.Iterator;
11 | import java.util.List;
12 | import java.util.Map;
13 | import java.util.regex.Matcher;
14 | import java.util.regex.Pattern;
15 |
16 | public class ApiUtils {
17 | /**
18 | * 正则表达式名称
19 | */
20 | private static final Pattern NAMES_PATTERN = Pattern.compile("\\{([^/]+?)}");
21 |
22 | /**
23 | * 展开Uri组件
24 | */
25 | public static String expandUriComponent(String url, Map uriVariables) {
26 | if (url == null) {
27 | return null;
28 | } else if (url.indexOf(123) == -1) {
29 | return url;
30 | } else {
31 | Matcher matcher = NAMES_PATTERN.matcher(url);
32 |
33 | StringBuffer sb;
34 | String replacement;
35 | for (sb = new StringBuffer(); matcher.find(); matcher.appendReplacement(sb, replacement)) {
36 | String match = matcher.group(1);
37 | String variableName = getVariableName(match);
38 | Object variableValue = uriVariables.get(variableName);
39 | if (variableValue == null) {
40 | throw new RuntimeException("协议定义错误,需要参数未找到");
41 | }
42 |
43 | String variableValueString = getVariableValueAsString(variableValue);
44 |
45 | try {
46 | replacement = Matcher.quoteReplacement(URLEncoder.encode(variableValueString, "utf8"));
47 | } catch (UnsupportedEncodingException var10) {
48 | throw new RuntimeException(var10);
49 | }
50 | }
51 |
52 | matcher.appendTail(sb);
53 | return sb.toString();
54 | }
55 | }
56 |
57 | /**
58 | * 获取变量名
59 | */
60 | private static String getVariableName(String match) {
61 | int colonIdx = match.indexOf(58);
62 | return colonIdx != -1 ? match.substring(0, colonIdx) : match;
63 | }
64 |
65 | /**
66 | * 获取变量值并转化为字符串
67 | */
68 | private static String getVariableValueAsString(Object variableValue) {
69 | if (variableValue != null) {
70 | if (variableValue instanceof List) {
71 | List list = (List) variableValue;
72 | StringBuilder sb = new StringBuilder();
73 |
74 | Object item;
75 | for (Iterator var3 = list.iterator(); var3.hasNext(); sb.append(item)) {
76 | item = var3.next();
77 | if (sb.length() > 0) {
78 | sb.append(',');
79 | }
80 | }
81 |
82 | return sb.toString();
83 | } else {
84 | return variableValue.toString();
85 | }
86 | } else {
87 | return "";
88 | }
89 | }
90 |
91 | public static ApiType type(Type raw, Type... types) {
92 | return new ApiType(raw, types);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-core/src/main/java/org/rxjava/apikit/client/ClientAdapter.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.client;
2 |
3 | import reactor.core.publisher.Mono;
4 |
5 | import java.lang.reflect.Type;
6 | import java.util.List;
7 | import java.util.Map.Entry;
8 |
9 | /**
10 | * @author happy
11 | * 客户端适配器
12 | */
13 | public interface ClientAdapter {
14 | /**
15 | * 发起http请求
16 | *
17 | * @param method 请求方法{@link org.rxjava.apikit.core.HttpMethodType}
18 | * @param uri 请求的Uri
19 | * @param form Post请求表单数据
20 | * @param returnType 返回值类型
21 | */
22 | Mono request(String method, String uri, List> form, Type returnType);
23 | }
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-core/src/main/java/org/rxjava/apikit/core/HttpMethodType.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.core;
2 |
3 | /**
4 | * @author happy
5 | * Http请求方法类型
6 | */
7 | public enum HttpMethodType {
8 | /**
9 | * 获取
10 | */
11 | GET,
12 | /**
13 | * 创建
14 | */
15 | POST,
16 | /**
17 | * 全部更新
18 | */
19 | PUT,
20 | /**
21 | * 删除
22 | */
23 | DELETE,
24 | /**
25 | * 部分更新
26 | */
27 | PATCH;
28 | }
29 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-maven-plugin/src/main/java/org/rxjava/apikit/plugin/ApikitMojo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.plugin;
2 |
3 | import org.apache.maven.plugin.AbstractMojo;
4 | import org.apache.maven.plugins.annotations.Mojo;
5 | import org.apache.maven.plugins.annotations.Parameter;
6 | import org.apache.maven.plugins.annotations.ResolutionScope;
7 | import org.apache.maven.project.MavenProject;
8 | import org.rxjava.apikit.plugin.bean.Group;
9 | import org.rxjava.apikit.plugin.bean.Task;
10 |
11 | import java.util.List;
12 | import java.util.Map;
13 |
14 | /**
15 | * @author happy
16 | */
17 | @Mojo(
18 | name = "api",
19 | requiresDependencyCollection = ResolutionScope.RUNTIME,
20 | requiresDependencyResolution = ResolutionScope.RUNTIME
21 | )
22 | public class ApikitMojo extends AbstractMojo {
23 | @Parameter
24 | private List tasks;
25 |
26 | @Parameter
27 | private String rootPackage;
28 |
29 | @Parameter
30 | private String apiType;
31 |
32 | @Override
33 | public void execute() {
34 |
35 | Map pluginContext = getPluginContext();
36 | MavenProject project = (MavenProject) pluginContext.get("project");
37 | String[] compileSourceRoots = project
38 | .getCompileSourceRoots()
39 | .stream()
40 | .filter(str -> !str.contains("generated-sources/annotations"))
41 | .toArray(String[]::new);
42 |
43 | if (compileSourceRoots.length > 1) {
44 | throw new RuntimeException("Multiple compileSourceRoot is not supported");
45 | }
46 | //获取到java源码路径
47 | String javaSourcePath = compileSourceRoots[0];
48 |
49 | getLog().info("开始执行全部任务" + tasks + pluginContext);
50 |
51 | MavenUtils.generate(project, new Group(tasks, rootPackage, apiType), javaSourcePath, compileSourceRoots);
52 |
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-maven-plugin/src/main/java/org/rxjava/apikit/plugin/ApikitsMojo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.plugin;
2 |
3 | import org.apache.maven.execution.MavenSession;
4 | import org.apache.maven.plugin.AbstractMojo;
5 | import org.apache.maven.plugins.annotations.Mojo;
6 | import org.apache.maven.plugins.annotations.Parameter;
7 | import org.apache.maven.plugins.annotations.ResolutionScope;
8 | import org.apache.maven.project.MavenProject;
9 | import org.rxjava.apikit.plugin.bean.Group;
10 |
11 | import java.util.List;
12 |
13 | @Mojo(
14 | name = "apis",
15 | requiresDependencyCollection = ResolutionScope.RUNTIME,
16 | requiresDependencyResolution = ResolutionScope.RUNTIME
17 | )
18 | public class ApikitsMojo extends AbstractMojo {
19 | @Parameter
20 | private List groups;
21 |
22 | @Parameter(defaultValue = "${session}", readonly = true, required = true)
23 | private MavenSession session;
24 |
25 | @Override
26 | public void execute() {
27 | MavenProject project = session.getCurrentProject();
28 | String[] compileSourceRoots = project
29 | .getCompileSourceRoots()
30 | .stream()
31 | .filter(str -> !str.contains("generated-sources/annotations"))
32 | .toArray(String[]::new);
33 |
34 | if (compileSourceRoots.length > 1) {
35 | throw new RuntimeException("Multiple compileSourceRoot is not supported");
36 | }
37 | String sourcePath = compileSourceRoots[0];
38 | try {
39 | getLog().info("开始执行全部任务:" + groups);
40 | for (Group group : groups) {
41 | getLog().info("开始执行第一组:" + group);
42 | MavenUtils.generate(project, group, sourcePath, compileSourceRoots);
43 | getLog().info("结束第一组:" + group);
44 | }
45 | } catch (Exception e) {
46 | throw new RuntimeException(e);
47 | }
48 | }
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-maven-plugin/src/main/java/org/rxjava/apikit/plugin/MavenUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.plugin;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
5 | import org.apache.maven.artifact.DependencyResolutionRequiredException;
6 | import org.apache.maven.project.MavenProject;
7 | import org.codehaus.plexus.classworlds.realm.ClassRealm;
8 | import org.rxjava.apikit.plugin.bean.Group;
9 |
10 | import java.io.IOException;
11 | import java.lang.reflect.Method;
12 | import java.net.MalformedURLException;
13 | import java.net.URL;
14 | import java.net.URLClassLoader;
15 | import java.nio.file.Paths;
16 | import java.util.List;
17 | import java.util.Optional;
18 | import java.util.stream.Stream;
19 |
20 | /**
21 | * @author happy 2019-01-05 15:40
22 | */
23 | public class MavenUtils {
24 | public static final ObjectMapper MAPPER = new ObjectMapper();
25 |
26 | static {
27 | MAPPER.enableDefaultTyping(BasicPolymorphicTypeValidator.builder().build(), ObjectMapper.DefaultTyping.NON_FINAL);
28 | }
29 |
30 | public static void generate(MavenProject project, Group group, String sourcePath, String[] srcPaths) {
31 | ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
32 | try {
33 | ClassLoader loader = getUrlClassLoader(project);
34 | @SuppressWarnings("unchecked")
35 | Class generateUtilsClass = (Class) loader
36 | .loadClass(GenerateUtils.class.getName());
37 | Method generateMethod = generateUtilsClass.getMethod(
38 | "generate",
39 | String.class,
40 | String.class,
41 | String[].class
42 | );
43 | String groupJson = serialize(group);
44 | /*
45 | * 切换后续操作的classLoad加载器
46 | */
47 | Thread.currentThread().setContextClassLoader(loader);
48 | generateMethod.invoke(null, groupJson, sourcePath, srcPaths);
49 | } catch (Exception e) {
50 | throw new RuntimeException(e);
51 | } finally {
52 | //还原
53 | Thread.currentThread().setContextClassLoader(contextClassLoader);
54 | }
55 | }
56 |
57 |
58 | public final static String serialize(Object o) {
59 | try {
60 | return MAPPER.writeValueAsString(o);
61 | } catch (IOException e) {
62 | throw new RuntimeException(e.getMessage(), e);
63 | }
64 | }
65 |
66 |
67 | private static URLClassLoader getUrlClassLoader(MavenProject project) throws DependencyResolutionRequiredException {
68 | List compileClasspathElements = project.getCompileClasspathElements();
69 | List systemClasspathElements = project.getSystemClasspathElements();
70 | ClassRealm classLoader = (ClassRealm) MavenUtils.class.getClassLoader();
71 |
72 | Optional apiClassRealm = classLoader.getImportRealms().stream().filter((p) -> "maven.api".equals(p.getId())).findFirst();
73 |
74 | URL[] urls = Stream.concat(
75 | Stream.concat(
76 | compileClasspathElements.stream().map(MavenUtils::toUrl),
77 | systemClasspathElements.stream().map(MavenUtils::toUrl)
78 | ),
79 | Stream.of(classLoader.getURLs())
80 | ).toArray(URL[]::new);
81 |
82 | return apiClassRealm
83 | .map(classRealm -> new URLClassLoader(urls, classRealm))
84 | .orElseGet(() -> new URLClassLoader(urls));
85 | }
86 |
87 |
88 | private static URL toUrl(String spec) {
89 | try {
90 | return Paths.get(spec).toUri().toURL();
91 | } catch (MalformedURLException e) {
92 | throw new RuntimeException(e);
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-maven-plugin/src/main/java/org/rxjava/apikit/plugin/bean/AbstractTask.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.plugin.bean;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * @author happy
7 | */
8 | @Data
9 | abstract class AbstractTask implements Task {
10 | private String outPath;
11 | }
12 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-maven-plugin/src/main/java/org/rxjava/apikit/plugin/bean/GitTask.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.plugin.bean;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author happy
10 | */
11 | @Getter
12 | @Setter
13 | public class GitTask extends AbstractTask {
14 | private String url;
15 | private String user;
16 | private String password;
17 | private String authorEmail = "apikit@rxjava.org";
18 | private String authorName = "apikit";
19 | private Task task;
20 | private String branch = "master";
21 | private String outPath;
22 | private List deleteUris;
23 | }
24 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-maven-plugin/src/main/java/org/rxjava/apikit/plugin/bean/Group.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.plugin.bean;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 | import lombok.Setter;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @author happy
12 | */
13 | @Getter
14 | @Setter
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | public class Group {
18 | private List tasks;
19 | private String rootPackage;
20 | private String apiType;
21 | }
22 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-maven-plugin/src/main/java/org/rxjava/apikit/plugin/bean/JavaClientTask.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.plugin.bean;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * @author happy
8 | */
9 | @Getter
10 | @Setter
11 | public class JavaClientTask extends AbstractTask {
12 | private String nameMaperSource;
13 | private String nameMaperDist;
14 | private String outRootPackage;
15 | }
16 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-maven-plugin/src/main/java/org/rxjava/apikit/plugin/bean/JavaScriptClientTask.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.plugin.bean;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * @author happy
8 | */
9 | @Getter
10 | @Setter
11 | public class JavaScriptClientTask extends AbstractTask {
12 | private String nameMaperSource;
13 | private String nameMaperDist;
14 | private String outRootPackage;
15 | private String serviceId;
16 | }
17 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-maven-plugin/src/main/java/org/rxjava/apikit/plugin/bean/Task.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.plugin.bean;
2 |
3 | /**
4 | * @author happy
5 | */
6 | public interface Task {
7 | }
8 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/ReadMe.md:
--------------------------------------------------------------------------------
1 | 命名说明:
2 |
3 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | org.rxjava
5 | rxjava-apikit
6 | 1.0.9-SNAPSHOT
7 |
8 | rxjava-apikit-tool
9 | jar
10 |
11 |
12 | org.rxjava
13 | rxjava-apikit-core
14 | ${project.parent.version}
15 |
16 |
17 | org.mongodb
18 | bson
19 |
20 |
21 | org.eclipse.jgit
22 | org.eclipse.jgit
23 |
24 |
25 | org.eclipse.jgit
26 | org.eclipse.jgit.pgm
27 |
28 |
29 | org.slf4j
30 | slf4j-log4j12
31 |
32 |
33 | org.eclipse.jetty
34 | jetty-servlet
35 |
36 |
37 |
38 |
39 | org.eclipse.jdt
40 | org.eclipse.jdt.core
41 |
42 |
43 | javax.validation
44 | validation-api
45 |
46 |
47 | org.springframework
48 | spring-context
49 |
50 |
51 | org.springframework
52 | spring-webflux
53 |
54 |
55 | com.thoughtworks.paranamer
56 | paranamer
57 |
58 |
59 | org.javassist
60 | javassist
61 |
62 |
63 | io.github.lukehutch
64 | fast-classpath-scanner
65 |
66 |
67 | com.github.httl
68 | httl
69 |
70 |
71 | commons-io
72 | commons-io
73 |
74 |
75 | org.slf4j
76 | slf4j-api
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/ApiGenerateManager.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool;
2 |
3 | import lombok.Getter;
4 | import lombok.NoArgsConstructor;
5 | import lombok.Setter;
6 | import org.rxjava.apikit.tool.analyse.impl.ControllerAnalyse;
7 | import org.rxjava.apikit.tool.analyse.impl.EnumClassAnalyse;
8 | import org.rxjava.apikit.tool.analyse.impl.ParamClassAnalyse;
9 | import org.rxjava.apikit.tool.generator.Context;
10 | import org.rxjava.apikit.tool.generator.Generator;
11 | import org.rxjava.apikit.tool.utils.LocalPathUtils;
12 |
13 | /**
14 | * @author happy
15 | * Api生成管理器
16 | */
17 | @Getter
18 | @Setter
19 | @NoArgsConstructor
20 | public class ApiGenerateManager {
21 | /**
22 | * src/main/java的绝对路径
23 | */
24 | private String javaSourceDir;
25 | /**
26 | * 需要分析的包路径
27 | */
28 | private String rootPackage;
29 | /**
30 | * 文件编码
31 | */
32 | private String fileCharset = "utf8";
33 | /**
34 | * 文件扩展名
35 | */
36 | private String fileSuffix = ".java";
37 | /**
38 | * 需要分析的包文件夹路径
39 | */
40 | private String rootDirPath;
41 | /**
42 | * 上下文
43 | */
44 | private Context context;
45 | private String[] srcPaths;
46 |
47 | public void generate(Generator generator) throws Exception {
48 | generator.generate(context);
49 | }
50 |
51 | /**
52 | * 开始分析指定文件夹指定包的api及param信息
53 | *
54 | * @param javaSourceDir 源码文件夹路径
55 | * @param rootPackage java包路径
56 | * @return api生成管理器
57 | */
58 | public static ApiGenerateManager analyse(String javaSourceDir, String rootPackage) {
59 | ApiGenerateManager manager = new ApiGenerateManager();
60 | manager.javaSourceDir = javaSourceDir;
61 | manager.rootPackage = rootPackage;
62 | //获取java源码的文件夹路径
63 | manager.rootDirPath = LocalPathUtils.packToPath(javaSourceDir, rootPackage).getAbsolutePath();
64 | manager.context = Context.create(rootPackage, javaSourceDir);
65 | //分析控制器信息并保存到上下文
66 | ControllerAnalyse.create().analyse(manager.context);
67 | //分析参数类型信息并保存到上下文
68 | ParamClassAnalyse.create().analyse(manager.context);
69 | //分析枚举类型信息并保存到上下文
70 | EnumClassAnalyse.create().analyse(manager.context);
71 | return manager;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/analyse/Analyse.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.analyse;
2 |
3 | import org.rxjava.apikit.tool.generator.Context;
4 |
5 | /**
6 | * @author happy
7 | * 分析器
8 | */
9 | public interface Analyse {
10 | void analyse(Context context);
11 | }
12 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/generator/ApiContext.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.generator;
2 |
3 | import lombok.Data;
4 | import org.rxjava.apikit.tool.info.ControllerInfo;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | /**
10 | * @author happy 2019/10/26 22:03
11 | * Api上下文
12 | */
13 | @Data
14 | public class ApiContext {
15 | private List controllerInfos=new ArrayList<>();
16 | }
17 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/generator/ClassNameMapper.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.generator;
2 |
3 | import java.util.Set;
4 |
5 | /**
6 | * @author happy
7 | * 类名Mapper接口
8 | */
9 | public interface ClassNameMapper {
10 | String apply(Set nameSet, String packageName, String name);
11 | }
12 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/generator/Context.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.generator;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import org.apache.commons.lang3.ObjectUtils;
6 | import org.rxjava.apikit.tool.info.*;
7 | import org.rxjava.apikit.tool.wrapper.BuilderWrapper;
8 |
9 | import java.util.*;
10 |
11 | /**
12 | * 上下文
13 | *
14 | * @author happy
15 | */
16 | @Setter
17 | @Getter
18 | public class Context {
19 |
20 | public static Context create(String rootPackage, String javaFilePath) {
21 | Context context = new Context();
22 | context.rootPackage = rootPackage;
23 | context.javaFilePath = javaFilePath;
24 | return context;
25 | }
26 |
27 | /**
28 | * 包信息
29 | */
30 | protected PackageInfo apis = new PackageInfo<>();
31 | /**
32 | * 主包路径
33 | */
34 | private String rootPackage;
35 | /**
36 | * Java文件路径
37 | */
38 | private String javaFilePath;
39 | /**
40 | * 消息包装map
41 | */
42 | private Map> paramClassWrapperMap;
43 | /**
44 | * 消息包装map
45 | */
46 | private Map> enumParamClassWrapperMap;
47 | /**
48 | * 枚举类
49 | */
50 | private Set enumInfoSet = new HashSet<>();
51 |
52 | private TreeMap fullNameParamMap = new TreeMap<>(Comparator.comparing(r -> r));
53 |
54 | public void addParamClassInfo(ClassInfo key, ParamClassInfo paramClassInfo) {
55 | paramMap.put(key, paramClassInfo);
56 | fullNameParamMap.put(key.getFullName(), paramClassInfo);
57 | }
58 |
59 | public void addEnumParamClassInfo(ClassInfo key, EnumParamClassInfo enumParamClassInfo) {
60 | enumParamMap.put(key, enumParamClassInfo);
61 | }
62 |
63 | private TreeMap paramMap = new TreeMap<>(Comparator.comparing(ClassInfo::getFullName));
64 |
65 | private TreeMap enumParamMap = new TreeMap<>(Comparator.comparing(ClassInfo::getFullName));
66 |
67 | public void addApi(ApiClassInfo apiInfo) {
68 | apis.add(apiInfo.getPackageName(), apiInfo);
69 | }
70 |
71 | public Collection getParamClassInfos() {
72 | return paramMap.values();
73 | }
74 |
75 | public Collection getEnumParamClassInfos() {
76 | return enumParamMap.values();
77 | }
78 |
79 | public BuilderWrapper getParamWrapper(String fullName) {
80 | return paramClassWrapperMap.get(fullName);
81 | }
82 |
83 | public BuilderWrapper extends ClassInfo> getParamOrEnumWrapper(String fullName) {
84 | BuilderWrapper paramClassInfoBuilderWrapper = paramClassWrapperMap.get(fullName);
85 | if (ObjectUtils.isEmpty(paramClassInfoBuilderWrapper)) {
86 | return enumParamClassWrapperMap.get(fullName);
87 | }
88 | return paramClassInfoBuilderWrapper;
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/generator/Generator.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.generator;
2 |
3 | /**
4 | * @author happy
5 | * 生成器接口
6 | */
7 | public interface Generator {
8 | /**
9 | * 根据上下文生成
10 | *
11 | * @param context 上下文
12 | */
13 | void generate(Context context) throws Exception;
14 |
15 | /**
16 | * 获取输出路径
17 | *
18 | * @return 文件输出路径
19 | */
20 | String getOutPath();
21 |
22 | /**
23 | * 设置版本号
24 | *
25 | * @param version 版本号
26 | */
27 | void setVersion(String version);
28 | }
29 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/generator/NameMaper.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.generator;
2 |
3 | /**
4 | * @author happy
5 | */
6 | public interface NameMaper {
7 | String apply(String name);
8 | }
9 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/generator/PackageNameMapper.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.generator;
2 |
3 | /**
4 | * @author happy
5 | * 包名Mapper
6 | */
7 | public interface PackageNameMapper {
8 | String apply(String sourceRootPackage, String packageName);
9 | }
10 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/generator/impl/AbstractCommonGenerator.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.generator.impl;
2 |
3 | import org.rxjava.apikit.tool.utils.LocalPathUtils;
4 | import org.rxjava.apikit.tool.wrapper.BuilderWrapper;
5 |
6 | import java.io.File;
7 |
8 | /**
9 | * @author happy
10 | * 抽象类:通用生成器
11 | */
12 | public abstract class AbstractCommonGenerator extends AbstractHttlGenerator {
13 | /**
14 | * 创建Api文件
15 | */
16 | File createApiFile(BuilderWrapper wrapper, String suffix) {
17 | String fullDistPackage = wrapper.getFullDistPackage();
18 | if ("d.ts".equals(suffix) || ("js".equals(suffix))) {
19 | fullDistPackage = "";
20 | }
21 | return LocalPathUtils.packToPath(outPath, fullDistPackage, wrapper.getDistClassName(), "." + suffix);
22 | }
23 |
24 | /**
25 | * 创建参数类文件
26 | */
27 | File createParamClassFile(BuilderWrapper wrapper, String suffix) {
28 | return LocalPathUtils.packToPath(outPath, wrapper.getFullDistPackage(wrapper.getDistFolder()), wrapper.getDistClassName(), "." + suffix);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/generator/impl/AbstractHttlGenerator.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.generator.impl;
2 |
3 | import org.rxjava.apikit.tool.generator.AbstractGenerator;
4 | import org.rxjava.apikit.tool.utils.HttlUtils;
5 | import org.rxjava.apikit.tool.wrapper.BuilderWrapper;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import java.io.File;
10 | import java.util.HashMap;
11 | import java.util.Map;
12 |
13 | /**
14 | * @author happy
15 | * 抽象类:Httl模板引擎生成器
16 | */
17 | abstract class AbstractHttlGenerator extends AbstractGenerator {
18 | private static final Logger log = LoggerFactory.getLogger(AbstractHttlGenerator.class);
19 |
20 | /**
21 | * 执行模块文件生成
22 | */
23 | void executeModule(BuilderWrapper wrapper, String templPath, File file) throws Exception {
24 | log.info("开始生成文件:{}, templ:{}", file.getAbsolutePath(), templPath);
25 | Map params = new HashMap<>();
26 | params.put("classInfo", wrapper.getClassInfo());
27 | params.put("wrapper", wrapper);
28 | HttlUtils.renderFile(file, params, templPath);
29 | log.info("结束生成文件:{}, templ:{}", file.getAbsolutePath(), templPath);
30 | }
31 |
32 | void execute(Map parameters, String templPath, File file) throws Exception {
33 |
34 | log.info("开始生成文件:{}, templ:{}", file.getAbsolutePath(), templPath);
35 | HttlUtils.renderFile(file, parameters, templPath);
36 | log.info("结束生成文件:{}, templ:{}", file.getAbsolutePath(), templPath);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/generator/impl/ApidocGenerator.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.generator.impl;
2 |
3 | import org.rxjava.apikit.tool.generator.ApiContext;
4 | import org.rxjava.apikit.tool.info.ClassBaseInfo;
5 | import org.rxjava.apikit.tool.utils.HttlUtils;
6 | import org.rxjava.apikit.tool.utils.LocalPathUtils;
7 |
8 | import java.io.File;
9 | import java.io.IOException;
10 | import java.text.ParseException;
11 | import java.util.HashMap;
12 | import java.util.List;
13 | import java.util.Map;
14 | import java.util.stream.Collectors;
15 |
16 | public class ApidocGenerator {
17 | public void generator(String javaOutApiPath, ApiContext apiContext) {
18 | List nameList = apiContext.getControllerInfos().stream()
19 | .map(ClassBaseInfo::getSimpleName)
20 | .collect(Collectors.toList());
21 |
22 | Map params = new HashMap<>();
23 | params.put("nameList", nameList);
24 | File file = LocalPathUtils.packToPath(javaOutApiPath, "test", "api.java");
25 | try {
26 | HttlUtils.renderFile(file, params, getTemplateFile("test.httl"));
27 | } catch (IOException | ParseException e) {
28 | e.printStackTrace();
29 | }
30 | }
31 |
32 | private String getTemplateFile(String name) {
33 | return "/org/rxjava/apikit/tool/generator/apidoc/" + name;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/generator/impl/DefaultClassNameMapper.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.generator.impl;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.rxjava.apikit.tool.generator.ClassNameMapper;
5 |
6 | import java.util.Set;
7 |
8 | /**
9 | * @author happy
10 | * 默认类名Mapper
11 | */
12 | public class DefaultClassNameMapper implements ClassNameMapper {
13 | @Override
14 | public String apply(Set nameSet, String packageName, String name) {
15 | if (!nameSet.contains(name)) {
16 | return name;
17 | }
18 | String[] packParts = packageName.split("\\.");
19 |
20 | StringBuilder nameSb = new StringBuilder(name);
21 | for (int i = packParts.length - 1; i >= 0; i--) {
22 | String part = packParts[i];
23 | if (StringUtils.isNotEmpty(part)) {
24 | nameSb.insert(0, Character.toUpperCase(Character.toUpperCase(part.codePointAt(0))));
25 | nameSb.insert(0, part.substring(1));
26 | }
27 | String curName = nameSb.toString();
28 | if (!nameSet.contains(curName)) {
29 | return curName;
30 | }
31 | }
32 |
33 | for (int i = 0; ; i++) {
34 | String curName = name + i;
35 | if (!nameSet.contains(curName)) {
36 | return curName;
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/generator/impl/DefaultPackageNameMapper.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.generator.impl;
2 |
3 | import org.rxjava.apikit.tool.generator.PackageNameMapper;
4 |
5 | /**
6 | * @author happy
7 | * 默认的包名Mapper
8 | */
9 | public class DefaultPackageNameMapper implements PackageNameMapper {
10 | @Override
11 | public String apply(String sourceRootPackage, String packageName) {
12 | boolean isInPack = packageName.startsWith(sourceRootPackage);
13 | if (isInPack) {
14 | String dist = packageName.substring(sourceRootPackage.length());
15 | if(dist.startsWith(".")){
16 | return dist.substring(1);
17 | }
18 | return dist;
19 | }else{
20 | int index = packageName.lastIndexOf(".");
21 | if(index>-1){
22 | String dist = packageName.substring(index, packageName.length());
23 | if(dist.startsWith(".")){
24 | return dist.substring(1);
25 | }
26 | return dist;
27 | }
28 | }
29 | return "core";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/generator/impl/JavaClientApiGenerator.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.generator.impl;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import org.rxjava.apikit.tool.info.ApiClassInfo;
6 | import org.rxjava.apikit.tool.info.EnumParamClassInfo;
7 | import org.rxjava.apikit.tool.info.ParamClassInfo;
8 | import org.rxjava.apikit.tool.wrapper.BuilderWrapper;
9 | import org.rxjava.apikit.tool.wrapper.JavaApiWrapper;
10 | import org.rxjava.apikit.tool.wrapper.JavaEnumParamClassWrapper;
11 | import org.rxjava.apikit.tool.wrapper.JavaParamClassWrapper;
12 |
13 | import java.io.File;
14 |
15 | /**
16 | * @author happy
17 | * Java客户端api生成器
18 | */
19 | @Setter
20 | @Getter
21 | public class JavaClientApiGenerator extends AbstractCommonGenerator {
22 |
23 | public JavaClientApiGenerator(String rootPackage,String outPath) {
24 | setOutRootPackage(rootPackage);
25 | setOutPath(outPath);
26 | }
27 |
28 | public JavaClientApiGenerator() {
29 | }
30 |
31 | @Override
32 | public void generateBaseFile() {
33 |
34 | }
35 |
36 | /**
37 | * 生成java客户端Api文件
38 | */
39 | @Override
40 | public void generateApiFile(ApiClassInfo apiInfo) throws Exception {
41 | JavaApiWrapper wrapper = new JavaApiWrapper(
42 | context, apiInfo, outRootPackage, apiNameMaper
43 | );
44 | File file = createApiFile(wrapper, "java");
45 | executeModule(wrapper, "/org/rxjava/apikit/tool/generator/java/ApiClass.httl", file);
46 | }
47 |
48 | /**
49 | * 生成参数文件
50 | */
51 | @Override
52 | public void generateParamFile(BuilderWrapper wrapper) throws Exception {
53 | File file = createParamClassFile(wrapper, "java");
54 | executeModule(
55 | wrapper,
56 | "/org/rxjava/apikit/tool/generator/java/ParamClass.httl",
57 | file
58 | );
59 | }
60 |
61 | @Override
62 | public void generateEnumParamFile(BuilderWrapper wrapper) throws Exception {
63 | File file = createParamClassFile(wrapper, "java");
64 | executeModule(
65 | wrapper,
66 | "/org/rxjava/apikit/tool/generator/java/EnumParamClass.httl",
67 | file
68 | );
69 | }
70 |
71 | /**
72 | * 创建Java类包装器
73 | * @param paramClassInfo 参数类信息
74 | * @param distPack 发布的包文件夹名
75 | * @param fileName 文件名
76 | */
77 | @Override
78 | protected JavaParamClassWrapper createParamClassWarpper(ParamClassInfo paramClassInfo, String distPack, String fileName) {
79 | JavaParamClassWrapper javaClassWrapper = new JavaParamClassWrapper(context, paramClassInfo, outRootPackage);
80 | javaClassWrapper.setDistFolder(distPack);
81 | return javaClassWrapper;
82 | }
83 |
84 | /**
85 | * 创建Java枚举类包装器
86 | * @param enumParamClassInfo 参数类信息
87 | * @param distPack 发布的包文件夹名
88 | * @param fileName 文件名
89 | */
90 | @Override
91 | protected JavaEnumParamClassWrapper createEnumParamClassWarpper(EnumParamClassInfo enumParamClassInfo, String distPack, String fileName) {
92 | JavaEnumParamClassWrapper javaEnumParamClassWrapper = new JavaEnumParamClassWrapper(context, enumParamClassInfo, outRootPackage);
93 | javaEnumParamClassWrapper.setDistFolder(distPack);
94 | return javaEnumParamClassWrapper;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/generator/impl/PatternNameMaper.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.generator.impl;
2 |
3 | import org.rxjava.apikit.tool.generator.NameMaper;
4 |
5 | import java.util.regex.Matcher;
6 | import java.util.regex.Pattern;
7 |
8 | /**
9 | * @author happy
10 | */
11 | public class PatternNameMaper implements NameMaper {
12 |
13 | /**
14 | * 一个正则表达式解压需要的信息从服务ID获取
15 | * "(?.*)-(?v.*$)"
16 | */
17 | private Pattern sourcePattern;
18 | /**
19 | * 一个正则表达式关联命名分组定义在服务部分
20 | * "${version}/${name}"
21 | */
22 | private String distPattern;
23 |
24 | @Override
25 | public String apply(String name) {
26 | Matcher matcher = this.sourcePattern.matcher(name);
27 | String distName = matcher.replaceFirst(this.distPattern);
28 | distName = clean(distName);
29 | return (hasText(distName) ? distName : name);
30 | }
31 |
32 | public PatternNameMaper(String sourcePattern, String distPattern) {
33 | this.sourcePattern = Pattern.compile(sourcePattern);
34 | this.distPattern = distPattern;
35 | }
36 |
37 | private String clean(final String route) {
38 | String routeToClean = route.replaceAll("/{2,}", "/");
39 | if (routeToClean.startsWith("/")) {
40 | routeToClean = routeToClean.substring(1);
41 | }
42 | if (routeToClean.endsWith("/")) {
43 | routeToClean = routeToClean.substring(0, routeToClean.length() - 1);
44 | }
45 | return routeToClean;
46 | }
47 |
48 | private static boolean hasLength(CharSequence str) {
49 | return str != null && str.length() > 0;
50 | }
51 |
52 | private static boolean hasText(CharSequence str) {
53 | if (!hasLength(str)) {
54 | return false;
55 | } else {
56 | int strLen = str.length();
57 |
58 | for (int i = 0; i < strLen; ++i) {
59 | if (!Character.isWhitespace(str.charAt(i))) {
60 | return true;
61 | }
62 | }
63 |
64 | return false;
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/AnnotationInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | /**
10 | * @author happy
11 | */
12 | @Getter
13 | @Setter
14 | public class AnnotationInfo {
15 | private ClassTypeInfo typeInfo;
16 |
17 | private List args = new ArrayList<>();
18 | }
19 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/ApiClassInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import org.rxjava.apikit.core.HttpMethodType;
4 |
5 | import java.util.ArrayList;
6 | import java.util.HashMap;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | /**
11 | * @author happy
12 | * Api类信息
13 | */
14 | public class ApiClassInfo extends ClassInfo {
15 | /**
16 | * url作为key的map
17 | */
18 | private Map> methodUrlMap = new HashMap<>();
19 | /**
20 | * 方法名methodName作为key的map
21 | */
22 | private Map methodNameMap = new HashMap<>();
23 | /**
24 | * api方法列表
25 | */
26 | private List apiMethodList = new ArrayList<>();
27 | /**
28 | * 添加api方法信息
29 | */
30 | public void addApiMethod(ApiMethodInfo apiMethodInfo) {
31 | Map map = methodUrlMap.computeIfAbsent(apiMethodInfo.getUrl(), k -> new HashMap<>());
32 | if (map.put(apiMethodInfo.getType(), apiMethodInfo) != null) {
33 | throw new RuntimeException(apiMethodInfo + "apiMethodInfo严重错误,重复的定义:url" + apiMethodInfo.getUrl() + ",type:" + apiMethodInfo.getType());
34 | }
35 | if (methodNameMap.put(apiMethodInfo.getMethodName(), apiMethodInfo) != null) {
36 | throw new RuntimeException(apiMethodInfo + "apiMethodInfo严重错误,重复的函数名称" + apiMethodInfo.getMethodName() + ",type:" + apiMethodInfo.getType());
37 | }
38 | apiMethodInfo.setIndex(apiMethodList.size());
39 | apiMethodList.add(apiMethodInfo);
40 | }
41 |
42 | public List getApiMethodList() {
43 | return apiMethodList;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/ApiInputClassInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 |
4 | import lombok.Getter;
5 | import lombok.Setter;
6 |
7 | /**
8 | * @author happy
9 | * Api方法输入类
10 | */
11 | @Setter
12 | @Getter
13 | public class ApiInputClassInfo extends FieldInfo {
14 | private boolean pathVariable = false;
15 | private boolean formParam = false;
16 |
17 | public ApiInputClassInfo(String name, ClassTypeInfo typeInfo) {
18 | super(name, typeInfo);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/ApiMethodInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Data;
4 | import org.apache.commons.collections4.CollectionUtils;
5 | import org.rxjava.apikit.core.HttpMethodType;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 | import java.util.stream.Collectors;
10 | import java.util.stream.Stream;
11 |
12 | /**
13 | * @author happy
14 | * Api方法信息
15 | */
16 | @Data
17 | public class ApiMethodInfo {
18 | /**
19 | * 索引号
20 | */
21 | private int index;
22 | /**
23 | * 方法名
24 | */
25 | private String methodName;
26 | /**
27 | * 方法请求url
28 | */
29 | private String url;
30 | /**
31 | * Http请求方法类型,默认为Get
32 | */
33 | private HttpMethodType[] httpMethodTypes = new HttpMethodType[]{HttpMethodType.GET};
34 | /**
35 | * 原始类型
36 | */
37 | private ClassTypeInfo returnClass;
38 | /**
39 | * 返回值的类型
40 | */
41 | private ClassTypeInfo resultDataType;
42 | /**
43 | * 参数列表
44 | */
45 | private ArrayList params = new ArrayList<>();
46 | /**
47 | * 路径参数列表
48 | */
49 | private ArrayList pathParams = new ArrayList<>();
50 | /**
51 | * 表单参数列表
52 | */
53 | private ArrayList formParams = new ArrayList<>();
54 | /**
55 | * java注释信息
56 | */
57 | private JavaDocInfo javaDocInfo;
58 | /**
59 | * 是否需要登陆
60 | */
61 | private boolean login = true;
62 |
63 | public HttpMethodType getType() {
64 | return httpMethodTypes.length > 0 ? httpMethodTypes[0] : null;
65 | }
66 |
67 | public void addParam(ApiInputClassInfo param) {
68 | params.add(param);
69 | if (param.isPathVariable()) {
70 | pathParams.add(param);
71 | }
72 | if (param.isFormParam()) {
73 | formParams.add(param);
74 | }
75 | if (formParams.size() > 1) {
76 | throw new RuntimeException("分析错误!暂时只支持单表单");
77 | }
78 | }
79 |
80 | protected void findTypes(ClassTypeInfo type, List list) {
81 | list.add(type);
82 | if (CollectionUtils.isNotEmpty(type.getTypeArguments())) {
83 | type.getTypeArguments().forEach(t -> findTypes(t, list));
84 | }
85 | }
86 |
87 | public List getAllTypes() {
88 | return Stream.of(this)
89 | .flatMap(m -> {
90 | List types = new ArrayList<>();
91 | types.add(m.getResultDataType());
92 | m.getParams().forEach(p -> types.add(p.getTypeInfo()));
93 | return types.stream();
94 | })
95 | .flatMap(type -> {
96 | List types = new ArrayList<>();
97 | findTypes(type, types);
98 | return types.stream();
99 | })
100 | .filter(typeInfo -> typeInfo.getType().equals(ClassTypeInfo.Type.OTHER))
101 | .filter(typeInfo -> !typeInfo.isCollection())
102 | .filter(typeInfo -> !typeInfo.isGeneric())
103 | .distinct()
104 | .collect(Collectors.toList());
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/ClassBaseInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * @author happy 2019/10/27 17:56
8 | * 类基本信息
9 | */
10 | @Getter
11 | @Setter
12 | public class ClassBaseInfo {
13 | /**
14 | * 所在包(org.rxjava.apikit.tool.info)
15 | * 包名为null代表为基本类型:如int,long等
16 | */
17 | private String packageName;
18 | /**
19 | * 简单类名(ClassBaseInfo)
20 | */
21 | private String simpleName;
22 | /**
23 | * 全类名(org.rxjava.apikit.tool.info.ClassBaseInfo)
24 | */
25 | private String name;
26 | }
27 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/ClassInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 |
4 | import lombok.EqualsAndHashCode;
5 | import lombok.Getter;
6 | import lombok.NoArgsConstructor;
7 | import lombok.Setter;
8 |
9 | /**
10 | * @author happy
11 | */
12 | @Setter
13 | @Getter
14 | @EqualsAndHashCode
15 | @NoArgsConstructor
16 | public class ClassInfo {
17 | /**
18 | * Java文档信息
19 | */
20 | protected JavaDocInfo javaDocInfo;
21 | /**
22 | * 包名
23 | */
24 | private String packageName;
25 | /**
26 | * 类名
27 | */
28 | private String className;
29 |
30 | public String getFullName() {
31 | return packageName + "." + className;
32 | }
33 |
34 | public ClassInfo(String packageName, String className) {
35 | this.packageName = packageName;
36 | this.className = className;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/ControllerInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import org.rxjava.apikit.tool.type.ApiType;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * @author happy 2019/10/26 22:22
11 | * 控制器信息
12 | */
13 | @Getter
14 | @Setter
15 | public class ControllerInfo extends ClassBaseInfo{
16 | /**
17 | * 控制器请求方法列表
18 | */
19 | private List methodInfos;
20 | /**
21 | * api接口类型
22 | * person:用户
23 | * admin:管理
24 | * inner:内部
25 | */
26 | private ApiType apiType;
27 | }
28 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/ControllerMethodInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Data;
4 | import org.rxjava.apikit.core.HttpMethodType;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | /**
10 | * @author happy 2019/10/26 22:32
11 | * 控制器方法信息
12 | */
13 | @Data
14 | public class ControllerMethodInfo {
15 | /**
16 | * 方法名
17 | */
18 | private String methodName;
19 | /**
20 | * 请求url
21 | */
22 | private String requestUrl;
23 | /**
24 | * http请求方法数组
25 | */
26 | private HttpMethodType[] httpMethodTypes;
27 | /**
28 | * 输入参数信息列表
29 | */
30 | private List inputParamInfos = new ArrayList<>();
31 | /**
32 | * 输出参数信息
33 | */
34 | private ParamInfo returnParamInfo;
35 |
36 | public void addInputParams(InputParamInfo inputParamInfo) {
37 | inputParamInfos.add(inputParamInfo);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/EnumConstantInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class EnumConstantInfo {
7 | private String name;
8 | private int ordinal;
9 | }
10 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/EnumParamClassInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import org.apache.commons.collections4.CollectionUtils;
6 | import org.eclipse.jdt.core.dom.TagElement;
7 | import org.eclipse.jdt.core.dom.TextElement;
8 | import org.eclipse.jdt.core.dom.TypeDeclaration;
9 |
10 | import java.util.*;
11 |
12 | /**
13 | * @author happy
14 | * 方法参数类信息(入参和出参)
15 | */
16 | @Getter
17 | @Setter
18 | public class EnumParamClassInfo extends ClassInfo {
19 | private List properties = new ArrayList<>();
20 | private Map propertiesMap = new HashMap<>();
21 | /**
22 | * 父类类型信息
23 | */
24 | private ClassTypeInfo superType;
25 | private Class clazz;
26 | protected TypeDeclaration type;
27 | private List typeParameters = new ArrayList<>();
28 | /**
29 | * 枚举常量信息
30 | */
31 | private List enumConstantInfos;
32 |
33 | public JavaDocInfo getClassComment() {
34 | return transform(type.getJavadoc());
35 | }
36 |
37 | protected static JavaDocInfo transform(org.eclipse.jdt.core.dom.Javadoc javadoc) {
38 | if (javadoc == null) {
39 | return null;
40 | }
41 | JavaDocInfo javadocInfo = new JavaDocInfo();
42 | List tags = javadoc.tags();
43 | for (Object tag : tags) {
44 | TagElement tagElement = (TagElement) tag;
45 | String tagName = tagElement.getTagName();
46 |
47 | List fragments = tagElement.fragments();
48 | ArrayList fragmentsInfo = new ArrayList<>();
49 | for (Object fragment : fragments) {
50 | if (fragment instanceof TextElement) {
51 | TextElement textElement = (TextElement) fragment;
52 | fragmentsInfo.add(textElement.getText());
53 | } else {
54 | fragmentsInfo.add(fragment.toString());
55 | }
56 | }
57 | javadocInfo.add(tagName, fragmentsInfo);
58 | }
59 | return javadocInfo;
60 | }
61 |
62 | public void addTypeParameter(String typeParameter) {
63 | typeParameters.add(typeParameter);
64 | }
65 |
66 | public void add(PropertyInfo attributeInfo) {
67 | properties.add(attributeInfo);
68 | propertiesMap.put(attributeInfo.getFieldName(), attributeInfo);
69 | }
70 |
71 | public void sortPropertys() {
72 | properties.sort(Comparator.comparing(FieldInfo::getFieldName));
73 | }
74 |
75 |
76 | public boolean hasGenerics() {
77 | return CollectionUtils.isNotEmpty(getTypeParameters());
78 | }
79 |
80 | public List getTypeParameters() {
81 | return typeParameters;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/FieldInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | /**
10 | * @author happy
11 | * 字段信息
12 | */
13 | @Setter
14 | @Getter
15 | public class FieldInfo {
16 | /**
17 | * 类型信息
18 | */
19 | private ClassTypeInfo typeInfo;
20 | /**
21 | * 字段名
22 | */
23 | private String fieldName;
24 | /**
25 | * 字段注解
26 | */
27 | private List annotations = new ArrayList<>();
28 |
29 | public FieldInfo(String fieldName, ClassTypeInfo typeInfo) {
30 | this.fieldName = fieldName;
31 | this.typeInfo = typeInfo;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/Import.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * @author happy
8 | */
9 | @Setter
10 | @Getter
11 | public class Import {
12 | /**
13 | * 包名
14 | */
15 | private String packageName;
16 | /**
17 | * 类名
18 | */
19 | private String className;
20 | /**
21 | * 是否需要进行包转换
22 | */
23 | private boolean inside;
24 | /**
25 | * 按需
26 | */
27 | private boolean onDemand;
28 |
29 | public Import(String packageName, String className, boolean inside, boolean onDemand) {
30 | this.packageName = packageName;
31 | this.className = className;
32 | this.inside = inside;
33 | this.onDemand = onDemand;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/InputParamInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * @author happy 2019/10/27 00:24
8 | * 输入的参数信息
9 | */
10 | @Getter
11 | @Setter
12 | public class InputParamInfo extends ParamInfo {
13 | /**
14 | * 是否有@PathVariable注解
15 | */
16 | private boolean pathVariable;
17 | /**
18 | * 是否有@Valid注解
19 | */
20 | private boolean valid;
21 | }
22 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/JavaDocInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import com.google.common.collect.ListMultimap;
4 | import com.google.common.collect.Multimaps;
5 |
6 | import java.util.*;
7 | import java.util.stream.Collectors;
8 |
9 | /**
10 | * javadoc 注释信息
11 | *
12 | * @author happy
13 | */
14 | public class JavaDocInfo {
15 |
16 | /**
17 | * List>> 结构是 tagName -> fragments list
18 | */
19 | private ListMultimap> tags = Multimaps.newListMultimap(
20 | new LinkedHashMap<>(), ArrayList::new
21 | );
22 |
23 | /**
24 | * 获取注释第一行
25 | */
26 | public String getFirstRow(){
27 | if (tags.isEmpty()) {
28 | return "请设置控制器中文名";
29 | }
30 | List> tagsList = tags.get(null);
31 | if (tagsList.isEmpty()) {
32 | return "请设置控制器中文名";
33 | }
34 | List tagValues = tagsList.get(0);
35 | return tagValues.get(0);
36 | }
37 |
38 | public void add(String tagName, List fragmentsInfo) {
39 | tags.put(tagName, fragmentsInfo);
40 | }
41 |
42 | public List> get(String tagName) {
43 | return tags.get(tagName);
44 | }
45 |
46 | public String getToString(String tagName, CharSequence delimiter) {
47 | return getToString(tagName, delimiter, "", "");
48 | }
49 |
50 | public String getToString(String tagName) {
51 | return getToString(tagName, " ", "", "");
52 | }
53 |
54 | public String getToString(String tagName, CharSequence delimiter, CharSequence prefix, CharSequence suffix) {
55 | return tags.get(tagName).stream().flatMap(Collection::stream).collect(Collectors.joining(delimiter, prefix, suffix));
56 | }
57 |
58 | public String getByParamToString(String param, CharSequence delimiter) {
59 | return getByParamToString(param, delimiter, "", "");
60 | }
61 |
62 | public String getByParamToString(String param, CharSequence delimiter, CharSequence prefix, CharSequence suffix) {
63 | return tags.get("@param").stream()
64 | .filter(r -> !r.isEmpty() && r.get(0).equals(param))
65 | .flatMap(item -> item.stream().skip(1))
66 | .collect(Collectors.joining(delimiter, prefix, suffix));
67 | }
68 |
69 | public ListMultimap> getTags() {
70 | return tags;
71 | }
72 |
73 | public Map.Entry>> getTags(int index) {
74 | int i = 0;
75 | for (Map.Entry>> entry : tags.asMap().entrySet()) {
76 | if (i == index) {
77 | return entry;
78 | }
79 | i++;
80 | }
81 | return null;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/PackageInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import com.google.common.collect.ListMultimap;
4 | import com.google.common.collect.Multimap;
5 | import com.google.common.collect.Multimaps;
6 |
7 | import java.util.Collection;
8 | import java.util.concurrent.ConcurrentSkipListMap;
9 | import java.util.concurrent.CopyOnWriteArrayList;
10 |
11 | /**
12 | * @author happy
13 | */
14 | public class PackageInfo {
15 |
16 | private Multimap multimap = Multimaps.newListMultimap(
17 | new ConcurrentSkipListMap<>(), CopyOnWriteArrayList::new
18 | );
19 |
20 | public void add(String packageName, T t) {
21 | multimap.put(packageName, t);
22 | }
23 |
24 | public Collection getValues() {
25 | return multimap.values();
26 | }
27 |
28 | public static void main(String[] args) {
29 | ListMultimap multimap = Multimaps.newListMultimap(new ConcurrentSkipListMap<>(), CopyOnWriteArrayList::new);
30 | multimap.put("hello", "hi");
31 | multimap.put("hello", "hia");
32 | multimap.put("hello", "hi");
33 | System.out.println(multimap.values());
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/ParamClassInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import org.apache.commons.collections4.CollectionUtils;
6 | import org.eclipse.jdt.core.dom.TagElement;
7 | import org.eclipse.jdt.core.dom.TextElement;
8 | import org.eclipse.jdt.core.dom.TypeDeclaration;
9 |
10 | import java.util.*;
11 |
12 | /**
13 | * @author happy
14 | * 方法参数类信息(入参和出参)
15 | */
16 | @Getter
17 | @Setter
18 | public class ParamClassInfo extends ClassInfo {
19 | private List properties = new ArrayList<>();
20 | private Map propertiesMap = new HashMap<>();
21 | /**
22 | * 父类类型信息
23 | */
24 | private ClassTypeInfo superType;
25 | private Class clazz;
26 | protected TypeDeclaration type;
27 | private List typeParameters = new ArrayList<>();
28 |
29 | public JavaDocInfo getClassComment() {
30 | return transform(type.getJavadoc());
31 | }
32 |
33 | protected static JavaDocInfo transform(org.eclipse.jdt.core.dom.Javadoc javadoc) {
34 | if (javadoc == null) {
35 | return null;
36 | }
37 | JavaDocInfo javadocInfo = new JavaDocInfo();
38 | List tags = javadoc.tags();
39 | for (Object tag : tags) {
40 | TagElement tagElement = (TagElement) tag;
41 | String tagName = tagElement.getTagName();
42 |
43 | List fragments = tagElement.fragments();
44 | ArrayList fragmentsInfo = new ArrayList<>();
45 | for (Object fragment : fragments) {
46 | if (fragment instanceof TextElement) {
47 | TextElement textElement = (TextElement) fragment;
48 | fragmentsInfo.add(textElement.getText());
49 | } else {
50 | fragmentsInfo.add(fragment.toString());
51 | }
52 | }
53 | javadocInfo.add(tagName, fragmentsInfo);
54 | }
55 | return javadocInfo;
56 | }
57 |
58 | public void addTypeParameter(String typeParameter) {
59 | typeParameters.add(typeParameter);
60 | }
61 |
62 | public void add(PropertyInfo attributeInfo) {
63 | properties.add(attributeInfo);
64 | propertiesMap.put(attributeInfo.getFieldName(), attributeInfo);
65 | }
66 |
67 | public void sortPropertys() {
68 | properties.sort(Comparator.comparing(FieldInfo::getFieldName));
69 | }
70 |
71 |
72 | public boolean hasGenerics() {
73 | return CollectionUtils.isNotEmpty(getTypeParameters());
74 | }
75 |
76 | public List getTypeParameters() {
77 | return typeParameters;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/ParamInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | /**
11 | * @author happy 2019/10/27 17:52
12 | */
13 | @Getter
14 | @Setter
15 | public class ParamInfo extends ClassBaseInfo {
16 | /**
17 | * 是否数组
18 | */
19 | private boolean array;
20 | /**
21 | * 参数字段名
22 | */
23 | private String fieldName;
24 | /**
25 | * 子参数信息
26 | * 为null则说明是不再分析的类型
27 | */
28 | private List childParamInfo;
29 | /**
30 | * 泛型中的实际类型列表
31 | * 非null则说明是泛型
32 | */
33 | private Map actualTypes;
34 | }
35 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/PropertyInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 |
4 | import lombok.Getter;
5 | import lombok.Setter;
6 |
7 | /**
8 | * @author happy
9 | * 属性信息
10 | */
11 | @Setter
12 | @Getter
13 | public class PropertyInfo extends FieldInfo {
14 |
15 | private JavaDocInfo javadocInfo;
16 |
17 | public PropertyInfo(String name, ClassTypeInfo typeInfo) {
18 | super(name, typeInfo);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/TestInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | /**
10 | * @author happy 2019/10/28 00:16
11 | */
12 | @Getter
13 | @Setter
14 | public class TestInfo {
15 | private String id;
16 | private int num;
17 | private boolean ok;
18 | private List list;
19 | private Map map;
20 | }
21 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/info/TestSuperInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.info;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | @Getter
7 | @Setter
8 | public class TestSuperInfo {
9 | private String testSuperInfoId;
10 | }
11 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/type/ApiType.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.type;
2 |
3 | /**
4 | * @author happy 2019/10/27 02:16
5 | * api接口类型
6 | */
7 | public enum ApiType {
8 | /**
9 | * 客户
10 | */
11 | person,
12 | /**
13 | * 管理
14 | */
15 | admin,
16 | /**
17 | * 内部
18 | */
19 | inner
20 | }
21 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/utils/CommentUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.utils;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.rxjava.apikit.tool.info.JavaDocInfo;
5 |
6 | import java.util.*;
7 | import java.util.stream.Collectors;
8 |
9 | /**
10 | * @author happy
11 | */
12 | public class CommentUtils {
13 | /**
14 | * 获取注释不包含tag的内容
15 | */
16 | public static String getCommentNoTag(JavaDocInfo comment, String start) {
17 | if (comment == null) {
18 | return start;
19 | }
20 | StringBuilder sb = new StringBuilder();
21 |
22 | for (String tagName : comment.getTags().keySet()) {
23 | if (StringUtils.isEmpty(tagName)) {
24 | sb.append(start);
25 | formatCommentItem(comment, start, sb, tagName);
26 | }
27 | }
28 | if (sb.length() > 0) {
29 | return sb.toString();
30 | } else {
31 | return start;
32 | }
33 | }
34 |
35 | /**
36 | * 获取注释不带tabName的内容
37 | */
38 | public static String getBaseComment(JavaDocInfo comment, String start) {
39 | if (comment == null) {
40 | return start;
41 | }
42 | StringBuilder sb = new StringBuilder();
43 |
44 | List> lists = comment.get(null);
45 | lists.stream().flatMap(Collection::stream).forEach(c -> {
46 | sb.append(start);
47 | sb.append(StringUtils.trimToEmpty(c).replace("\n", "").replace("\r", ""));
48 | sb.append("\n");
49 | });
50 | String str = StringUtils.stripEnd(sb.toString(), null);
51 | if (str.length() > 0) {
52 | return str;
53 | } else {
54 | return start;
55 | }
56 | }
57 |
58 | /**
59 | * 格式化注释
60 | */
61 | private static void formatCommentItem(JavaDocInfo comment, String start, StringBuilder sb, String tagName) {
62 | List> fragments = comment.getTags().get(tagName);
63 | sb.append(fragments.stream().flatMap(Collection::stream).collect(Collectors.joining("\n" + start)));
64 | }
65 |
66 | /**
67 | * 获取注释
68 | */
69 | public static String getComment(JavaDocInfo comment, String start) {
70 | if (comment == null) {
71 | return start;
72 | }
73 | StringBuilder sb = new StringBuilder();
74 | for (String tagName : comment.getTags().keySet()) {
75 | sb.append(start);
76 | if (StringUtils.isNotEmpty(tagName)) {
77 | sb.append(tagName);
78 | sb.append(' ');
79 | }
80 | formatCommentItem(comment, start, sb, tagName);
81 | sb.append("\n");
82 | }
83 | if (sb.length() > 0) {
84 | sb.setLength(sb.length() - 1);
85 | }
86 | return sb.toString();
87 | }
88 |
89 | /**
90 | * 转化注释为map
91 | */
92 | public static Map toMap(JavaDocInfo comment) {
93 | if (comment == null) {
94 | return Collections.emptyMap();
95 | }
96 | Map map = new HashMap<>();
97 |
98 | for (String tagName : comment.getTags().keySet()) {
99 | StringBuilder sb = new StringBuilder();
100 |
101 | boolean isParam = "@param".equals(tagName);
102 |
103 | Collection> fragments = comment.getTags().get(tagName);
104 |
105 | if (isParam) {
106 | fragments.forEach(fragment -> {
107 | if (!fragment.isEmpty()) {
108 | String paramName = fragment.get(0);
109 | map.put(paramName, fragments.stream().skip(1).flatMap(Collection::stream).collect(Collectors.joining(" ")));
110 | }
111 | });
112 | } else {
113 | map.put(tagName, fragments.stream().flatMap(Collection::stream).collect(Collectors.joining(" ")));
114 | }
115 | }
116 | return map;
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/utils/DateTimeUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.utils;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Date;
6 |
7 | /**
8 | * 日期帮助类
9 | *
10 | * @author happy
11 | */
12 | public class DateTimeUtils {
13 |
14 | static final String FORMAT = "yyyy-MM-dd HH:mm:ss";
15 |
16 | /**
17 | * 格式化日期为字符串
18 | */
19 | public static String format(Date date) {
20 | SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT);
21 | dateFormat.setLenient(false);
22 | return dateFormat.format(date);
23 | }
24 |
25 | /**
26 | * 解析日期字符串
27 | */
28 | public static Date parse(String date) throws ParseException {
29 | SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT);
30 | dateFormat.setLenient(false);
31 | return dateFormat.parse(date);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/utils/HttlUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.utils;
2 |
3 | import httl.Engine;
4 | import httl.Template;
5 | import org.apache.commons.io.FileUtils;
6 | import org.apache.commons.io.output.StringBuilderWriter;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import java.io.File;
11 | import java.io.IOException;
12 | import java.text.ParseException;
13 | import java.util.Map;
14 | import java.util.Properties;
15 |
16 | /**
17 | * Httl模版引擎帮助类
18 | */
19 | public class HttlUtils {
20 |
21 | private static final Logger log = LoggerFactory.getLogger(HttlUtils.class);
22 | /**
23 | * 文件编码
24 | */
25 | private static final String FILE_ENCODING = "utf8";
26 |
27 | private static Engine getEngine() {
28 | return Inner.ENGINE;
29 | }
30 |
31 |
32 | private static class Inner {
33 | private static final Engine ENGINE;
34 |
35 | static {
36 | Properties configProperties = new Properties();
37 | try {
38 | configProperties.load(HttlUtils.class.getResourceAsStream("/org/rxjava/apikit/tool/httl.properties"));
39 | ENGINE = Engine.getEngine(configProperties);
40 | } catch (IOException e) {
41 | throw new RuntimeException(e);
42 | }
43 | }
44 | }
45 |
46 | /**
47 | * 根据模板生成文件
48 | */
49 | public static void renderFile(File file, Map params, String templPath) throws IOException, ParseException {
50 | if (!file.getParentFile().exists()) {
51 | synchronized (HttlUtils.class) {
52 | if (!file.getParentFile().exists()) {
53 | if (!file.getParentFile().mkdirs()) {
54 | throw new RuntimeException("创建路径失败!");
55 | }
56 | }
57 | }
58 | }
59 |
60 | String code = renderToString(params, templPath);
61 | if (file.getName().endsWith(".java")) {
62 | String formatCode = JavaFileFormat.formatCode(code);
63 | writeStringToFile(file, formatCode);
64 | log.info("生成一个文件{}", file.getAbsolutePath());
65 | } else {
66 | writeStringToFile(file, code);
67 | log.info("生成一个文件{}", file.getAbsolutePath());
68 | }
69 | }
70 |
71 | private static void writeStringToFile(File file, String data) throws IOException {
72 | data = data.replaceAll("(\r\n|\r|\n|\n\r)", "\r\n");
73 | FileUtils.writeStringToFile(file, data, HttlUtils.FILE_ENCODING);
74 | }
75 |
76 | private static String renderToString(Map params, String templPath) throws IOException, ParseException {
77 | StringBuilderWriter writer = new StringBuilderWriter();
78 | Template template = getEngine().getTemplate(templPath);
79 | template.render(params, writer);
80 | log.info("生成一个文件到字符串");
81 | return writer.toString();
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/utils/JavaFileFormat.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.utils;
2 |
3 | import org.eclipse.jdt.core.JavaCore;
4 | import org.eclipse.jdt.core.ToolFactory;
5 | import org.eclipse.jdt.core.formatter.CodeFormatter;
6 | import org.eclipse.jface.text.Document;
7 | import org.eclipse.jface.text.IDocument;
8 | import org.eclipse.text.edits.TextEdit;
9 |
10 | import java.util.Map;
11 |
12 | /**
13 | * Java代码格式化
14 | */
15 | public class JavaFileFormat {
16 |
17 | public static final CodeFormatter CODE_FORMATTER = createCodeFormatter();
18 |
19 | private static CodeFormatter createCodeFormatter() {
20 | Map options = JavaCore.getOptions();
21 | JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options);
22 | options.put("org.eclipse.jdt.core.formatter.lineSplit", "120");
23 | return ToolFactory.createCodeFormatter(options);
24 | }
25 |
26 | public synchronized static String formatCode(String contents) {
27 | IDocument doc = new Document(contents);
28 | TextEdit edit = CODE_FORMATTER.format(
29 | CodeFormatter.K_COMPILATION_UNIT, doc.get(), 0, doc.get()
30 | .length(), 0, null);
31 | if (edit != null) {
32 | try {
33 | edit.apply(doc);
34 | contents = doc.get();
35 | } catch (Exception e) {
36 | throw new RuntimeException(e);
37 | }
38 | }
39 | return contents;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/utils/JsonUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.utils;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 | import com.fasterxml.jackson.core.JsonFactory;
5 | import com.fasterxml.jackson.core.JsonParser;
6 | import com.fasterxml.jackson.core.type.TypeReference;
7 | import com.fasterxml.jackson.databind.*;
8 | import com.fasterxml.jackson.datatype.guava.GuavaModule;
9 |
10 | import java.io.IOException;
11 | import java.lang.reflect.Type;
12 | import java.text.SimpleDateFormat;
13 | import java.util.List;
14 |
15 | /**
16 | * @author happy
17 | */
18 | public class JsonUtils {
19 | public static final ObjectMapper MAPPER = new ObjectMapper();
20 |
21 | static {
22 | MAPPER.registerModule(new GuavaModule());
23 | MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
24 | MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
25 | MAPPER.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
26 | SimpleDateFormat dateFormat = new SimpleDateFormat(DateTimeUtils.FORMAT);
27 | dateFormat.setLenient(false);
28 | MAPPER.setDateFormat(dateFormat);
29 | }
30 |
31 | public static ObjectMapper getObjectMapper() {
32 | return MAPPER;
33 | }
34 |
35 | public static final JsonFactory JSON_FACTORY = new JsonFactory();
36 |
37 | /**
38 | * 不能处理复杂情况,和继承情况
39 | */
40 | public static String serialize(Object o) {
41 | try {
42 | if (o instanceof List) {
43 | return MAPPER.writeValueAsString(((List>) o).toArray());
44 | }
45 | return MAPPER.writeValueAsString(o);
46 | } catch (IOException e) {
47 | throw new RuntimeException(e.getMessage(), e);
48 | }
49 | }
50 |
51 | /**
52 | * 不能处理复杂情况,和继承情况
53 | */
54 | public static T deserialize(String json, Class valueType) {
55 | try {
56 | return MAPPER.readValue(json, valueType);
57 | } catch (IOException e) {
58 | throw new RuntimeException(e.getMessage(), e);
59 | }
60 | }
61 |
62 | public static T deserialize(String json, Class> parentClass, Class>... elementClasses) {
63 | try {
64 | JavaType javaType = MAPPER.getTypeFactory().constructParametricType(
65 | parentClass, elementClasses
66 | );
67 | return MAPPER.readValue(json, javaType);
68 | } catch (IOException e) {
69 | throw new RuntimeException(e.getMessage(), e);
70 | }
71 | }
72 |
73 | /**
74 | * 不能处理复杂情况,和继承情况
75 | * 对付一般的List;MyClass; 方式足够了
76 | */
77 | public static T deserialize(String json, TypeReference valueTypeRef) {
78 | try {
79 | return MAPPER.readValue(json, valueTypeRef);
80 | } catch (IOException e) {
81 | throw new RuntimeException(e.getMessage(), e);
82 | }
83 | }
84 |
85 | public static JsonNode deserialize(String json) {
86 | try {
87 | return MAPPER.readTree(json);
88 | } catch (IOException e) {
89 | throw new RuntimeException(e.getMessage(), e);
90 | }
91 | }
92 |
93 | public static ObjectMapper create(boolean isNoDefault) {
94 | return create(isNoDefault, DateTimeUtils.FORMAT);
95 | }
96 |
97 | public static ObjectMapper create(boolean isNoDefault, String dateFormat) {
98 | ObjectMapper mapper = new ObjectMapper();
99 | mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
100 | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
101 | mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true);
102 | if (isNoDefault) {
103 | mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
104 | }
105 | mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
106 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
107 | simpleDateFormat.setLenient(false);
108 | mapper.setDateFormat(simpleDateFormat);
109 | return mapper;
110 | }
111 |
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/utils/LocalPathUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.utils;
2 |
3 | import org.rxjava.apikit.tool.info.Import;
4 |
5 | import java.io.File;
6 |
7 | /**
8 | * 路径帮助类
9 | *
10 | * @author happy
11 | */
12 | public final class LocalPathUtils {
13 |
14 | /**
15 | * 获取指定路径下文件并修改名称+后缀
16 | */
17 | public static File packToPath(String path, String packname, String name, String suffix) {
18 | File file = packToPath(path, packname);
19 | return new File(file, name + suffix);
20 | }
21 |
22 | /**
23 | * 获取指定路径下文件
24 | */
25 | public static File packToPath(String path, String packageName) {
26 | return new File(path, packageName.replace(".", File.separator));
27 | }
28 |
29 | /**
30 | * 获取指定路径下文件并修改名称
31 | */
32 | public static File packToPath(String path, String packname, String name) {
33 | File file = packToPath(path, packname);
34 | return new File(file, name);
35 | }
36 |
37 | /**
38 | * 路径转为包格式
39 | */
40 | public static String pathToPack(String path) {
41 | return path.replace(File.separator, ".");
42 | }
43 |
44 | /**
45 | * 字符串首字母大写
46 | */
47 | public static String toClassName(String str) {
48 | StringBuilder sb = new StringBuilder();
49 | for (int i = 0; i < str.length(); i++) {
50 | char c = str.charAt(i);
51 | if (0 == i) {
52 | sb.append(Character.toUpperCase(c));
53 | } else {
54 | sb.append(c);
55 | }
56 | }
57 | return sb.toString();
58 | }
59 |
60 | /**
61 | * 检查是否在Lang包中的类
62 | */
63 | public static Import getLangImport(String name) {
64 | try {
65 | Class> aClass = Class.forName("java.lang" + "." + name);
66 | return new Import("java.lang", name, false, false);
67 | } catch (ClassNotFoundException e) {
68 | return null;
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/utils/NameUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.utils;
2 |
3 | /**
4 | * @author happy
5 | * 命名帮助类
6 | */
7 | public class NameUtils {
8 | /**
9 | * 首字母小写
10 | */
11 | public static String toFieldName(String name) {
12 | if (!name.isEmpty()) {
13 | char c = name.charAt(0);
14 | return Character.toLowerCase(c) + name.substring(1);
15 | }
16 | return name;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/utils/OrderStatus.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.utils;
2 |
3 | /**
4 | * 订单状态
5 | */
6 | public enum OrderStatus {
7 | /**
8 | * 已创建
9 | */
10 | CREATED,
11 | /**
12 | * 已付款
13 | */
14 | PAID,
15 | /**
16 | * 已发货
17 | */
18 | SHIPPED,
19 | /**
20 | * 确认收货
21 | */
22 | CONFIRMED,
23 | /**
24 | * 取消订单
25 | */
26 | CANCELLED;
27 | }
28 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/wrapper/BuilderWrapper.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.wrapper;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import org.apache.commons.collections4.CollectionUtils;
6 | import org.apache.commons.lang3.StringUtils;
7 | import org.rxjava.apikit.tool.generator.Context;
8 | import org.rxjava.apikit.tool.info.JavaDocInfo;
9 | import org.rxjava.apikit.tool.info.ClassInfo;
10 | import org.rxjava.apikit.tool.info.ClassTypeInfo;
11 | import org.rxjava.apikit.tool.utils.CommentUtils;
12 |
13 | import java.util.List;
14 |
15 | /**
16 | * @author happy
17 | * 生成器包装类
18 | */
19 | @Setter
20 | @Getter
21 | public class BuilderWrapper {
22 | /**
23 | * 类信息
24 | */
25 | protected T classInfo;
26 | /**
27 | * 发布的根包
28 | */
29 | private String distRootPackage;
30 | /**
31 | * 微服务Id
32 | */
33 | private String serviceId;
34 | /**
35 | * 发布的文件夹
36 | */
37 | protected String distFolder;
38 | /**
39 | * 上下文
40 | */
41 | protected Context context;
42 |
43 | BuilderWrapper(Context context, T classInfo, String distRootPackage) {
44 | this.context = context;
45 | this.classInfo = classInfo;
46 | this.distRootPackage = distRootPackage;
47 | }
48 |
49 | public String getDistClassName() {
50 | return classInfo.getClassName();
51 | }
52 |
53 | public String getFullDistPackage() {
54 | //源码所在的包
55 | String sourcePackage = classInfo.getPackageName();
56 | //源码所在的根包
57 | String sourceRootPackage = context.getRootPackage();
58 |
59 | String distFolder = sourcePackage.replace(sourceRootPackage, "");
60 |
61 | if (distFolder.startsWith(".")) {
62 | distFolder = distFolder.substring(1);
63 | }
64 | //如果源码所在的包根根包不一致,则仅仅获取源码所在的文件夹
65 | String[] floders = distFolder.split("\\.");
66 | if (!sourcePackage.contains(sourceRootPackage) && floders.length > 1) {
67 | distFolder = floders[floders.length - 1];
68 | }
69 | return getFullDistPackage(distFolder);
70 | }
71 |
72 | public String getDistPackage() {
73 | return getFullDistPackage(getDistFolder());
74 | }
75 |
76 | public String getFullDistPackage(String distFolder) {
77 | if (StringUtils.isEmpty(distFolder)) {
78 | if (distRootPackage == null) {
79 | return "";
80 | }
81 | return distRootPackage;
82 | } else {
83 | if (StringUtils.isEmpty(distRootPackage)) {
84 | return distFolder;
85 | } else {
86 | return distRootPackage + "." + distFolder;
87 | }
88 | }
89 | }
90 |
91 | void findTypes(ClassTypeInfo type, List list) {
92 | list.add(type);
93 | if (CollectionUtils.isNotEmpty(type.getTypeArguments())) {
94 | type.getTypeArguments().forEach(t -> findTypes(t, list));
95 | }
96 | }
97 |
98 | public String getSourceFullName() {
99 | return classInfo.getPackageName() + "." + classInfo.getClassName();
100 | }
101 |
102 | public String comment(String start) {
103 | JavaDocInfo comment = classInfo.getJavaDocInfo();
104 | return CommentUtils.getComment(comment, start);
105 | }
106 |
107 | public static String formatBaseComment(JavaDocInfo comment, String start) {
108 | return CommentUtils.getBaseComment(comment, start);
109 | }
110 |
111 | public static String formatComment(JavaDocInfo comment, String start) {
112 | return CommentUtils.getComment(comment, start);
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/wrapper/JavaEnumParamClassWrapper.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.wrapper;
2 |
3 | import org.rxjava.apikit.tool.generator.Context;
4 | import org.rxjava.apikit.tool.info.EnumParamClassInfo;
5 |
6 | /**
7 | * @author happy
8 | * Java参数类信息包装器
9 | */
10 | public class JavaEnumParamClassWrapper extends JavaWrapper {
11 | public JavaEnumParamClassWrapper(Context context, EnumParamClassInfo classInfo, String distRootPackage) {
12 | super(context, classInfo, distRootPackage);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/java/org/rxjava/apikit/tool/wrapper/JavaScriptWrapper.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.apikit.tool.wrapper;
2 |
3 | import com.google.common.collect.ImmutableMap;
4 | import org.rxjava.apikit.tool.generator.Context;
5 | import org.rxjava.apikit.tool.info.ClassInfo;
6 | import org.rxjava.apikit.tool.info.ClassTypeInfo;
7 |
8 | /**
9 | * @author happy 2019-05-09 23:04
10 | */
11 | public class JavaScriptWrapper extends BuilderWrapper {
12 |
13 | public JavaScriptWrapper(Context context, T classInfo, String rootPackage) {
14 | super(context, classInfo, rootPackage);
15 | }
16 |
17 | public String toTypeString(ClassTypeInfo typeInfo) {
18 | return toTypeString(typeInfo, false);
19 | }
20 |
21 | public String toTypeString(ClassTypeInfo typeInfo, boolean isArray) {
22 | StringBuilder sb = new StringBuilder();
23 | ClassTypeInfo.Type type = typeInfo.getType();
24 | if (typeInfo.isCollection()) {
25 | ClassTypeInfo typeInfoArg = typeInfo.getTypeArguments().get(0);
26 | return toTypeString(typeInfoArg, true);
27 | } else if (type == ClassTypeInfo.Type.OTHER) {
28 | if (typeInfo.isGeneric()) {
29 | sb.append("Object");
30 | } else {
31 | sb.append(typeInfo.getClassName());
32 | }
33 | } else {
34 | sb.append(toJavaScriptString(type));
35 | }
36 | if (typeInfo.isArray() || isArray) {
37 | sb.append("[]");
38 | }
39 | return sb.toString();
40 | }
41 |
42 | public String toJavaScriptString(ClassTypeInfo.Type type) {
43 | return TYPE_MAP.get(type);
44 | }
45 |
46 | private static final ImmutableMap TYPE_MAP
47 | = ImmutableMap.builder()
48 | .put(ClassTypeInfo.Type.VOID, "void")
49 | .put(ClassTypeInfo.Type.BOOLEAN, "boolean")
50 | .put(ClassTypeInfo.Type.BYTE, "number")
51 | .put(ClassTypeInfo.Type.SHORT, "number")
52 | .put(ClassTypeInfo.Type.INT, "number")
53 | .put(ClassTypeInfo.Type.LONG, "number")
54 | .put(ClassTypeInfo.Type.FLOAT, "number")
55 | .put(ClassTypeInfo.Type.DOUBLE, "number")
56 | .put(ClassTypeInfo.Type.DATE, "Date")
57 | .put(ClassTypeInfo.Type.STRING, "string")
58 | .build();
59 | }
60 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/apidoc/api.httl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ##设置第一个tag为null的字符串为控制器Controller中文名称
5 |
6 | $!{classInfo.javadocInfo.firstRow}
7 |
8 | 请输入控制器名称
9 |
10 |
11 | ##method方法
12 |
13 | $!{method.name}
14 | $!{method.url}
15 |
16 |
17 | ##设置第一个tag为null的字符串为控制器Controller中文名称
18 |
19 | $!{method.comment.firstRow}
20 |
21 | 请输入方法名称
22 |
23 |
24 |
25 | ##循环结束
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/apidoc/index.httl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $!{api.key}
5 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/apidoc/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rxjava-api",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1"
7 | },
8 | "dependencies": {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/apidoc/paramClass.httl:
--------------------------------------------------------------------------------
1 |
2 |
3 | $!{classInfo.name}
4 | ##参数属性列表
5 |
6 | $!{property.name}
7 |
8 | ##循环结束
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/apidoc/test.httl:
--------------------------------------------------------------------------------
1 |
2 |
3 | ##method方法
4 |
5 | $!{name}
6 |
7 | ##循环结束
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/es2015/Api.d.httl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $!{wrapper.imports}
7 |
8 | /**
9 | $!{wrapper.comment(" * ")}
10 | */
11 | declare class $!{wrapper.getDistClassName()} extends AbstractApi {
12 |
13 | ##异步方法
14 |
15 | /**
16 | $!{wrapper.formatBaseComment(method.comment," * ")}
17 | *
18 | $!{wrapper.requestComment(method," * ")}
19 | */
20 | $!{method.name}($!{wrapper.params(method,true)}):Promise<$!{wrapper.resultTypeString(method)}>;
21 |
22 | ##循环结束
23 | }
24 | export { $!{wrapper.getDistClassName()} };
25 | declare const $!{wrapper.fieldName}: $!{wrapper.getDistClassName()};
26 | export default $!{wrapper.fieldName};
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/es2015/ParamClass.d.httl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $!{wrapper.imports}
6 |
7 | /**
8 | $!{wrapper.comment(" * ")}
9 | */
10 | interface $!{classInfo.name} {
11 |
12 |
13 |
14 | /**
15 | $!{wrapper.formatComment(attr.javadocInfo," * ")}
16 | */
17 |
18 | $!{attr.name}?:$!{wrapper.toTypeString(attr.typeInfo)};
19 |
20 | }
21 |
22 | export default $!{classInfo.name};
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/es2015/ParamClass.httl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apersonw/rxjava/1df845e8d8421cf8efbc9f245a56c0dd69a3cbcb/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/es2015/ParamClass.httl
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/es2015/index.d.httl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | import $!{api.key} from '.$!{api.value}';
6 |
7 |
8 |
9 | export {
10 |
11 | $!{api.key},
12 |
13 | };
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/es2015/index.httl:
--------------------------------------------------------------------------------
1 |
2 |
3 | "use strict";
4 |
5 | Object.defineProperty(exports, "__esModule", {
6 | value: true
7 | });
8 |
9 |
10 | Object.defineProperty(exports, "$!{api.key}", {
11 | enumerable: true,
12 | get: function get() {
13 | return _$!{api.key}.default;
14 | }
15 | });
16 | var _$!{api.key} = _interopRequireDefault(require(".$!{api.value}"));
17 |
18 |
19 |
20 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/es2015/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rxjava-api",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1"
7 | },
8 | "dependencies": {
9 | "rxjava-api-core": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/java/ApiClass.httl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | package $!{wrapper.getFullDistPackage()};
7 |
8 | import reactor.core.publisher.Mono;
9 |
10 | import java.util.*;
11 | import java.util.Map.Entry;
12 | import java.util.concurrent.Future;
13 |
14 |
15 | import org.rxjava.apikit.client.*;
16 |
17 | $!{wrapper.imports}
18 |
19 | public class $!{wrapper.getDistClassName()} {
20 | private ClientAdapter clientAdapter;
21 |
22 | public $!{wrapper.getDistClassName()}() {
23 | }
24 |
25 | public $!{wrapper.getDistClassName()}(ClientAdapter clientAdapter) {
26 | this.clientAdapter = clientAdapter;
27 | }
28 |
29 |
30 | public Mono<$!{wrapper.resultData(method)}> $!{method.methodName}($!{wrapper.params(method)}) {
31 | Map _uriVariables = new HashMap<>();
32 |
33 | _uriVariables.put("$!{param.getFieldName()}", $!{param.getFieldName()});
34 |
35 | String _url = ApiUtils.expandUriComponent("$!{method.url}", _uriVariables);
36 |
37 |
38 |
39 | List> _form = $!{param.fieldName}.encode("", new ArrayList<>());
40 | return clientAdapter.request("$!{method.type.name()}", _url, _form, _$!{method.index}Type);
41 |
42 | return clientAdapter.request("$!{method.type.name()}", _url, null, _$!{method.index}Type);
43 |
44 | }
45 |
46 |
47 | public void setClientAdapter(ClientAdapter clientAdapter) {
48 | this.clientAdapter = clientAdapter;
49 | }
50 |
51 | public ClientAdapter getClientAdapter() {
52 | return clientAdapter;
53 | }
54 |
55 |
56 | $!{wrapper.resultTypeString(method," ")}
57 |
58 | }
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/java/EnumParamClass.httl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | package $!{wrapper.getFullDistPackage()};
5 |
6 | public enum $!{wrapper.getDistClassName()} {
7 |
8 |
9 | $!{constant.name};
10 |
11 | $!{constant.name},
12 |
13 |
14 | }
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/generator/java/ParamClass.httl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | package $!{wrapper.getFullDistPackage()};
6 |
7 | import lombok.Getter;
8 | import lombok.Setter;
9 | import java.util.*;
10 | import java.util.Map.Entry;
11 | import java.util.AbstractMap.SimpleImmutableEntry;
12 | import org.bson.types.ObjectId;
13 | $!{wrapper.imports}
14 |
15 | @Getter
16 | @Setter
17 | public class $!{wrapper.getDistClassName()}$!{wrapper.typeParameters} $!{wrapper.superInfo} {
18 |
19 | private $!{wrapper.toJavaTypeString(attr.typeInfo, false, true)} $!{attr.fieldName};
20 |
21 |
22 | public List> encode(String $parent, List> $list) {
23 | $!{wrapper.encodeCode(" ", "$parent")}
24 | }
25 | }
--------------------------------------------------------------------------------
/rxjava-apikit/rxjava-apikit-tool/src/main/resources/org/rxjava/apikit/tool/httl.properties:
--------------------------------------------------------------------------------
1 | compiler=httl.spi.compilers.JavassistCompiler
2 | import.packages+=org.rxjava.apikit.tool.info,\
3 | org.rxjava.apikit.tool.utils,\
4 | org.rxjava.apikit.tool.wrapper
5 | template.directory=
6 | message.basename=messages
7 | input.encoding=UTF-8
8 | output.encoding=UTF-8
9 | reloadable=true
10 | precompiled=true
--------------------------------------------------------------------------------
/rxjava-example/README.md:
--------------------------------------------------------------------------------
1 | ###模块说明
2 |
3 | 本模块下为一系列使用的相关例子工程
--------------------------------------------------------------------------------
/rxjava-example/rxjava-gateway-example/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | org.rxjava
6 | rxjava-gateway
7 | 1.0.8-SNAPSHOT
8 |
9 | rxjava-gateway-example
10 | jar
11 |
12 | example
13 | Example
14 |
15 |
16 |
17 | org.rxjava
18 | rxjava-apikit-tool
19 | ${project.parent.version}
20 |
21 |
22 | com.google.zxing
23 | core
24 | 3.3.3
25 |
26 |
27 | com.google.zxing
28 | javase
29 | 3.3.3
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-test
34 |
35 |
36 | org.junit.vintage
37 | junit-vintage-engine
38 |
39 |
40 |
41 |
42 |
43 |
44 | release
45 |
46 |
47 |
48 | maven-assembly-plugin
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-gateway-example/src/assembly/bin.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | bin
6 |
7 | dir
8 |
9 | false
10 |
11 |
12 |
13 | ${project.groupId}:*
14 |
15 | base-lib
16 | false
17 |
18 |
19 |
20 | ${project.groupId}:*
21 |
22 | lib
23 | false
24 |
25 |
26 |
27 |
28 | ${basedir}/target/classes
29 | classes
30 |
31 | bootstrap.yml
32 | application.yml
33 |
34 |
35 |
36 | src/assembly/config/release
37 |
38 | bootstrap.yml
39 | application.yml
40 |
41 | true
42 | classes
43 |
44 |
45 | src/assembly/config/release
46 |
47 | Dockerfile
48 | startup.sh
49 |
50 | true
51 | ./
52 |
53 |
54 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-gateway-example/src/assembly/config/release/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM registry.cn-shanghai.aliyuncs.com/taro-mall/java:8_server-jre
2 |
3 | RUN mkdir /rxservice
4 | WORKDIR /rxservice
5 |
6 | COPY base-lib base-lib
7 | COPY lib lib
8 | COPY classes classes
9 | COPY startup.sh startup.sh
10 |
11 | EXPOSE 8080
12 | CMD ["./startup.sh"]
--------------------------------------------------------------------------------
/rxjava-example/rxjava-gateway-example/src/assembly/config/release/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: rxjava-${module.type}-${module.name}
4 | cloud:
5 | kubernetes:
6 | config:
7 | sources:
8 | - name: common-configmap
9 | namespace: default
10 | data:
11 | mongodb:
12 | database: rxjava-${module.type}-${module.name}
--------------------------------------------------------------------------------
/rxjava-example/rxjava-gateway-example/src/assembly/config/release/startup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | java $JAVA_OPTIONS -cp ./classes org.rxjava.${module.type}.${module.name}.Rx${module.Type}${module.Name}Main
--------------------------------------------------------------------------------
/rxjava-example/rxjava-gateway-example/src/main/java/org/rxjava/gateway/example/CustomGatewayDiscoveryClientAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.gateway.example;
2 |
3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
4 | import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
5 | import org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator;
6 | import org.springframework.cloud.gateway.discovery.DiscoveryLocatorProperties;
7 | import org.springframework.context.annotation.Bean;
8 |
9 | public class CustomGatewayDiscoveryClientAutoConfiguration {
10 | @Bean
11 | @ConditionalOnProperty(name = "spring.cloud.gateway.discovery.locator.enabled")
12 | public DiscoveryClientRouteDefinitionLocator customDiscoveryClientRouteDefinitionLocator(
13 | ReactiveDiscoveryClient discoveryClient,
14 | DiscoveryLocatorProperties properties) {
15 | return new CustomDiscoveryClientRouteDefinitionLocator(discoveryClient, properties);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-gateway-example/src/main/java/org/rxjava/gateway/example/LoginInfoServiceImpl.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.gateway.example;
2 |
3 | import org.rxjava.common.core.entity.LoginInfo;
4 | import org.rxjava.common.core.service.LoginInfoService;
5 | import org.springframework.stereotype.Service;
6 | import org.springframework.web.server.ServerWebExchange;
7 | import reactor.core.publisher.Mono;
8 |
9 | @Service
10 | public class LoginInfoServiceImpl implements LoginInfoService {
11 | @Override
12 | public Mono checkToken(ServerWebExchange serverWebExchange) {
13 | return Mono.just(new LoginInfo());
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-gateway-example/src/main/java/org/rxjava/gateway/example/RxGatewayExampleApplication.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.gateway.example;
2 |
3 | import org.springframework.boot.WebApplicationType;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.boot.builder.SpringApplicationBuilder;
6 | import org.springframework.cloud.gateway.route.RouteLocator;
7 | import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
8 | import org.springframework.context.annotation.Bean;
9 |
10 | import java.util.function.Predicate;
11 |
12 | /**
13 | * @author happy 2019-05-10 18:06
14 | */
15 | @SpringBootApplication
16 | public class RxGatewayExampleApplication {
17 | public static void main(String[] args) {
18 | new SpringApplicationBuilder(RxGatewayExampleApplication.class).web(WebApplicationType.REACTIVE).run(args);
19 | }
20 |
21 | // @Bean
22 | // public RouteLocator routeLocator(RouteLocatorBuilder builder) {
23 | // return builder.routes()
24 | // .route(p -> p.path("/**")
25 | // .filters(u -> u.rewritePath("/([^/]+)/(?.*)", "/${segment}"))
26 | // .uri("https://www.baidu.com"))
27 | // .build();
28 | // }
29 | }
30 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-gateway-example/src/main/java/org/rxjava/gateway/example/RxGatewayExampleMain.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.gateway.example;
2 |
3 | import java.lang.reflect.Method;
4 | import java.net.URL;
5 | import java.net.URLClassLoader;
6 | import java.nio.file.Files;
7 | import java.nio.file.Path;
8 | import java.nio.file.Paths;
9 | import java.util.function.Consumer;
10 |
11 | /**
12 | * @author happy 2019-03-17 22:23
13 | */
14 | public class RxGatewayExampleMain {
15 | public static void main(String... args) {
16 | try {
17 | URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader();
18 | Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
19 | addURL.setAccessible(true);
20 | String[] strPaths = new String[]{"base-lib", "lib"};
21 | for (String strPath : strPaths) {
22 | Path path = Paths.get(strPath);
23 | if (Files.isDirectory(path)) {
24 | Consumer pathConsumer = p -> {
25 | try {
26 | addURL.invoke(cl, p.toUri().toURL());
27 | } catch (Exception e) {
28 | e.printStackTrace();
29 | }
30 | };
31 | Files.newDirectoryStream(path).forEach(pathConsumer);
32 | }
33 | }
34 | } catch (Exception e) {
35 | e.printStackTrace();
36 | }
37 | RxGatewayExampleApplication.main(args);
38 | }
39 | }
--------------------------------------------------------------------------------
/rxjava-example/rxjava-gateway-example/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.rxjava.gateway.example.CustomGatewayDiscoveryClientAutoConfiguration
--------------------------------------------------------------------------------
/rxjava-example/rxjava-gateway-example/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: rxjava-gateway-example
4 | data:
5 | mongodb:
6 | uri: mongodb://127.0.0.1:27017
7 | database: rxjava-gateway-example
8 | auto-index-creation: false
9 | rabbitmq:
10 | host: 127.0.0.1
11 | port: 5672
12 | username: admin
13 | password: admin
14 | listener:
15 | simple:
16 | concurrency: 10
17 | max-concurrency: 10
18 | prefetch: 1
19 | default-requeue-rejected: true
20 | auto-startup: true
21 | cloud:
22 | kubernetes:
23 | config:
24 | enabled: false
25 | discovery:
26 | enabled: false
27 | bus:
28 | enabled: false
29 | gateway:
30 | discovery:
31 | locator:
32 | lower-case-service-id: true
33 | enabled: true
34 | custom: true
35 | server:
36 | port: 8080
37 | mock:
38 | userId: alkjqwerpoiuasdf
39 | management:
40 | endpoints:
41 | web:
42 | exposure:
43 | include: "*"
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # 构建
3 | mvn clean install -Prelease
4 |
5 | # 从pom.xml获取模块名
6 | module_name=`grep 'artifactId' pom.xml | tr -d '/'| sed 's///g' | awk 'NR==2 {print}' | sed 's/ //g'`
7 |
8 | # 请自行修改自己要push的docker仓库
9 | # 推送构建的docker镜像到阿里云服务器
10 | module_tag=registry.cn-shanghai.aliyuncs.com/taro-mall/${module_name}:latest
11 |
12 | docker build ./target/docker-bin/ -t ${module_tag}
13 |
14 | docker push ${module_tag}
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/k8s/rxjava-service-example.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: rxjava-service-example
5 | labels:
6 | app: rxjava-service-example
7 | spec:
8 | replicas: 1
9 | template:
10 | metadata:
11 | name: rxjava-service-example
12 | labels:
13 | app: rxjava-service-example
14 | spec:
15 | containers:
16 | - name: rxjava-service-example
17 | image: registry.cn-shanghai.aliyuncs.com/taro-mall/rxjava-service-example:latest
18 | imagePullPolicy: Always
19 | restartPolicy: Always
20 | selector:
21 | matchLabels:
22 | app: rxjava-service-example
23 | ---
24 | apiVersion: v1
25 | kind: Service
26 | metadata:
27 | name: rxjava-service-example
28 | spec:
29 | selector:
30 | app: rxjava-service-example
31 | ports:
32 | - port: 8080
33 | protocol: TCP
34 | targetPort: 8080
35 | type: NodePort
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | org.rxjava
6 | rxjava-service
7 | 1.0.8-SNAPSHOT
8 |
9 | rxjava-service-example
10 | jar
11 |
12 | example
13 | Example
14 |
15 |
16 |
17 | org.rxjava
18 | rxjava-apikit-tool
19 | ${project.parent.version}
20 |
21 |
22 | com.google.zxing
23 | core
24 | 3.3.3
25 |
26 |
27 | com.google.zxing
28 | javase
29 | 3.3.3
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-test
34 |
35 |
36 | org.junit.vintage
37 | junit-vintage-engine
38 |
39 |
40 |
41 |
42 |
43 |
44 | release
45 |
46 |
47 |
48 | maven-assembly-plugin
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/assembly/bin.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | bin
6 |
7 | dir
8 |
9 | false
10 |
11 |
12 |
13 | ${project.groupId}:*
14 |
15 | base-lib
16 | false
17 |
18 |
19 |
20 | ${project.groupId}:*
21 |
22 | lib
23 | false
24 |
25 |
26 |
27 |
28 | ${basedir}/target/classes
29 | classes
30 |
31 | bootstrap.yml
32 | application.yml
33 |
34 |
35 |
36 | src/assembly/config/release
37 |
38 | bootstrap.yml
39 | application.yml
40 |
41 | true
42 | classes
43 |
44 |
45 | src/assembly/config/release
46 |
47 | Dockerfile
48 | startup.sh
49 |
50 | true
51 | ./
52 |
53 |
54 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/assembly/config/release/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM registry.cn-shanghai.aliyuncs.com/taro-mall/java:8_server-jre
2 |
3 | RUN mkdir /rxservice
4 | WORKDIR /rxservice
5 |
6 | COPY base-lib base-lib
7 | COPY lib lib
8 | COPY classes classes
9 | COPY startup.sh startup.sh
10 |
11 | EXPOSE 8080
12 | CMD ["./startup.sh"]
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/assembly/config/release/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: rxjava-${module.type}-${module.name}
4 | cloud:
5 | kubernetes:
6 | config:
7 | sources:
8 | - name: common-configmap
9 | namespace: default
10 | data:
11 | mongodb:
12 | database: rxjava-${module.type}-${module.name}
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/assembly/config/release/startup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | java $JAVA_OPTIONS -cp ./classes org.rxjava.${module.type}.${module.name}.Rx${module.Type}${module.Name}Main
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/main/java/org/rxjava/service/example/RxApiBuildApplication.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.example;
2 |
3 | import org.rxjava.apikit.tool.ApiGenerateManager;
4 | import org.rxjava.apikit.tool.generator.impl.ApidocApiGenerator;
5 | import org.rxjava.apikit.tool.generator.impl.JavaClientApiGenerator;
6 | import org.rxjava.apikit.tool.generator.impl.JavaScriptApiGenerator;
7 | import org.springframework.boot.CommandLineRunner;
8 | import org.springframework.boot.WebApplicationType;
9 | import org.springframework.boot.builder.SpringApplicationBuilder;
10 |
11 | import java.io.File;
12 |
13 | /**
14 | * @author happy
15 | * 手动构建api
16 | */
17 | public class RxApiBuildApplication implements CommandLineRunner {
18 | /**
19 | * 构建api
20 | */
21 | public static void main(String[] args) {
22 | new SpringApplicationBuilder(RxApiBuildApplication.class).web(WebApplicationType.NONE).run(args);
23 | }
24 |
25 | @Override
26 | public void run(String... args) throws Exception {
27 | //模块绝对路径
28 | String moduleAbsolutePath = getModuleAbsolutePath("rxjava-service-example");
29 | //java源码文件夹
30 | String javaSourceDir = new File(moduleAbsolutePath, "src/main/java/").getAbsolutePath();
31 | //设置Java生成后的文件夹路径
32 | String javaOutPath = new File(moduleAbsolutePath, "src/test/java/").getAbsolutePath();
33 | //设置Js生成后的文件夹路径
34 | String jsOutPath = new File(moduleAbsolutePath, "src/test/js/").getAbsolutePath();
35 | //设置Js生成后的文件夹路径
36 | String apidocOutPath = new File(moduleAbsolutePath, "src/test/apidoc/").getAbsolutePath();
37 |
38 | //分析api和param
39 | ApiGenerateManager manager = ApiGenerateManager.analyse(javaSourceDir, "org.rxjava.service.example");
40 | {
41 | //配置java客户端生成器
42 | JavaClientApiGenerator javaClientApiGenerator = new JavaClientApiGenerator();
43 | javaClientApiGenerator.setOutRootPackage("org.rxjava.api.example");
44 | javaClientApiGenerator.setOutPath(javaOutPath);
45 |
46 | //生成java客户端Api
47 | manager.generate(javaClientApiGenerator);
48 | }
49 |
50 | // {
51 | // //配置js客户端生成器
52 | // JavaScriptApiGenerator javaScriptApiGenerator = new JavaScriptApiGenerator();
53 | // javaScriptApiGenerator.setOutPath(jsOutPath);
54 | // javaScriptApiGenerator.setServiceId("example");
55 | //
56 | // //生成java script客户端Api
57 | // manager.generate(javaScriptApiGenerator);
58 | // }
59 |
60 | // {
61 | // //配置apidoc生成器
62 | // ApidocApiGenerator apidocApiGenerator = new ApidocApiGenerator();
63 | // apidocApiGenerator.setOutPath(apidocOutPath);
64 | // apidocApiGenerator.setServiceId("example");
65 | //
66 | // //生成apidoc
67 | // manager.generate(apidocApiGenerator);
68 | // }
69 | }
70 |
71 | /**
72 | * 获取指定模块绝对路径
73 | */
74 | private String getModuleAbsolutePath(String module) {
75 | File root = new File(module);
76 | if (!root.exists()) {
77 | root = new File("rxjava/rxjava-example/", module);
78 | }
79 | if (!root.exists()) {
80 | root = new File("rxjava-example/", module);
81 | }
82 | if (!root.exists()) {
83 | root = new File(".");
84 | }
85 | return root.getAbsolutePath();
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/main/java/org/rxjava/service/example/RxServiceExampleApplication.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.example;
2 |
3 | import org.springframework.boot.WebApplicationType;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.boot.builder.SpringApplicationBuilder;
6 |
7 | /**
8 | * @author happy 2019-05-10 18:06
9 | */
10 | @SpringBootApplication
11 | public class RxServiceExampleApplication {
12 | public static void main(String[] args) {
13 | new SpringApplicationBuilder(RxServiceExampleApplication.class).web(WebApplicationType.REACTIVE).run(args);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/main/java/org/rxjava/service/example/RxServiceExampleMain.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.example;
2 |
3 | import java.lang.reflect.Method;
4 | import java.net.URL;
5 | import java.net.URLClassLoader;
6 | import java.nio.file.Files;
7 | import java.nio.file.Path;
8 | import java.nio.file.Paths;
9 | import java.util.function.Consumer;
10 |
11 | /**
12 | * @author happy 2019-03-17 22:23
13 | */
14 | public class RxServiceExampleMain {
15 | public static void main(String... args) {
16 | try {
17 | URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader();
18 | Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
19 | addURL.setAccessible(true);
20 | String[] strPaths = new String[]{"base-lib", "lib"};
21 | for (String strPath : strPaths) {
22 | Path path = Paths.get(strPath);
23 | if (Files.isDirectory(path)) {
24 | Consumer pathConsumer = p -> {
25 | try {
26 | addURL.invoke(cl, p.toUri().toURL());
27 | } catch (Exception e) {
28 | e.printStackTrace();
29 | }
30 | };
31 | Files.newDirectoryStream(path).forEach(pathConsumer);
32 | }
33 | }
34 | } catch (Exception e) {
35 | e.printStackTrace();
36 | }
37 | RxServiceExampleApplication.main(args);
38 | }
39 | }
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/main/java/org/rxjava/service/example/entity/Example.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.example.entity;
2 |
3 | import lombok.Data;
4 | import org.bson.types.ObjectId;
5 | import org.springframework.data.annotation.CreatedDate;
6 | import org.springframework.data.annotation.Id;
7 | import org.springframework.data.mongodb.core.mapping.Document;
8 |
9 | import java.time.LocalDateTime;
10 |
11 | @Data
12 | @Document
13 | public class Example {
14 | @Id
15 | private ObjectId id;
16 | private String name;
17 | @CreatedDate
18 | private LocalDateTime createDate;
19 | }
20 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/main/java/org/rxjava/service/example/form/TestForm.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.example.form;
2 |
3 | import lombok.Data;
4 | import lombok.Getter;
5 | import lombok.Setter;
6 | import org.bson.types.ObjectId;
7 | import org.rxjava.service.example.type.TestEnumType;
8 |
9 | import javax.validation.constraints.NotEmpty;
10 | import javax.validation.constraints.NotNull;
11 |
12 | /**
13 | * @author happy 2019-01-27 12:16
14 | */
15 | @Data
16 | public class TestForm extends TestSuperForm {
17 | private ObjectId objectId;
18 | private TestEnumType testEnumType;
19 | private String stringId;
20 | }
21 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/main/java/org/rxjava/service/example/form/TestSuperForm.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.example.form;
2 |
3 | import lombok.Data;
4 | import lombok.Getter;
5 | import lombok.Setter;
6 | import org.hibernate.validator.constraints.Range;
7 |
8 | import javax.validation.constraints.Min;
9 |
10 | /**
11 | * @author happy 2019-03-27 19:49
12 | */
13 | @Data
14 | public class TestSuperForm {
15 | @Min(0)
16 | private int page = 0;
17 | @Range(min = 0, max = 20)
18 | private int pageSize = 10;
19 | }
20 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/main/java/org/rxjava/service/example/model/TestModel.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.example.model;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class TestModel {
7 | private String id;
8 | private String name;
9 | }
10 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/main/java/org/rxjava/service/example/person/TestController.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.example.person;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.rxjava.service.example.entity.Example;
5 | import org.rxjava.service.example.form.TestForm;
6 | import org.rxjava.service.example.model.TestModel;
7 | import org.rxjava.service.example.repository.ExampleRepository;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.web.bind.annotation.GetMapping;
10 | import org.springframework.web.bind.annotation.PathVariable;
11 | import org.springframework.web.bind.annotation.RequestMapping;
12 | import org.springframework.web.bind.annotation.RestController;
13 | import reactor.core.publisher.Mono;
14 |
15 | import javax.validation.Valid;
16 |
17 | /**
18 | * @author happy
19 | */
20 | @RestController
21 | @RequestMapping("mergeTestPath")
22 | @Slf4j
23 | public class TestController {
24 |
25 | @Autowired
26 | private ExampleRepository exampleRepository;
27 |
28 | /**
29 | * 路径变量测试
30 | */
31 | @GetMapping("path/{id}")
32 | public Mono testPath(
33 | @PathVariable String id,
34 | @Valid TestForm form
35 | ) {
36 | TestModel testModel = new TestModel();
37 | testModel.setId("haha");
38 | testModel.setName("我是testModel");
39 | log.info("TestController id:{}",id);
40 | log.info("TestController objectId:{}",form.getObjectId());
41 | log.info("TestController testPath:{}",testModel);
42 | Example example = new Example();
43 | example.setName("我是测试人员");
44 | return exampleRepository.save(example).thenReturn(testModel);
45 | }
46 | }
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/main/java/org/rxjava/service/example/repository/ExampleRepository.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.example.repository;
2 |
3 | import org.bson.types.ObjectId;
4 | import org.rxjava.service.example.entity.Example;
5 | import org.springframework.data.repository.reactive.ReactiveSortingRepository;
6 | import org.springframework.stereotype.Repository;
7 |
8 | @Repository
9 | public interface ExampleRepository extends ReactiveSortingRepository {
10 | }
11 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/main/java/org/rxjava/service/example/type/TestEnumType.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.example.type;
2 |
3 | public enum TestEnumType {
4 | PNG, JPG
5 | }
6 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: rxjava-service-example
4 | data:
5 | mongodb:
6 | uri: mongodb://127.0.0.1:27017
7 | database: rxjava-service-example
8 | auto-index-creation: false
9 | rabbitmq:
10 | host: 127.0.0.1
11 | port: 5672
12 | username: admin
13 | password: admin
14 | listener:
15 | simple:
16 | concurrency: 10
17 | max-concurrency: 10
18 | prefetch: 1
19 | default-requeue-rejected: true
20 | auto-startup: true
21 | cloud:
22 | kubernetes:
23 | config:
24 | enabled: false
25 | discovery:
26 | enabled: false
27 | bus:
28 | enabled: false
29 | server:
30 | port: 8080
31 | mock:
32 | userId: alkjqwerpoiuasdf
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/main/resources/exceptions/exception_zh_CN.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 异常消息
5 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/test/java/org/rxjava/api/example/test/TestApplication.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.api.example.test;
2 |
3 | import org.bson.types.ObjectId;
4 | import org.junit.jupiter.api.Test;
5 | import org.rxjava.api.example.form.TestForm;
6 | import org.rxjava.api.example.model.TestModel;
7 | import org.rxjava.api.example.person.TestApi;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.boot.test.context.SpringBootTest;
10 |
11 | @SpringBootTest(classes = {TestContext.class})
12 | public class TestApplication {
13 | @Autowired
14 | private TestApi testApi;
15 |
16 | @Test
17 | public void testSave() {
18 | TestForm form = new TestForm();
19 | form.setObjectId(new ObjectId());
20 | TestModel haha = testApi.testPath("haha", form).block();
21 | System.out.println(haha);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/rxjava-example/rxjava-service-example/src/test/java/org/rxjava/api/example/test/TestContext.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.api.example.test;
2 |
3 | import org.rxjava.api.example.person.TestApi;
4 | import org.rxjava.apikit.client.ClientAdapter;
5 | import org.rxjava.common.core.api.ReactiveHttpClientAdapter;
6 | import org.rxjava.service.starter.boot.RxJavaWebFluxConfigurer;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.context.annotation.Import;
10 | import org.springframework.format.support.DefaultFormattingConversionService;
11 | import org.springframework.web.reactive.function.client.WebClient;
12 |
13 | @Configuration
14 | public class TestContext {
15 |
16 | @Bean
17 | public ClientAdapter clientAdapter() {
18 | return ReactiveHttpClientAdapter.build(new DefaultFormattingConversionService(), WebClient.builder(), "localhost");
19 | }
20 |
21 | @Bean
22 | public TestApi testApi(ClientAdapter clientAdapter) {
23 | TestApi testApi = new TestApi();
24 | testApi.setClientAdapter(clientAdapter);
25 | return testApi;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/rxjava-gateway/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | org.rxjava
6 | rxjava
7 | 1.0.9-SNAPSHOT
8 |
9 | rxjava-gateway
10 | pom
11 |
12 | gateway
13 | Gateway
14 |
15 |
16 |
17 | org.rxjava
18 | rxjava-spring-cloud-starter-gateway
19 | ${project.parent.version}
20 |
21 |
22 |
--------------------------------------------------------------------------------
/rxjava-service/README.md:
--------------------------------------------------------------------------------
1 | ### 一、模块说明
2 |
3 | rxjava-apikit-maven-plugin
4 |
5 | 主要是整合了api基本的生成配置
6 |
7 | 子项目可进行一下的一些配置
8 |
9 | ```xml
10 |
11 | ${项目api生成后git推送的地址路径}
12 | ${模块名称,纯英文,首字母小写}
13 | ${模块名称,同module.name,首字母大写}
14 | ${模块类型,默认为service,可根据需要进行修改,首字母小写}
15 | ${模块类型,默认为Service,可根据需要进行修改,首字母大写}
16 |
17 | ```
18 |
--------------------------------------------------------------------------------
/rxjava-spring/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | org.rxjava
5 | rxjava
6 | 1.0.9-SNAPSHOT
7 |
8 | 4.0.0
9 | rxjava-spring
10 | pom
11 |
12 | rxjava-spring-boot-core
13 | rxjava-spring-boot-starter-service
14 | rxjava-spring-cloud-starter-gateway
15 | rxjava-spring-cloud-starter-bus
16 | rxjava-spring-mock-starter
17 |
18 |
19 |
20 | org.springframework.boot
21 | spring-boot-starter-webflux
22 |
23 |
24 | org.springframework.boot
25 | spring-boot-starter-data-mongodb-reactive
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-data-redis-reactive
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-actuator
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-validation
38 |
39 |
40 | org.springframework.cloud
41 | spring-cloud-starter-kubernetes-all
42 |
43 |
44 | org.springframework.retry
45 | spring-retry
46 |
47 |
48 | org.springframework.boot
49 | spring-boot-starter-test
50 | test
51 |
52 |
53 | org.junit.vintage
54 | junit-vintage-engine
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | org.rxjava
6 | rxjava-spring
7 | 1.0.9-SNAPSHOT
8 |
9 | rxjava-spring-boot-core
10 | jar
11 |
12 |
13 | org.rxjava
14 | rxjava-apikit-core
15 | ${project.parent.version}
16 |
17 |
18 |
19 | org.assertj
20 | assertj-core
21 |
22 |
23 | com.belerweb
24 | pinyin4j
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/RxJavaCoreAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core;
2 |
3 | import org.rxjava.common.core.tools.RequestTool;
4 | import org.springframework.boot.autoconfigure.AutoConfigureOrder;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.context.annotation.Primary;
8 | import org.springframework.core.Ordered;
9 |
10 | @Configuration
11 | @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
12 | public class RxJavaCoreAutoConfiguration {
13 | /**
14 | * 网络请求工具
15 | */
16 | @Bean
17 | @Primary
18 | public RequestTool requestTool(){
19 | return new RequestTool();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/annotation/Check.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * 认证授权检查
7 | */
8 | @Target(ElementType.METHOD)
9 | @Retention(RetentionPolicy.RUNTIME)
10 | @Documented
11 | public @interface Check {
12 | boolean value() default true;
13 | }
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/annotation/EnumValue.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.annotation;
2 |
3 |
4 | import org.assertj.core.util.Strings;
5 |
6 | import javax.validation.Constraint;
7 | import javax.validation.ConstraintValidator;
8 | import javax.validation.ConstraintValidatorContext;
9 | import javax.validation.Payload;
10 | import java.lang.annotation.ElementType;
11 | import java.lang.annotation.Retention;
12 | import java.lang.annotation.RetentionPolicy;
13 | import java.lang.annotation.Target;
14 | import java.lang.reflect.InvocationTargetException;
15 | import java.lang.reflect.Method;
16 | import java.lang.reflect.Modifier;
17 |
18 | /**
19 | * 校验枚举值有效性
20 | * @author happy on 2018-05-25.
21 | */
22 | @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
23 | @Retention(RetentionPolicy.RUNTIME)
24 | @Constraint(validatedBy = EnumValue.Validator.class)
25 | public @interface EnumValue {
26 |
27 | String message() default "value is not enum";
28 |
29 | Class>[] groups() default {};
30 |
31 | Class extends Payload>[] payload() default {};
32 |
33 | Class extends Enum>> enumClass();
34 |
35 | String enumMethod() default "isValidName";
36 |
37 | class Validator implements ConstraintValidator {
38 |
39 | private Class extends Enum>> enumClass;
40 | private String enumMethod;
41 |
42 | @Override
43 | public void initialize(EnumValue enumValue) {
44 | enumMethod = enumValue.enumMethod();
45 | enumClass = enumValue.enumClass();
46 | }
47 |
48 | @Override
49 | public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
50 | if (value == null) {
51 | return Boolean.TRUE;
52 | }
53 |
54 | if (enumClass == null || enumMethod == null) {
55 | return Boolean.TRUE;
56 | }
57 |
58 | Class> valueClass = value.getClass();
59 |
60 | try {
61 | Method method = enumClass.getMethod(enumMethod, valueClass);
62 | if (!Boolean.TYPE.equals(method.getReturnType()) && !Boolean.class.equals(method.getReturnType())) {
63 | throw new RuntimeException(Strings.formatIfArgs("%s method return is not boolean type in the %s class", enumMethod, enumClass));
64 | }
65 |
66 | if(!Modifier.isStatic(method.getModifiers())) {
67 | throw new RuntimeException(Strings.formatIfArgs("%s method is not static method in the %s class", enumMethod, enumClass));
68 | }
69 |
70 | Boolean result = (Boolean)method.invoke(null, value);
71 | return result == null ? false : result;
72 | } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
73 | throw new RuntimeException(e);
74 | } catch (NoSuchMethodException | SecurityException e) {
75 | throw new RuntimeException(Strings.formatIfArgs("This %s(%s) method does not exist in the %s", enumMethod, valueClass, enumClass), e);
76 | }
77 | }
78 |
79 | }
80 | }
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/annotation/Login.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * 是否登陆注解
7 | * 默认为需要登陆
8 | */
9 | @Target(ElementType.METHOD)
10 | @Retention(RetentionPolicy.RUNTIME)
11 | @Documented
12 | public @interface Login {
13 | boolean value() default true;
14 | }
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/entity/BaseEntity.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.entity;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import org.springframework.data.annotation.CreatedDate;
6 | import org.springframework.data.annotation.LastModifiedDate;
7 | import org.springframework.data.annotation.Version;
8 | import org.springframework.data.mongodb.core.index.Indexed;
9 | import org.springframework.data.mongodb.core.mapping.Document;
10 |
11 | import java.time.LocalDateTime;
12 |
13 | import static org.springframework.data.mongodb.core.index.IndexDirection.DESCENDING;
14 |
15 | /**
16 | * @author happy 2019/10/20 02:10
17 | */
18 | @Getter
19 | @Setter
20 | @Document
21 | public class BaseEntity {
22 | private String id;
23 | @Version
24 | private long version;
25 | /**
26 | * 创建日期
27 | */
28 | @CreatedDate
29 | @Indexed(direction = DESCENDING)
30 | private LocalDateTime createDate;
31 | /**
32 | * 更新日期
33 | */
34 | @LastModifiedDate
35 | private LocalDateTime updateDate;
36 | }
37 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/entity/Image.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.entity;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * @author happy 2019-07-16 22:36
7 | * 图片
8 | */
9 | @Data
10 | public class Image {
11 | /**
12 | * 宽:单位像素
13 | */
14 | private int width;
15 | /**
16 | * 高:单位像素
17 | */
18 | private int height;
19 | /**
20 | * 存储Key
21 | */
22 | private String key;
23 | }
24 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/entity/KeyValue.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.entity;
2 |
3 | import lombok.*;
4 |
5 | import java.util.Objects;
6 |
7 | /**
8 | * @author happy 2019-04-22 15:47
9 | * 键值对对象
10 | */
11 | @Data
12 | public class KeyValue {
13 | private K key;
14 | private V value;
15 | }
16 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/entity/LoginInfo.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.entity;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | import java.time.LocalDateTime;
7 |
8 | /**
9 | * @author happy 2019-04-14 14:00
10 | * 登陆信息
11 | */
12 | @Getter
13 | @Setter
14 | public class LoginInfo {
15 | /**
16 | * 用户Id
17 | */
18 | private String userId;
19 | /**
20 | * 用户登陆信息对应的token
21 | */
22 | private String token;
23 | /**
24 | * 合作伙伴Id
25 | */
26 | private String partnerId;
27 | /**
28 | * 过期时间
29 | */
30 | private LocalDateTime expireDate;
31 | }
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/entity/Video.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.entity;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * @author happy 2019-07-16 22:36
7 | * 视频
8 | */
9 | @Data
10 | public class Video {
11 | /**
12 | * 宽:单位像素
13 | */
14 | private int width;
15 | /**
16 | * 高:单位像素
17 | */
18 | private int height;
19 | /**
20 | * 存储Key
21 | */
22 | private String key;
23 | }
24 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/exception/DefaultError.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.exception;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4 | import org.springframework.context.support.DefaultMessageSourceResolvable;
5 |
6 | /**
7 | * @author happy 2019-04-16 23:45
8 | */
9 | @JsonIgnoreProperties("code")
10 | class DefaultError extends DefaultMessageSourceResolvable {
11 | DefaultError(String code) {
12 | super(code);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/exception/ErrorMessage.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.exception;
2 |
3 | import lombok.Data;
4 | import org.springframework.context.MessageSourceResolvable;
5 |
6 | import java.time.LocalDateTime;
7 | import java.util.ArrayList;
8 | import java.util.List;
9 | import java.util.stream.Stream;
10 |
11 | /**
12 | * @author happy 2019-04-18 01:14
13 | */
14 | @Data
15 | public class ErrorMessage implements MessageSourceResolvable {
16 | private String[] codes;
17 | private Object[] arguments;
18 | private String defaultMessage;
19 | private LocalDateTime timestamp;
20 | private String path;
21 | private String message;
22 | private List errors;
23 | /**
24 | * 状态字段
25 | */
26 | private int status;
27 |
28 | public ErrorMessage(String[] codes, Object[] arguments, String defaultMessage) {
29 | this.codes = codes;
30 | this.arguments = arguments;
31 | this.defaultMessage = defaultMessage;
32 | }
33 |
34 | public ErrorMessage(String code, Object... args) {
35 | this(new String[]{code}, args);
36 | }
37 |
38 | public ErrorMessage(String[] codes, Object[] arguments) {
39 | this(codes, arguments, codes[0]);
40 | }
41 |
42 | public ErrorMessage(String code, String... argCode) {
43 | this(code, (Object[]) Stream.of(argCode)
44 | .map(DefaultError::new)
45 | .toArray(DefaultError[]::new));
46 | }
47 |
48 | public ErrorMessage addFieldObjs(String field, String[] codes, Object... args) {
49 | return add(new FieldError(field, codes, args));
50 | }
51 |
52 | public ErrorMessage add(FieldError fieldError) {
53 | if (errors == null) {
54 | errors = new ArrayList<>();
55 | }
56 | errors.add(fieldError);
57 | return this;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/exception/ErrorMessageException.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.exception;
2 |
3 | import org.apache.commons.lang3.ArrayUtils;
4 | import reactor.core.publisher.Mono;
5 |
6 | import java.text.MessageFormat;
7 | import java.util.stream.Stream;
8 |
9 | /**
10 | * @author happy 2019-04-16 23:37
11 | * 错误消息异常(可预知错误均抛出此异常)
12 | */
13 | public class ErrorMessageException extends RuntimeException {
14 | private ErrorMessage errorMessage;
15 | private ErrorMessageException(String[] codes, Object[] arguments, String defaultMessage, Throwable cause) {
16 | super(MessageFormat.format(
17 | "codes:{0},args:{1}, defaultMessage:{2}",
18 | ArrayUtils.toString(codes),
19 | ArrayUtils.toString(arguments),
20 | defaultMessage
21 | ), cause);
22 | this.errorMessage = new ErrorMessage(codes, arguments, defaultMessage);
23 | }
24 |
25 | /**
26 | * 解析错误码和参数码
27 | *
28 | * @param code 错误码
29 | * @param argsCode 参数码
30 | * @return 解析后的异常
31 | */
32 | private static ErrorMessageException parseCode(String code, String... argsCode) {
33 | return new ErrorMessageException(code, argsCode);
34 | }
35 |
36 | private ErrorMessageException(String code, String... argsCodes) {
37 | this(new String[]{code}, Stream.of(argsCodes).map(DefaultError::new).toArray(DefaultError[]::new), null, null);
38 | }
39 |
40 | public static Mono mono(String code) {
41 | return Mono.error(parseCode(code));
42 | }
43 |
44 | public static ErrorMessageException of(String code) {
45 | return new ErrorMessageException(new String[]{code}, null, null, null);
46 | }
47 |
48 | public ErrorMessage getErrorMessage() {
49 | return errorMessage;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/exception/FieldError.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.exception;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4 | import org.springframework.context.MessageSourceResolvable;
5 | import org.springframework.util.Assert;
6 | import reactor.util.annotation.Nullable;
7 |
8 | import java.util.Arrays;
9 |
10 | /**
11 | * @author happy 2019-04-18 01:32
12 | */
13 | @JsonIgnoreProperties("code")
14 | public class FieldError implements MessageSourceResolvable {
15 | private String[] codes;
16 | private Object[] arguments;
17 | private String defaultMessage;
18 |
19 |
20 | private String field;
21 | private String message;
22 |
23 | public FieldError() {
24 | }
25 |
26 | private FieldError(String[] codes, Object[] arguments, String defaultMessage) {
27 | this.codes = codes;
28 | this.arguments = arguments;
29 | this.defaultMessage = defaultMessage;
30 | }
31 |
32 | /**
33 | * Create a new instance of the ObjectError class.
34 | *
35 | * @param field the name of the affected object
36 | * @param defaultMessage the default message to be used to resolve this message
37 | */
38 | public FieldError(String field, String defaultMessage) {
39 | this(field, null, null, defaultMessage);
40 | }
41 |
42 | /**
43 | * Create a new instance of the ObjectError class.
44 | *
45 | * @param field the name of the affected object
46 | * @param codes the codes to be used to resolve this message
47 | * @param arguments the array of arguments to be used to resolve this message
48 | * @param defaultMessage the default message to be used to resolve this message
49 | */
50 | public FieldError(
51 | String field,
52 | @Nullable String[] codes,
53 | @Nullable Object[] arguments,
54 | @Nullable String defaultMessage) {
55 | this(codes, arguments, defaultMessage);
56 | Assert.notNull(field, "Object name must not be null");
57 | this.field = field;
58 | }
59 |
60 | public FieldError(
61 | String field,
62 | @Nullable String[] codes,
63 | @Nullable Object[] arguments
64 | ) {
65 | this(codes, arguments, null);
66 | Assert.notNull(field, "Object name must not be null");
67 | this.field = field;
68 | }
69 |
70 | public String getField() {
71 | return field;
72 | }
73 |
74 |
75 | public String getMessage() {
76 | return message;
77 | }
78 |
79 | public void setMessage(String message) {
80 | this.message = message;
81 | }
82 |
83 |
84 | @Override
85 | public String[] getCodes() {
86 | return this.codes;
87 | }
88 |
89 |
90 | public String getCode() {
91 | return this.codes != null && this.codes.length > 0 ? this.codes[this.codes.length - 1] : null;
92 | }
93 |
94 | public void setField(String field) {
95 | this.field = field;
96 | }
97 |
98 | @Override
99 | public Object[] getArguments() {
100 | return this.arguments;
101 | }
102 |
103 |
104 | @Override
105 | public String getDefaultMessage() {
106 | String defaultMessage = this.defaultMessage;
107 | if (defaultMessage == null) {
108 | return getCode();
109 | }
110 | return defaultMessage;
111 | }
112 |
113 | public void setCodes(String[] codes) {
114 | this.codes = codes;
115 | }
116 |
117 | public void setArguments(Object[] arguments) {
118 | this.arguments = arguments;
119 | }
120 |
121 | public void setDefaultMessage(String defaultMessage) {
122 | this.defaultMessage = defaultMessage;
123 | }
124 |
125 | @Override
126 | public String toString() {
127 | return "FieldError{" +
128 | "codes=" + Arrays.toString(codes) +
129 | ", arguments=" + Arrays.toString(arguments) +
130 | ", defaultMessage='" + defaultMessage + '\'' +
131 | ", field='" + field + '\'' +
132 | ", message='" + message + '\'' +
133 | '}';
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/exception/ForbiddenException.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.exception;
2 |
3 | import org.apache.commons.lang3.ArrayUtils;
4 | import reactor.core.publisher.Mono;
5 |
6 | import java.text.MessageFormat;
7 | import java.util.stream.Stream;
8 |
9 | public class ForbiddenException extends RuntimeException {
10 | private ErrorMessage errorMessage;
11 |
12 | public ForbiddenException(String message) {
13 | super(message);
14 | }
15 |
16 | private ForbiddenException(String[] codes, Object[] arguments, String defaultMessage, Throwable cause) {
17 | super(MessageFormat.format(
18 | "codes:{0},args:{1}, defaultMessage:{2}",
19 | ArrayUtils.toString(codes),
20 | ArrayUtils.toString(arguments),
21 | defaultMessage
22 | ), cause);
23 | this.errorMessage = new ErrorMessage(codes, arguments, defaultMessage);
24 | }
25 |
26 | public static ForbiddenException of(String message) {
27 | return new ForbiddenException(message);
28 | }
29 |
30 | private static ForbiddenException parseCode(String code, String... argsCode) {
31 | return new ForbiddenException(code, argsCode);
32 | }
33 |
34 | private ForbiddenException(String code, String... argsCodes) {
35 | this(new String[]{code}, Stream.of(argsCodes).map(DefaultError::new).toArray(DefaultError[]::new), null, null);
36 | }
37 |
38 | public static Mono mono(String code) {
39 | return Mono.error(parseCode(code));
40 | }
41 |
42 | public ErrorMessage getErrorMessage() {
43 | return errorMessage;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/exception/UnauthorizedException.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.exception;
2 |
3 | import org.apache.commons.lang3.ArrayUtils;
4 | import reactor.core.publisher.Mono;
5 |
6 | import java.text.MessageFormat;
7 | import java.util.stream.Stream;
8 |
9 | public class UnauthorizedException extends RuntimeException {
10 | private ErrorMessage errorMessage;
11 |
12 | public UnauthorizedException(String message) {
13 | super(message);
14 | }
15 |
16 | private UnauthorizedException(String[] codes, Object[] arguments, String defaultMessage, Throwable cause) {
17 | super(MessageFormat.format(
18 | "codes:{0},args:{1}, defaultMessage:{2}",
19 | ArrayUtils.toString(codes),
20 | ArrayUtils.toString(arguments),
21 | defaultMessage
22 | ), cause);
23 | this.errorMessage = new ErrorMessage(codes, arguments, defaultMessage);
24 | }
25 |
26 | public static UnauthorizedException of(String message) {
27 | return new UnauthorizedException(message);
28 | }
29 |
30 | private static UnauthorizedException parseCode(String code, String... argsCode) {
31 | return new UnauthorizedException(code, argsCode);
32 | }
33 |
34 | private UnauthorizedException(String code, String... argsCodes) {
35 | this(new String[]{code}, Stream.of(argsCodes).map(DefaultError::new).toArray(DefaultError[]::new), null, null);
36 | }
37 |
38 | public static Mono mono(String code) {
39 | return Mono.error(parseCode(code));
40 | }
41 |
42 | public ErrorMessage getErrorMessage() {
43 | return errorMessage;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/form/PageForm.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.form;
2 |
3 | import lombok.Data;
4 | import lombok.Getter;
5 | import lombok.Setter;
6 |
7 | import javax.validation.constraints.Max;
8 | import javax.validation.constraints.Min;
9 |
10 | /**
11 | * @author happy 2019-04-27 10:53
12 | */
13 | @Getter
14 | @Setter
15 | public class PageForm {
16 | /**
17 | * 页码
18 | */
19 | @Min(value = 0, message = "页面最小为0")
20 | private int page = 0;
21 | /**
22 | * 页大小
23 | */
24 | @Min(value = 1, message = "页大小最小为1")
25 | @Max(value = 100, message = "页大小最大为100")
26 | private int pageSize = 10;
27 | }
28 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/mongo/PageAgent.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.mongo;
2 |
3 | import org.springframework.data.domain.Page;
4 | import org.springframework.data.domain.PageImpl;
5 | import org.springframework.data.domain.PageRequest;
6 | import org.springframework.data.domain.Pageable;
7 | import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
8 | import org.springframework.data.mongodb.core.query.Query;
9 | import reactor.core.publisher.Mono;
10 |
11 | import java.util.List;
12 |
13 | /**
14 | * @author happy 2019-04-27 11:06
15 | */
16 | public class PageAgent {
17 | private ReactiveMongoTemplate reactiveMongoTemplate;
18 | private Class clazz;
19 |
20 | public PageAgent(ReactiveMongoTemplate reactiveMongoTemplate, Class clazz) {
21 | this.reactiveMongoTemplate = reactiveMongoTemplate;
22 | this.clazz = clazz;
23 | }
24 |
25 | public Mono> findPage(Query query, Pageable pageable) {
26 | return Mono.subscriberContext()
27 | .flatMap(context -> Mono
28 | .zip(
29 | reactiveMongoTemplate.find(query, clazz).collectList(),
30 | reactiveMongoTemplate.count(query, clazz)
31 | )
32 | .map(z -> {
33 | List goodsList = z.getT1();
34 | Long num = z.getT2();
35 | return new PageImpl<>(goodsList, PageRequest.of(pageable.getPageNumber(), pageable.getPageSize()), num);
36 | })
37 | );
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/service/DefaultLoginInfoServiceImpl.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.service;
2 |
3 | import org.rxjava.common.core.entity.LoginInfo;
4 | import org.springframework.web.server.ServerWebExchange;
5 | import reactor.core.publisher.Mono;
6 |
7 | /**
8 | * @author happy 2019-06-29 18:23
9 | * 默认登陆信息服务
10 | */
11 | public class DefaultLoginInfoServiceImpl implements LoginInfoService {
12 | /**
13 | * Token检查
14 | */
15 | @Override
16 | public Mono checkToken(ServerWebExchange serverWebExchange) {
17 | return Mono.empty();
18 | }
19 | }
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/service/LoginInfoService.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.service;
2 |
3 | import org.rxjava.common.core.entity.LoginInfo;
4 | import org.springframework.http.HttpMethod;
5 | import org.springframework.web.server.ServerWebExchange;
6 | import reactor.core.publisher.Mono;
7 |
8 | /**
9 | * @author happy 2019-06-29 21:52
10 | */
11 | public interface LoginInfoService {
12 |
13 | /**
14 | * token校验
15 | */
16 | Mono checkToken(ServerWebExchange serverWebExchange);
17 | }
18 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/status/Status.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.status;
2 |
3 | /**
4 | * @author happy 2019-04-27 10:31
5 | */
6 | public enum Status {
7 | /**
8 | * 正常
9 | */
10 | NORMAL,
11 | /**
12 | * 下线
13 | */
14 | OFFLINE,
15 | /**
16 | * 删除
17 | */
18 | DELETE
19 | }
20 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/tools/RequestTool.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.tools;
2 |
3 | import com.fasterxml.jackson.databind.JsonNode;
4 | import com.fasterxml.jackson.databind.node.JsonNodeFactory;
5 | import org.rxjava.common.core.utils.JsonUtils;
6 | import org.springframework.http.HttpMethod;
7 | import org.springframework.util.LinkedMultiValueMap;
8 | import org.springframework.util.MultiValueMap;
9 | import org.springframework.util.StringUtils;
10 | import org.springframework.web.reactive.function.BodyInserters;
11 | import org.springframework.web.reactive.function.client.WebClient;
12 | import reactor.core.publisher.Mono;
13 |
14 | /**
15 | * @author happy 2019/10/5 11:54
16 | */
17 | public class RequestTool {
18 |
19 | public Mono get(String requestUrl) {
20 | return get(requestUrl, new LinkedMultiValueMap<>());
21 | }
22 |
23 | /**
24 | * get请求
25 | * 路径参数
26 | */
27 | public Mono get(String requestUrl, MultiValueMap params) {
28 | return WebClient.create(requestUrl)
29 | .method(HttpMethod.GET)
30 | .uri(uriBuilder -> {
31 | if (params.isEmpty()) {
32 | return uriBuilder.build();
33 | }
34 | return uriBuilder.queryParams(params).build();
35 | })
36 | .retrieve()
37 | .bodyToMono(String.class)
38 | .map(jsonStr -> {
39 | if (StringUtils.isEmpty(jsonStr) || !(jsonStr.startsWith("[") || jsonStr.startsWith("{"))) {
40 | return JsonNodeFactory.instance.missingNode();
41 | }
42 | return JsonUtils.deserialize(jsonStr, JsonNode.class);
43 | });
44 | }
45 |
46 | public Mono post(String requestUrl) {
47 | return post(requestUrl, new LinkedMultiValueMap<>());
48 | }
49 |
50 | /**
51 | * post请求
52 | * formdata参数
53 | */
54 | public Mono post(String requestUrl, MultiValueMap params) {
55 | return WebClient.create(requestUrl)
56 | .method(HttpMethod.POST)
57 | .body(BodyInserters.fromFormData(params))
58 | .retrieve()
59 | .bodyToMono(String.class);
60 | }
61 |
62 | public static void main(String[] args) {
63 | JsonNode block = new RequestTool().get("https://qy-h5-dev.billbear.cn/api/javahotel/cityList").block();
64 | System.out.println(block);
65 | }
66 | }
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/utils/ErrorMessageUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.utils;
2 |
3 | import org.rxjava.common.core.exception.ErrorMessage;
4 | import org.springframework.context.support.MessageSourceAccessor;
5 | import org.springframework.util.CollectionUtils;
6 |
7 | /**
8 | * @author happy 2019-04-18 01:25
9 | */
10 | public class ErrorMessageUtils {
11 | public static ErrorMessage handlerI18n(ErrorMessage errorMessage, MessageSourceAccessor messageSourceAccessor) {
12 | if (errorMessage.getMessage() == null) {
13 | errorMessage.setMessage(messageSourceAccessor.getMessage(errorMessage));
14 | }
15 |
16 | if (!CollectionUtils.isEmpty(errorMessage.getErrors())) {
17 | errorMessage.getErrors().forEach(fieldError -> {
18 | if (fieldError.getMessage() == null) {
19 | fieldError.setMessage(messageSourceAccessor.getMessage(fieldError));
20 | }
21 | });
22 | }
23 | return errorMessage;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/utils/FileRenameUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.utils;
2 |
3 | import net.sourceforge.pinyin4j.PinyinHelper;
4 | import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
5 | import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
6 | import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
7 | import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
8 | import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
9 | import org.apache.commons.lang3.ArrayUtils;
10 | import org.apache.commons.lang3.StringUtils;
11 |
12 | import java.io.IOException;
13 | import java.nio.file.Files;
14 | import java.nio.file.Path;
15 | import java.nio.file.Paths;
16 | import java.nio.file.StandardCopyOption;
17 | import java.util.stream.Collectors;
18 |
19 | /**
20 | * @author happy 2019-06-20 14:41
21 | */
22 | public class FileRenameUtils {
23 | public static final HanyuPinyinOutputFormat FORMAT = new HanyuPinyinOutputFormat();
24 |
25 | static {
26 | FORMAT.setCaseType(HanyuPinyinCaseType.LOWERCASE);
27 | FORMAT.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
28 | FORMAT.setVCharType(HanyuPinyinVCharType.WITH_V);
29 | }
30 |
31 | public static void main(String[] args) {
32 |
33 | Path source = Paths.get("/Users/happy/DeskTop/img");
34 | Path dist = Paths.get("/Users/happy/DeskTop/img_py");
35 | handler(source, dist, "@", "Select");
36 | }
37 |
38 | private static void handler(Path source, Path dist, String split, String suffix) {
39 | try {
40 | if (Files.isDirectory(source)) {
41 | Files.list(source).forEach(child -> {
42 | Path fileName = child.getFileName();
43 | String pinyinName = toPinyin(fileName.getFileName().toString());
44 | if (StringUtils.isNoneEmpty(split, suffix)) {
45 | pinyinName = pinyinName.replace(split, suffix + split);
46 | }
47 | handler(child, dist.resolve(pinyinName));
48 | });
49 | } else {
50 | String pinyinName = toPinyin(dist.getFileName().toString()) + suffix;
51 | Files.createDirectories(dist.getParent());
52 | Files.copy(source, dist.resolveSibling(pinyinName), StandardCopyOption.REPLACE_EXISTING);
53 | }
54 | } catch (IOException ex) {
55 | throw new RuntimeException(ex);
56 | }
57 | }
58 |
59 | private static void handler(Path source, Path dist) {
60 | handler(source, dist, "", "");
61 | }
62 |
63 | public static String toPinyin(String name) {
64 | return name.chars().mapToObj((int r) -> {
65 | try {
66 | char ch = (char) r;
67 | String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(ch, FORMAT);
68 | if (ArrayUtils.isEmpty(pinyins)) {
69 | return Character.toString(ch);
70 | } else {
71 | String pinyin = pinyins[0];
72 | return pinyin.substring(0, 1).toUpperCase() +
73 | (pinyin.length() > 1 ? pinyin.substring(1) : "");
74 | }
75 | } catch (BadHanyuPinyinOutputFormatCombination ex) {
76 | throw new RuntimeException(ex);
77 | }
78 | }).collect(Collectors.joining());
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/utils/JavaTimeModuleUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.utils;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.core.JsonParser;
5 | import com.fasterxml.jackson.databind.DeserializationContext;
6 | import com.fasterxml.jackson.databind.JsonDeserializer;
7 | import com.fasterxml.jackson.databind.JsonSerializer;
8 | import com.fasterxml.jackson.databind.SerializerProvider;
9 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
10 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
11 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
12 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
13 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
14 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
15 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
16 | import lombok.Getter;
17 |
18 | import java.io.IOException;
19 | import java.time.*;
20 | import java.time.format.DateTimeFormatter;
21 |
22 | /**
23 | * 日期时间模块帮助类
24 | */
25 | public class JavaTimeModuleUtils {
26 | @Getter
27 | private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
28 | @Getter
29 | private static final String DATE_FORMAT = "yyyy-MM-dd";
30 | @Getter
31 | private static final String TIME_FORMAT = "HH:mm:ss.SSS";
32 | @Getter
33 | private static JavaTimeModule javaTimeModule = new JavaTimeModule();
34 |
35 | /**
36 | * 禁止实例化
37 | */
38 | private JavaTimeModuleUtils() {
39 | }
40 |
41 | /**
42 | * 添加日期时间格式解析支持
43 | */
44 | public static void addAllFormatter(){
45 | addTimeFormatter();
46 | addInstantFormatter();
47 | addDateTimeFormatter();
48 | addDateFormatter();
49 | }
50 |
51 | /**
52 | * 添加日期时间格式支持
53 | */
54 | private static void addDateTimeFormatter() {
55 | DateTimeFormatter dataTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT).withZone(ZoneId.systemDefault());
56 | javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dataTimeFormatter));
57 | javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dataTimeFormatter));
58 | }
59 |
60 | /**
61 | * 添加日期格式支持
62 | */
63 | private static void addDateFormatter() {
64 | DateTimeFormatter dataFormatter = DateTimeFormatter.ofPattern(DATE_FORMAT).withZone(ZoneId.systemDefault());
65 | javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dataFormatter));
66 | javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dataFormatter));
67 | }
68 |
69 | /**
70 | * 添加时间格式支持
71 | */
72 | private static void addTimeFormatter() {
73 | DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(TIME_FORMAT).withZone(ZoneId.systemDefault());
74 | javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(timeFormatter));
75 | javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(timeFormatter));
76 | }
77 |
78 | /**
79 | * 添加Instant格式支持
80 | */
81 | private static void addInstantFormatter(){
82 | DateTimeFormatter dataTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT).withZone(ZoneId.systemDefault());
83 | javaTimeModule.addDeserializer(Instant.class, new JsonDeserializer() {
84 | @Override
85 | public Instant deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
86 | return Instant.from(dataTimeFormatter.parse(jsonParser.getText()));
87 | }
88 | });
89 | javaTimeModule.addSerializer(Instant.class, new JsonSerializer() {
90 | @Override
91 | public void serialize(Instant value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
92 | String str = dataTimeFormatter.format(value);
93 | gen.writeString(str);
94 | }
95 | });
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/utils/JsonUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.utils;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 |
5 | import java.io.IOException;
6 | import java.util.List;
7 |
8 | /**
9 | * @author happy 2019-04-16 23:26
10 | */
11 | public class JsonUtils {
12 | public static final ObjectMapper DEFAULT_MAPPER = new ObjectMapper();
13 |
14 | public static ObjectMapper create() {
15 | return new ObjectMapper();
16 | }
17 |
18 | /**
19 | * 反序列化Json字符串
20 | */
21 | public static T deserialize(String json, Class valueType) {
22 | try {
23 | return DEFAULT_MAPPER.readValue(json, valueType);
24 | } catch (IOException e) {
25 | throw new RuntimeException(e.getMessage(), e);
26 | }
27 | }
28 |
29 | public static String serialize(Object o) {
30 | try {
31 | if (o instanceof List) {
32 | return DEFAULT_MAPPER.writeValueAsString(((List>) o).toArray());
33 | }
34 | return DEFAULT_MAPPER.writeValueAsString(o);
35 | } catch (IOException e) {
36 | throw new RuntimeException(e.getMessage(), e);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/utils/KeyUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.utils;
2 |
3 | /**
4 | * @author happy 2019-04-27 00:30
5 | */
6 | public class KeyUtils {
7 | public static String newCacheId(Class clazz, String key) {
8 | return clazz.getSimpleName() + "-" + key;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-core/src/main/java/org/rxjava/common/core/utils/UUIDUtils.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.core.utils;
2 |
3 | import java.util.Base64;
4 | import java.util.UUID;
5 |
6 | /**
7 | * @author happy 2019-01-12 22:41
8 | * UUID帮助类
9 | */
10 | public class UUIDUtils {
11 | public static String randomUUIDToBase64() {
12 | UUID uuid = UUID.randomUUID();
13 | byte[] uuidArr = asByteArray(uuid);
14 | return Base64.getUrlEncoder().withoutPadding().encodeToString(uuidArr);
15 | }
16 |
17 | public static void main(String[] args) {
18 | System.out.println(randomUUIDToBase64());
19 | System.out.println(randomUUIDToBase64().length());
20 | }
21 |
22 | public static byte[] asByteArray(UUID uuid) {
23 | long msb = uuid.getMostSignificantBits();
24 | long lsb = uuid.getLeastSignificantBits();
25 | byte[] buffer = new byte[16];
26 |
27 | for (int i = 0; i < 8; i++) {
28 | buffer[i] = (byte) (msb >>> 8 * (7 - i));
29 | }
30 | for (int i = 8; i < 16; i++) {
31 | buffer[i] = (byte) (lsb >>> 8 * (7 - i));
32 | }
33 |
34 | return buffer;
35 | }
36 |
37 | public static UUID toUUID(byte[] byteArray) {
38 |
39 | long msb = 0;
40 | long lsb = 0;
41 | for (int i = 0; i < 8; i++) {
42 | msb = (msb << 8) | (byteArray[i] & 0xff);
43 | }
44 | for (int i = 8; i < 16; i++) {
45 | lsb = (lsb << 8) | (byteArray[i] & 0xff);
46 | }
47 | return new UUID(msb, lsb);
48 | }
49 | }
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-starter-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | org.rxjava
5 | rxjava-spring
6 | 1.0.9-SNAPSHOT
7 |
8 | 4.0.0
9 | rxjava-spring-boot-starter-service
10 | jar
11 |
12 |
13 | org.rxjava
14 | rxjava-spring-boot-core
15 | ${project.parent.version}
16 |
17 |
18 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-starter-service/src/main/java/org/rxjava/service/starter/RxJavaServiceAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.starter;
2 |
3 | import org.rxjava.service.starter.boot.RxJavaWebFluxConfigurer;
4 | import org.rxjava.service.starter.boot.ServiceDelegatingWebFluxConfiguration;
5 | import org.springframework.boot.autoconfigure.AutoConfigureOrder;
6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.context.annotation.Import;
9 | import org.springframework.core.Ordered;
10 | import org.springframework.data.mongodb.config.EnableMongoAuditing;
11 |
12 | /**
13 | * @author happy 2019-04-09 01:32
14 | * RxJava微服务自动装配
15 | */
16 | @Configuration
17 | @EnableDiscoveryClient
18 | @EnableMongoAuditing
19 | @Import({ServiceDelegatingWebFluxConfiguration.class, RxJavaWebFluxConfigurer.class})
20 | @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
21 | public class RxJavaServiceAutoConfiguration {
22 | }
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-starter-service/src/main/java/org/rxjava/service/starter/boot/LoginInfoArgumentResolver.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.starter.boot;
2 |
3 | import org.rxjava.common.core.entity.LoginInfo;
4 | import org.springframework.core.MethodParameter;
5 | import org.springframework.core.ReactiveAdapterRegistry;
6 | import org.springframework.web.reactive.BindingContext;
7 | import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolverSupport;
8 | import org.springframework.web.reactive.result.method.SyncHandlerMethodArgumentResolver;
9 | import org.springframework.web.server.ServerWebExchange;
10 |
11 | /**
12 | * @author happy 2019-04-14 17:21
13 | * 登陆信息参数解析
14 | */
15 | public class LoginInfoArgumentResolver extends HandlerMethodArgumentResolverSupport implements SyncHandlerMethodArgumentResolver {
16 |
17 | static final String LOGIN_REQUEST_ATTRIBUTE = LoginInfoArgumentResolver.class.getName() + "LOGIN_REQUEST_ATTRIBUTE";
18 |
19 | public LoginInfoArgumentResolver(ReactiveAdapterRegistry adapterRegistry) {
20 | super(adapterRegistry);
21 | }
22 |
23 | @Override
24 | public boolean supportsParameter(MethodParameter parameter) {
25 | return parameter.getParameterType().equals(LoginInfo.class);
26 | }
27 |
28 | @Override
29 | public Object resolveArgumentValue(MethodParameter parameter, BindingContext bindingContext, ServerWebExchange exchange) {
30 | return exchange.getAttribute(LoginInfoArgumentResolver.LOGIN_REQUEST_ATTRIBUTE);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-starter-service/src/main/java/org/rxjava/service/starter/boot/RxJavaWebFluxConfigurer.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.starter.boot;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
6 | import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
7 | import org.rxjava.common.core.utils.JavaTimeModuleUtils;
8 | import org.rxjava.common.core.utils.JsonUtils;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.context.annotation.Bean;
11 | import org.springframework.context.annotation.Primary;
12 | import org.springframework.context.support.ReloadableResourceBundleMessageSource;
13 | import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;
14 | import org.springframework.data.redis.core.ReactiveRedisTemplate;
15 | import org.springframework.data.redis.serializer.RedisSerializationContext;
16 | import org.springframework.http.codec.ServerCodecConfigurer;
17 | import org.springframework.http.codec.json.Jackson2JsonDecoder;
18 | import org.springframework.http.codec.json.Jackson2JsonEncoder;
19 | import org.springframework.web.reactive.config.WebFluxConfigurer;
20 |
21 | import java.text.SimpleDateFormat;
22 |
23 | /**
24 | * @author happy 2019-05-13 01:30
25 | * WebFluxConfigurer
26 | */
27 | public class RxJavaWebFluxConfigurer implements WebFluxConfigurer {
28 |
29 | @Autowired
30 | private ObjectMapper objectMapper;
31 |
32 | /**
33 | * Redis Bean
34 | */
35 | @Bean
36 | @Primary
37 | ReactiveRedisTemplate reactiveRedisTemplate(ReactiveRedisConnectionFactory factory) {
38 | return new ReactiveRedisTemplate<>(factory, RedisSerializationContext.string());
39 | }
40 |
41 | /**
42 | * 使用指定的资源访问指定的名称,异常消息国际化处理
43 | */
44 | @Bean
45 | public ReloadableResourceBundleMessageSource messageSource() {
46 | ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
47 | messageSource.setBasenames(
48 | "classpath:exceptions/exception",
49 | "classpath:defaultExceptions/exception"
50 | );
51 | messageSource.setUseCodeAsDefaultMessage(true);
52 | messageSource.setCacheSeconds(99999999);
53 | return messageSource;
54 | }
55 |
56 | /**
57 | * 配置ObjectMapper
58 | */
59 | @Bean
60 | @Primary
61 | public ObjectMapper objectMapper() {
62 | ObjectMapper objectMapper = JsonUtils.create();
63 | //字段值为null则不输出
64 | objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
65 |
66 | //添加json日期时间序列化和反序列化格式支持
67 | JavaTimeModuleUtils.addAllFormatter();
68 |
69 | //注册模块
70 | objectMapper
71 | .registerModule(new ParameterNamesModule())
72 | .registerModule(new Jdk8Module())
73 | .registerModule(JavaTimeModuleUtils.getJavaTimeModule());
74 |
75 | //配置SimpleDateFormat格式为日期时间格式
76 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(JavaTimeModuleUtils.getDATE_TIME_FORMAT());
77 | simpleDateFormat.setLenient(false);
78 | objectMapper.setDateFormat(simpleDateFormat);
79 |
80 | return objectMapper;
81 | }
82 |
83 | /**
84 | * 配置json序列化和反序列化
85 | */
86 | @Override
87 | public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
88 | configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(objectMapper));
89 | configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(objectMapper));
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-starter-service/src/main/java/org/rxjava/service/starter/boot/SecurityRequestMappingHandlerAdapter.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.starter.boot;
2 |
3 | import org.apache.commons.lang3.ObjectUtils;
4 | import org.apache.commons.lang3.StringUtils;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.rxjava.common.core.annotation.Login;
8 | import org.rxjava.common.core.entity.LoginInfo;
9 | import org.rxjava.common.core.exception.ErrorMessageException;
10 | import org.rxjava.common.core.exception.UnauthorizedException;
11 | import org.rxjava.common.core.utils.JsonUtils;
12 | import org.springframework.http.server.PathContainer;
13 | import org.springframework.http.server.reactive.ServerHttpRequest;
14 | import org.springframework.web.method.HandlerMethod;
15 | import org.springframework.web.reactive.HandlerResult;
16 | import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
17 | import org.springframework.web.server.ServerWebExchange;
18 | import reactor.core.publisher.Mono;
19 |
20 | import java.io.UnsupportedEncodingException;
21 | import java.net.URLDecoder;
22 |
23 | import static org.rxjava.service.starter.boot.LoginInfoArgumentResolver.LOGIN_REQUEST_ATTRIBUTE;
24 |
25 | /**
26 | * @author happy 2019-04-16 23:05
27 | * 请求映射适配器
28 | */
29 | public class SecurityRequestMappingHandlerAdapter extends RequestMappingHandlerAdapter {
30 | private static final Logger log = LogManager.getLogger();
31 | private static final String LOGIN_INFO = "loginInfo";
32 |
33 | SecurityRequestMappingHandlerAdapter() {
34 | super();
35 | }
36 |
37 | @Override
38 | public boolean supports(Object handler) {
39 | return super.supports(handler);
40 | }
41 |
42 | @Override
43 | public Mono handle(ServerWebExchange exchange, Object handler) {
44 | HandlerMethod handlerMethod = (HandlerMethod) handler;
45 |
46 | ServerHttpRequest request = exchange.getRequest();
47 | PathContainer path = request.getPath().pathWithinApplication();
48 | String pathValue = path.value();
49 |
50 | //微服务彼此间接口不注入登陆信息(信息均需要明确传入)
51 | if (pathValue.startsWith("/inner/")) {
52 | return super.handle(exchange, handler);
53 | }
54 |
55 | //检查接口方法是否需要登陆
56 | Login login = handlerMethod.getMethodAnnotation(Login.class);
57 | if (login == null || login.value()) {
58 |
59 | String loginInfoJson = request.getHeaders().getFirst(LOGIN_INFO);
60 | LoginInfo loginInfo = parseLoginJson(loginInfoJson);
61 |
62 | if (loginInfo == null) {
63 | throw UnauthorizedException.of("unauthorized");
64 | }
65 | //请求参数注入登陆信息对象
66 | exchange.getAttributes().put(LOGIN_REQUEST_ATTRIBUTE, loginInfo);
67 | }
68 | return super.handle(exchange, handler);
69 | }
70 |
71 | /**
72 | * 解析网关注入的登陆信息
73 | */
74 | private LoginInfo parseLoginJson(String loginInfoJson) {
75 | log.info("parseLoginJson:{}", loginInfoJson);
76 | if (StringUtils.isEmpty(loginInfoJson)) {
77 | return null;
78 | }
79 | try {
80 | loginInfoJson = URLDecoder.decode(loginInfoJson, "utf8");
81 | } catch (UnsupportedEncodingException e) {
82 | throw new RuntimeException(e);
83 | }
84 | return JsonUtils.deserialize(loginInfoJson, LoginInfo.class);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-starter-service/src/main/java/org/rxjava/service/starter/boot/ServiceDelegatingWebFluxConfiguration.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.service.starter.boot;
2 |
3 | import org.rxjava.common.core.exception.JsonResponseStatusExceptionHandler;
4 | import org.springframework.beans.factory.ObjectProvider;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.core.Ordered;
7 | import org.springframework.core.annotation.Order;
8 | import org.springframework.http.codec.ServerCodecConfigurer;
9 | import org.springframework.web.reactive.config.DelegatingWebFluxConfiguration;
10 | import org.springframework.web.reactive.result.method.annotation.ArgumentResolverConfigurer;
11 | import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
12 | import org.springframework.web.reactive.result.view.ViewResolver;
13 | import org.springframework.web.server.WebExceptionHandler;
14 |
15 | import java.util.Collections;
16 | import java.util.List;
17 |
18 | /**
19 | * @author happy 2019-04-16 23:04
20 | * DelegatingWebFluxConfiguration
21 | */
22 | public class ServiceDelegatingWebFluxConfiguration extends DelegatingWebFluxConfiguration {
23 |
24 | @Override
25 | protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {
26 | return new SecurityRequestMappingHandlerAdapter();
27 | }
28 |
29 | /**
30 | * 异常处理器(排在所有异常处理器最前面)
31 | */
32 | @Bean
33 | @Order(Ordered.HIGHEST_PRECEDENCE)
34 | public WebExceptionHandler jsonResponseStatusExceptionHandler(
35 | ObjectProvider> viewResolversProvider,
36 | ServerCodecConfigurer serverCodecConfigurer
37 | ) {
38 | JsonResponseStatusExceptionHandler handler = new JsonResponseStatusExceptionHandler();
39 | handler.setMessageWriters(serverCodecConfigurer.getWriters());
40 | handler.setViewResolvers(viewResolversProvider.getIfAvailable(Collections::emptyList));
41 | return handler;
42 | }
43 |
44 | /**
45 | * 自定义方法参数配置解析器
46 | */
47 | @Override
48 | public void configureArgumentResolvers(ArgumentResolverConfigurer configurer) {
49 | configurer.addCustomResolver(new LoginInfoArgumentResolver(webFluxAdapterRegistry()));
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-starter-service/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.rxjava.service.starter.RxJavaServiceAutoConfiguration
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-starter-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | logging:
2 | level:
3 | root: INFO
4 | org:
5 | springframework:
6 | #控制台打印mongodb操作数据库的日志信息
7 | data.mongodb.core.ReactiveMongoTemplate: DEBUG
8 | context.support: TRACE
9 | web: INFO
10 | boot:
11 | autoconfigure:
12 | logging: DEBUG
13 | #控制台打印httl模板引擎日志信息
14 | httl: INFO
15 | spring:
16 | http:
17 | encoding:
18 | force: true
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-boot-starter-service/src/main/resources/defaultExceptions/exception_zh_CN.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 默认异常异常消息
5 | 结果集空错误
6 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-cloud-starter-bus/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | org.rxjava
5 | rxjava-spring
6 | 1.0.9-SNAPSHOT
7 |
8 | 4.0.0
9 | rxjava-spring-cloud-starter-bus
10 | jar
11 |
12 |
13 | org.springframework.cloud
14 | spring-cloud-starter-bus-amqp
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-cloud-starter-bus/src/main/java/org/rxjava/common/bus/BusEvent.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.bus;
2 |
3 | import com.fasterxml.jackson.databind.JsonNode;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | /**
10 | * @author happy 2019-06-04 10:26
11 | */
12 | @Data
13 | @Builder
14 | @NoArgsConstructor
15 | @AllArgsConstructor
16 | public class BusEvent {
17 | /**
18 | * 事件唯一Id,保证幂等
19 | */
20 | private String id;
21 | /**
22 | * 事件类型
23 | */
24 | private BusEventType type;
25 | /**
26 | * 时间戳
27 | */
28 | private long timestamp;
29 | /**
30 | * 微服务
31 | */
32 | private String service;
33 | /**
34 | * 数据
35 | */
36 | private JsonNode data;
37 | }
38 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-cloud-starter-bus/src/main/java/org/rxjava/common/bus/BusEventType.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.bus;
2 |
3 | /**
4 | * @author happy 2019-06-04 10:24
5 | * 总线消息类型
6 | */
7 | public enum BusEventType {
8 | //应用服务总线消息
9 | /**
10 | * 应用订单取消成功
11 | */
12 | APP_ORDER_CANCEL_SUCCESS,
13 | /**
14 | * 应用订单待发货
15 | */
16 | APP_ORDER_WAIT_DELIVER,
17 | /**
18 | * 应用订单发货成功
19 | */
20 | APP_ORDER_SHIP_SUCCESS,
21 |
22 | //订单服务总线消息类型
23 | /**
24 | * 支付成功
25 | */
26 | PAY_SUCCESS,
27 | /**
28 | * 订单取消开始
29 | */
30 | ORDER_CANCEL_START,
31 |
32 | //会员卡服务总线消息类型
33 |
34 | //商品服务总线消息类型
35 |
36 | }
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-cloud-starter-bus/src/main/java/org/rxjava/common/bus/BusReceiver.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.bus;
2 |
3 | /**
4 | * @author happy 2019-06-04 10:30
5 | * 接收者
6 | */
7 | public interface BusReceiver {
8 | void receiveMessage(BusEvent busEvent);
9 | }
10 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-cloud-starter-bus/src/main/java/org/rxjava/common/bus/EnableBus.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.bus;
2 |
3 | import org.springframework.context.annotation.Import;
4 |
5 | import java.lang.annotation.*;
6 |
7 | /**
8 | * @author happy 2019-06-04 10:22
9 | * 开启Bus
10 | */
11 | @Target({ElementType.TYPE})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | @Documented
14 | @Import({RxBusConfiguration.class})
15 | public @interface EnableBus {
16 | }
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-cloud-starter-bus/src/main/java/org/rxjava/common/bus/MessageReceiver.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.bus;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import com.fasterxml.jackson.databind.exc.InvalidFormatException;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 |
9 | import java.io.IOException;
10 |
11 | public class MessageReceiver {
12 | private static final Logger log = LogManager.getLogger();
13 |
14 | @Autowired
15 | private ObjectMapper objectMapper;
16 | @Autowired
17 | private BusReceiver busReceiver;
18 |
19 | public void receiveMessage(String json) throws IOException {
20 | try {
21 | BusEvent busEvent = objectMapper.readValue(json, BusEvent.class);
22 | busReceiver.receiveMessage(busEvent);
23 | } catch (InvalidFormatException e) {
24 | log.info("忽略非json消息:{},Exception:{e}", json, e);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-cloud-starter-bus/src/main/java/org/rxjava/common/bus/RxBusConfiguration.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.common.bus;
2 |
3 | import org.springframework.amqp.core.Binding;
4 | import org.springframework.amqp.core.BindingBuilder;
5 | import org.springframework.amqp.core.FanoutExchange;
6 | import org.springframework.amqp.core.Queue;
7 | import org.springframework.amqp.rabbit.connection.ConnectionFactory;
8 | import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
9 | import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
10 | import org.springframework.beans.factory.annotation.Qualifier;
11 | import org.springframework.beans.factory.annotation.Value;
12 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
13 | import org.springframework.context.annotation.Bean;
14 | import org.springframework.context.annotation.Configuration;
15 |
16 | import java.util.HashMap;
17 | import java.util.Map;
18 |
19 | /**
20 | * @author happy 2019-05-02 14:32
21 | * 消息总线配置
22 | */
23 | @Configuration
24 | public class RxBusConfiguration {
25 | /**
26 | * fanout交换机名称
27 | */
28 | static final String FANOUT_EXCHANGE = "rxjava-fanout-exchange";
29 | /**
30 | * 队列名前缀
31 | */
32 | private static final String QUEUE_NAME_PREFIX = "rxjava-queue.";
33 | /**
34 | * delay队列名前缀
35 | */
36 | static final String QUEUE_NAME_DELAY_PREFIX = "rxjava-delay-queue.";
37 | /**
38 | * 应用名
39 | */
40 | @Value("${spring.application.name}")
41 | String applicationName;
42 |
43 | /**
44 | * fanout交换机
45 | */
46 | @Bean
47 | @Qualifier("fanoutExchange")
48 | public FanoutExchange fanoutExchange() {
49 | return new FanoutExchange(FANOUT_EXCHANGE);
50 | }
51 |
52 | /**
53 | * 队列
54 | */
55 | @Bean
56 | @ConditionalOnBean(BusReceiver.class)
57 | @Qualifier("queue")
58 | public Queue queue() {
59 | return new Queue(QUEUE_NAME_PREFIX + applicationName, true);
60 | }
61 |
62 | /**
63 | * delay队列
64 | */
65 | @Bean
66 | @ConditionalOnBean(BusReceiver.class)
67 | @Qualifier("delayQueue")
68 | public Queue delayQueue() {
69 | Map args = new HashMap<>();
70 | args.put("x-dead-letter-exchange", FANOUT_EXCHANGE);
71 | args.put("x-dead-letter-router-key", QUEUE_NAME_PREFIX + "#");
72 | return new Queue(QUEUE_NAME_DELAY_PREFIX + applicationName, true, false, false, args);
73 | }
74 |
75 | /**
76 | * 绑定交换机和队列
77 | */
78 | @Bean
79 | @ConditionalOnBean(BusReceiver.class)
80 | @Qualifier("fanoutBinding")
81 | public Binding fanoutBinding(
82 | @Qualifier("fanoutExchange") FanoutExchange fanoutExchange,
83 | @Qualifier("queue") Queue queue
84 | ) {
85 | return BindingBuilder.bind(queue).to(fanoutExchange);
86 | }
87 |
88 | /**
89 | * 消息发射bean
90 | */
91 | @Bean
92 | public BusEmitter busEmitter() {
93 | return new BusEmitter();
94 | }
95 |
96 | /**
97 | * 消息接收bean
98 | */
99 | @Bean
100 | @ConditionalOnBean(BusReceiver.class)
101 | @Qualifier("messageReceiver")
102 | public MessageReceiver messageReceiver() {
103 | return new MessageReceiver();
104 | }
105 |
106 | /**
107 | * 消息监听适配器
108 | */
109 | @Bean
110 | @ConditionalOnBean(BusReceiver.class)
111 | @Qualifier("messageListenerAdapter")
112 | public MessageListenerAdapter messageListenerAdapter(@Qualifier("messageReceiver") MessageReceiver messageReceiver) {
113 | return new MessageListenerAdapter(messageReceiver, "receiveMessage");
114 | }
115 |
116 | /**
117 | * 消息监听容器
118 | */
119 | @Bean
120 | @ConditionalOnBean(BusReceiver.class)
121 | public SimpleMessageListenerContainer busContainer(
122 | ConnectionFactory connectionFactory,
123 | @Qualifier("messageListenerAdapter") MessageListenerAdapter messageListenerAdapter
124 | ) {
125 | SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
126 | container.setConnectionFactory(connectionFactory);
127 | container.setQueueNames(QUEUE_NAME_PREFIX + applicationName);
128 | container.setMessageListener(messageListenerAdapter);
129 | return container;
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-cloud-starter-gateway/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | org.rxjava
5 | rxjava-spring
6 | 1.0.9-SNAPSHOT
7 |
8 | 4.0.0
9 | rxjava-spring-cloud-starter-gateway
10 | jar
11 |
12 |
13 | org.springframework.cloud
14 | spring-cloud-starter-gateway
15 |
16 |
17 | org.rxjava
18 | rxjava-spring-boot-core
19 | ${project.parent.version}
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-security
24 |
25 |
26 | org.rxjava
27 | rxjava-spring-boot-starter-service
28 | ${project.parent.version}
29 |
30 |
31 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-cloud-starter-gateway/src/main/java/org/rxjava/gateway/starter/RxJavaGatewayAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.gateway.starter;
2 |
3 | import org.rxjava.gateway.starter.config.RxJavaWebFluxSecurityConfig;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.context.annotation.Import;
6 |
7 | /**
8 | * @author happy 2019-06-28 14:32
9 | */
10 | @Configuration
11 | @Import({RxJavaWebFluxSecurityConfig.class})
12 | public class RxJavaGatewayAutoConfiguration {
13 | }
14 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-cloud-starter-gateway/src/main/java/org/rxjava/gateway/starter/config/AuthenticationToken.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.gateway.starter.config;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import org.rxjava.common.core.entity.LoginInfo;
6 | import org.springframework.security.authentication.AbstractAuthenticationToken;
7 |
8 | /**
9 | * @author happy 2019-06-29 03:31
10 | * 授权token
11 | */
12 | @Getter
13 | @Setter
14 | public class AuthenticationToken extends AbstractAuthenticationToken {
15 | private String token;
16 | private LoginInfo loginInfo;
17 |
18 | public AuthenticationToken(String token) {
19 | super(null);
20 | this.token = token;
21 | }
22 |
23 | public AuthenticationToken(String token, LoginInfo loginInfo) {
24 | super(null);
25 | this.token = token;
26 | this.loginInfo = loginInfo;
27 | setAuthenticated(true);
28 | }
29 |
30 | /**
31 | * 凭证即为token
32 | */
33 | @Override
34 | public Object getCredentials() {
35 | return token;
36 | }
37 |
38 | /**
39 | * LoginInfo
40 | */
41 | @Override
42 | public LoginInfo getPrincipal() {
43 | return this.loginInfo;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-cloud-starter-gateway/src/main/java/org/rxjava/gateway/starter/config/CustomServerAuthenticationFailureHandler.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.gateway.starter.config;
2 |
3 | import org.springframework.security.core.AuthenticationException;
4 | import org.springframework.security.web.server.WebFilterExchange;
5 | import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
6 | import org.springframework.web.server.ServerWebExchange;
7 | import org.springframework.web.server.WebFilterChain;
8 | import reactor.core.publisher.Mono;
9 |
10 | /**
11 | * @author happy 2019-06-29 16:31
12 | */
13 | public class CustomServerAuthenticationFailureHandler implements ServerAuthenticationFailureHandler {
14 |
15 | /**
16 | * 鉴权失败,则不注入loginInfo,由微服务判断是否需要loginInfo
17 | */
18 | @Override
19 | public Mono onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException e) {
20 | ServerWebExchange exchange = webFilterExchange.getExchange();
21 | WebFilterChain chain = webFilterExchange.getChain();
22 | return chain.filter(exchange);
23 | }
24 | }
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-cloud-starter-gateway/src/main/java/org/rxjava/gateway/starter/config/CustomServerAuthenticationSuccessHandler.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.gateway.starter.config;
2 |
3 | import org.apache.commons.lang3.ObjectUtils;
4 | import org.apache.commons.lang3.StringUtils;
5 | import org.rxjava.common.core.entity.LoginInfo;
6 | import org.rxjava.common.core.utils.JsonUtils;
7 | import org.springframework.http.server.reactive.ServerHttpRequest;
8 | import org.springframework.security.core.Authentication;
9 | import org.springframework.security.web.server.WebFilterExchange;
10 | import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
11 | import org.springframework.web.server.ServerWebExchange;
12 | import org.springframework.web.server.WebFilterChain;
13 | import reactor.core.publisher.Mono;
14 |
15 | import java.io.UnsupportedEncodingException;
16 | import java.net.URLEncoder;
17 |
18 | /**
19 | * @author happy 2019-06-29 16:31
20 | */
21 | public class CustomServerAuthenticationSuccessHandler implements ServerAuthenticationSuccessHandler {
22 | /**
23 | * 鉴权成功后,将loginInfo注入请求头中
24 | */
25 | @Override
26 | public Mono onAuthenticationSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
27 | ServerWebExchange exchange = webFilterExchange.getExchange();
28 | WebFilterChain chain = webFilterExchange.getChain();
29 |
30 | ServerHttpRequest request = exchange.getRequest();
31 | AuthenticationToken authenticationToken = (AuthenticationToken) authentication;
32 | LoginInfo loginInfo = authenticationToken.getLoginInfo();
33 |
34 | if (ObjectUtils.isEmpty(loginInfo)) {
35 | return chain.filter(exchange);
36 | }
37 |
38 | String loginInfoJson = null;
39 | try {
40 | loginInfoJson = URLEncoder.encode(JsonUtils.serialize(loginInfo), "utf8");
41 | } catch (UnsupportedEncodingException e) {
42 | e.printStackTrace();
43 | }
44 |
45 | if (StringUtils.isEmpty(loginInfoJson)) {
46 | return chain.filter(exchange);
47 | }
48 |
49 | ServerHttpRequest host = request
50 | .mutate()
51 | .header("loginInfo", loginInfoJson)
52 | .build();
53 | ServerWebExchange build = exchange
54 | .mutate()
55 | .request(host)
56 | .build();
57 |
58 | return chain.filter(build);
59 | }
60 | }
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-cloud-starter-gateway/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.rxjava.gateway.starter.RxJavaGatewayAutoConfiguration
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-mock-starter/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | org.rxjava
5 | rxjava-spring
6 | 1.0.9-SNAPSHOT
7 |
8 | 4.0.0
9 | rxjava-spring-mock-starter
10 | jar
11 |
12 |
13 | org.rxjava
14 | rxjava-spring-boot-core
15 | ${project.parent.version}
16 |
17 |
18 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-mock-starter/src/main/java/org/rxjava/mock/starter/RxJavaMockAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.mock.starter;
2 |
3 | import org.rxjava.common.core.entity.LoginInfo;
4 | import org.rxjava.common.core.utils.JsonUtils;
5 | import org.rxjava.mock.starter.config.MockProperties;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.core.annotation.Order;
10 | import org.springframework.http.server.reactive.ServerHttpRequest;
11 | import org.springframework.web.server.ServerWebExchange;
12 | import org.springframework.web.server.WebFilter;
13 | import org.springframework.web.server.WebFilterChain;
14 | import reactor.core.publisher.Mono;
15 |
16 | import java.io.UnsupportedEncodingException;
17 | import java.net.URLEncoder;
18 | import java.util.Objects;
19 |
20 | /**
21 | * @author happy 2019-07-03 11:37
22 | * Mock自动配置信息,此过滤器注入用户登陆信息
23 | */
24 | @Configuration
25 | @EnableConfigurationProperties({MockProperties.class})
26 | @Order(1)
27 | public class RxJavaMockAutoConfiguration implements WebFilter {
28 |
29 | private static final String LOGIN_INFO = "loginInfo";
30 |
31 | @Autowired
32 | private MockProperties mockProperties;
33 |
34 | @Override
35 | public Mono filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
36 | LoginInfo loginInfo = new LoginInfo();
37 | loginInfo.setUserId(mockProperties.getUserId());
38 |
39 | String loginInfoJson = null;
40 | try {
41 | loginInfoJson = URLEncoder.encode(JsonUtils.serialize(loginInfo), "utf8");
42 | } catch (UnsupportedEncodingException e) {
43 | e.printStackTrace();
44 | }
45 |
46 | ServerHttpRequest request = serverWebExchange.getRequest();
47 | ServerHttpRequest host = request
48 | .mutate()
49 | .header(LOGIN_INFO, Objects.requireNonNull(loginInfoJson))
50 | .build();
51 | ServerWebExchange build = serverWebExchange
52 | .mutate()
53 | .request(host)
54 | .build();
55 |
56 | return webFilterChain.filter(build);
57 | }
58 | }
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-mock-starter/src/main/java/org/rxjava/mock/starter/config/MockProperties.java:
--------------------------------------------------------------------------------
1 | package org.rxjava.mock.starter.config;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import org.springframework.boot.context.properties.ConfigurationProperties;
6 |
7 | @ConfigurationProperties(
8 | prefix = "mock"
9 | )
10 | @Getter
11 | @Setter
12 | public class MockProperties {
13 | private String userId;
14 | }
15 |
--------------------------------------------------------------------------------
/rxjava-spring/rxjava-spring-mock-starter/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.rxjava.mock.starter.RxJavaMockAutoConfiguration
--------------------------------------------------------------------------------