├── .gitignore
├── README.md
├── common
├── pom.xml
└── src
│ └── main
│ └── java
│ └── top
│ └── ylonline
│ └── common
│ ├── cache
│ ├── annotation
│ │ └── Expired.java
│ ├── interceptor
│ │ ├── TCacheErrorHandler.java
│ │ ├── TCacheResolver.java
│ │ └── TKeyGenerator.java
│ └── util
│ │ └── CacheUtils.java
│ └── util
│ └── StrUtils.java
├── dom4j-example
├── README.md
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── top
│ │ └── ylonline
│ │ └── dom4j
│ │ ├── Dom4jUtils.java
│ │ └── XMLParserConfiguration.java
│ └── test
│ ├── java
│ └── top
│ │ └── ylonline
│ │ └── dom4j
│ │ ├── CrmTest.java
│ │ ├── CspTest.java
│ │ └── TestCase.java
│ └── resources
│ ├── crm.receive.cdata.txt
│ ├── crm.receive.txt
│ ├── crm.send.cdata.txt
│ ├── crm.send.txt
│ ├── csp.receive.cdata.txt
│ ├── csp.receive.txt
│ ├── csp.send.cdata.txt
│ └── csp.send.txt
├── dubbo-examples
├── dubbo-sca
│ ├── dubbo-sca-api
│ │ ├── pom.xml
│ │ └── src
│ │ │ └── main
│ │ │ └── java
│ │ │ └── top
│ │ │ └── ylonline
│ │ │ └── dubbo
│ │ │ └── sca
│ │ │ └── api
│ │ │ ├── DubboService.java
│ │ │ ├── EchoService.java
│ │ │ └── RestService.java
│ ├── dubbo-sca-consumer
│ │ ├── pom.xml
│ │ └── src
│ │ │ └── main
│ │ │ ├── java
│ │ │ └── top
│ │ │ │ └── ylonline
│ │ │ │ └── dubbo
│ │ │ │ └── sca
│ │ │ │ └── DubboScaConsumerApp.java
│ │ │ └── resources
│ │ │ ├── application-consul.yml
│ │ │ ├── application-zk.yml
│ │ │ ├── bootstrap.yml
│ │ │ └── logback.xml
│ ├── dubbo-sca-provider
│ │ ├── pom.xml
│ │ └── src
│ │ │ └── main
│ │ │ ├── java
│ │ │ └── top
│ │ │ │ └── ylonline
│ │ │ │ └── dubbo
│ │ │ │ └── sca
│ │ │ │ ├── DubboScaProviderApp.java
│ │ │ │ └── service
│ │ │ │ ├── DubboServiceImpl.java
│ │ │ │ ├── EchoServiceImpl.java
│ │ │ │ └── RestServiceImpl.java
│ │ │ └── resources
│ │ │ ├── application-consul.yml
│ │ │ ├── application-zk.yml
│ │ │ ├── bootstrap.yml
│ │ │ └── logback.xml
│ └── pom.xml
├── dubbo-v2.6.x
│ ├── README.md
│ ├── dubbo-v2.6.x-api
│ │ ├── pom.xml
│ │ └── src
│ │ │ └── main
│ │ │ └── java
│ │ │ └── top
│ │ │ └── ylonline
│ │ │ └── dubbo
│ │ │ └── spring
│ │ │ └── boot
│ │ │ └── api
│ │ │ ├── DubboService.java
│ │ │ ├── MultipleService.java
│ │ │ └── RestService.java
│ ├── dubbo-v2.6.x-consumer
│ │ ├── pom.xml
│ │ ├── pom.xml.nacos
│ │ ├── pom.xml.zk
│ │ └── src
│ │ │ └── main
│ │ │ ├── java
│ │ │ └── top
│ │ │ │ └── ylonline
│ │ │ │ └── dubbo
│ │ │ │ └── spring
│ │ │ │ └── boot
│ │ │ │ ├── DubboConsumer.java
│ │ │ │ └── controller
│ │ │ │ └── DemoController.java
│ │ │ └── resources
│ │ │ ├── application.yml
│ │ │ ├── dubbo-consumer-nacos.xml
│ │ │ ├── dubbo-consumer-zk.xml
│ │ │ └── logback-spring.xml
│ ├── dubbo-v2.6.x-provider
│ │ ├── pom.xml
│ │ ├── pom.xml.nacos
│ │ ├── pom.xml.zk
│ │ └── src
│ │ │ └── main
│ │ │ ├── java
│ │ │ └── top
│ │ │ │ └── ylonline
│ │ │ │ └── dubbo
│ │ │ │ └── spring
│ │ │ │ └── boot
│ │ │ │ ├── DubboProvider.java
│ │ │ │ └── service
│ │ │ │ ├── DubboServiceImpl.java
│ │ │ │ ├── MultipleServiceImpl.java
│ │ │ │ └── RestServiceImpl.java
│ │ │ └── resources
│ │ │ ├── application-nacos.yml
│ │ │ ├── application-zk.yml
│ │ │ ├── application.yml
│ │ │ └── logback-spring.xml
│ └── pom.xml
├── dubbo-v2.7.x
│ ├── README-v2.7.0.md
│ ├── README.md
│ ├── dubbo-v2.7.x-api
│ │ ├── pom.xml
│ │ └── src
│ │ │ └── main
│ │ │ └── java
│ │ │ └── top
│ │ │ └── ylonline
│ │ │ └── dubbo27x
│ │ │ └── api
│ │ │ ├── DubboService.java
│ │ │ ├── MultipleService.java
│ │ │ └── RestService.java
│ ├── dubbo-v2.7.x-consumer
│ │ ├── pom.xml
│ │ └── src
│ │ │ └── main
│ │ │ ├── java
│ │ │ └── top
│ │ │ │ └── ylonline
│ │ │ │ └── dubbo27x
│ │ │ │ ├── DubboConsumer270.java
│ │ │ │ └── controller
│ │ │ │ └── DemoController.java
│ │ │ └── resources
│ │ │ ├── application-zk.yml
│ │ │ ├── application.yml
│ │ │ ├── dubbo-consumer-zk.xml
│ │ │ └── logback-spring.xml
│ ├── dubbo-v2.7.x-provider
│ │ ├── pom.xml
│ │ └── src
│ │ │ └── main
│ │ │ ├── java
│ │ │ └── top
│ │ │ │ └── ylonline
│ │ │ │ └── dubbo27x
│ │ │ │ ├── DubboProvider270.java
│ │ │ │ └── service
│ │ │ │ ├── DubboServiceImpl.java
│ │ │ │ ├── MultipleServiceImpl.java
│ │ │ │ └── RestServiceImpl.java
│ │ │ └── resources
│ │ │ ├── application-nacos.yml
│ │ │ ├── application-zk.yml
│ │ │ ├── application.yml
│ │ │ └── logback-spring.xml
│ ├── pom.xml
│ └── 元数据中心配置.md
└── pom.xml
├── encrypt-examples
├── frontend-backend-encrypt-with-rsa
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── top
│ │ │ │ └── ylonline
│ │ │ │ └── encrypt
│ │ │ │ ├── FrontendBackendEncryptWithRsaApp.java
│ │ │ │ ├── common
│ │ │ │ └── Const.java
│ │ │ │ ├── controller
│ │ │ │ └── DemoController.java
│ │ │ │ └── util
│ │ │ │ ├── AesUtils.java
│ │ │ │ ├── EncryptException.java
│ │ │ │ └── RsaUtils.java
│ │ └── resources
│ │ │ ├── application.yml
│ │ │ ├── logback.xml
│ │ │ ├── static
│ │ │ ├── crypto-js
│ │ │ │ ├── aes.js
│ │ │ │ ├── cipher-core.js
│ │ │ │ ├── core.js
│ │ │ │ ├── enc-base64.js
│ │ │ │ ├── enc-utf16.js
│ │ │ │ ├── evpkdf.js
│ │ │ │ ├── format-hex.js
│ │ │ │ ├── hmac.js
│ │ │ │ ├── lib-typedarrays.js
│ │ │ │ ├── md5.js
│ │ │ │ ├── mode-cfb.js
│ │ │ │ ├── mode-ctr-gladman.js
│ │ │ │ ├── mode-ctr.js
│ │ │ │ ├── mode-ecb.js
│ │ │ │ ├── mode-ofb.js
│ │ │ │ ├── pad-ansix923.js
│ │ │ │ ├── pad-iso10126.js
│ │ │ │ ├── pad-iso97971.js
│ │ │ │ ├── pad-nopadding.js
│ │ │ │ ├── pad-zeropadding.js
│ │ │ │ ├── pbkdf2.js
│ │ │ │ ├── rabbit-legacy.js
│ │ │ │ ├── rabbit.js
│ │ │ │ ├── rc4.js
│ │ │ │ ├── ripemd160.js
│ │ │ │ ├── sha1.js
│ │ │ │ ├── sha224.js
│ │ │ │ ├── sha256.js
│ │ │ │ ├── sha3.js
│ │ │ │ ├── sha384.js
│ │ │ │ ├── sha512.js
│ │ │ │ ├── tripledes.js
│ │ │ │ └── x64-core.js
│ │ │ ├── rsa.js
│ │ │ └── rsa.min.js
│ │ │ └── templates
│ │ │ ├── aes.html
│ │ │ ├── error
│ │ │ ├── 404.html
│ │ │ └── 500.html
│ │ │ ├── rsa-and-aes.html
│ │ │ └── rsa.html
│ │ └── test
│ │ └── java
│ │ └── top
│ │ └── ylonline
│ │ └── encrypt
│ │ ├── AppTest.java
│ │ └── util
│ │ ├── AesUtilsTest.java
│ │ └── RsaUtilsTest.java
└── pom.xml
├── feign-examples
├── openfeign
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── top
│ │ │ │ └── ylonline
│ │ │ │ └── feign
│ │ │ │ ├── OpenFeignApp.java
│ │ │ │ └── client
│ │ │ │ ├── CspClient.java
│ │ │ │ ├── Github.java
│ │ │ │ └── GithubClient.java
│ │ └── resources
│ │ │ ├── application.yml
│ │ │ └── logback-spring.xml
│ │ └── test
│ │ └── java
│ │ └── top
│ │ └── ylonline
│ │ └── feign
│ │ └── client
│ │ ├── CspClientTest.java
│ │ ├── GithubClientTest.java
│ │ └── GithubTest.java
└── pom.xml
├── flow-examples
├── pom.xml
└── src
│ └── main
│ └── java
│ └── top
│ └── ylonline
│ └── App.java
├── gateway-examples
├── gateway-nacos
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── top
│ │ │ └── ylonline
│ │ │ └── nacos
│ │ │ └── spring
│ │ │ └── cloud
│ │ │ └── gateway
│ │ │ └── example
│ │ │ └── NacosGatewayApp.java
│ │ └── resources
│ │ ├── application.yml
│ │ ├── bootstrap.yml
│ │ └── logback-spring.xml
├── gateway-simple
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── top
│ │ │ └── ylonline
│ │ │ └── spring
│ │ │ └── cloud
│ │ │ └── gateway
│ │ │ └── example
│ │ │ └── GatewayApp.java
│ │ └── resources
│ │ ├── application-dev.yml
│ │ ├── application-local.yml
│ │ ├── application-pro.yml
│ │ ├── application.yml
│ │ └── logback-spring.xml
└── pom.xml
├── nacos-examples
├── nacos-spring-boot-example
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── top
│ │ │ └── ylonline
│ │ │ └── nacos
│ │ │ └── spring
│ │ │ └── boot
│ │ │ └── example
│ │ │ └── NacosBootApp.java
│ │ └── resources
│ │ ├── application-dev.yml
│ │ ├── application-local.yml
│ │ ├── application-pro.yml
│ │ ├── application.yml
│ │ └── logback-spring.xml
├── nacos-spring-cloud-example
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── top
│ │ │ └── ylonline
│ │ │ └── nacos
│ │ │ └── spring
│ │ │ └── cloud
│ │ │ └── example
│ │ │ ├── NacosCloudApp.java
│ │ │ └── controller
│ │ │ └── DemoController.java
│ │ └── resources
│ │ ├── application-nacos.yml
│ │ ├── application.yml
│ │ ├── bootstrap.properties
│ │ └── logback-spring.xml
└── pom.xml
├── pom.xml
├── sb-examples
├── events-and-listeners
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── top
│ │ │ └── ylonline
│ │ │ └── sb
│ │ │ └── el
│ │ │ ├── EventsAndListenersApp.java
│ │ │ ├── config
│ │ │ ├── EventListenerConfig.java
│ │ │ └── MyAsyncConfigurer.java
│ │ │ ├── domain
│ │ │ └── User.java
│ │ │ ├── event
│ │ │ └── UserEvent.java
│ │ │ └── listener
│ │ │ └── UserEventListener.java
│ │ └── resources
│ │ ├── application.yml
│ │ └── logback.xml
├── pom.xml
├── redis-v1
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── top
│ │ │ └── ylonline
│ │ │ └── sb
│ │ │ └── redis
│ │ │ └── v1
│ │ │ ├── TRedisAutoConfiguration.java
│ │ │ └── cache
│ │ │ └── TRedisCacheManager.java
│ │ └── test
│ │ ├── java
│ │ └── top
│ │ │ └── ylonline
│ │ │ └── sb
│ │ │ └── redis
│ │ │ └── v1
│ │ │ └── test
│ │ │ ├── RedisV1App.java
│ │ │ ├── RedisV1AppTest.java
│ │ │ ├── domain
│ │ │ └── User.java
│ │ │ └── service
│ │ │ └── UserService.java
│ │ └── resources
│ │ ├── META-INF
│ │ └── spring.factories
│ │ ├── application.yml
│ │ └── logback.xml
├── redis-v2.0
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── top
│ │ │ └── ylonline
│ │ │ └── sb
│ │ │ └── redis
│ │ │ └── v2
│ │ │ ├── TRedisAutoConfiguration.java
│ │ │ └── cache
│ │ │ └── TRedisCacheManager.java
│ │ └── test
│ │ ├── java
│ │ └── top
│ │ │ └── ylonline
│ │ │ └── sb
│ │ │ └── redis
│ │ │ └── v2
│ │ │ └── test
│ │ │ ├── RedisV2App.java
│ │ │ ├── RedisV2AppTest.java
│ │ │ ├── domain
│ │ │ └── User.java
│ │ │ └── service
│ │ │ └── UserService.java
│ │ └── resources
│ │ ├── META-INF
│ │ └── spring.factories
│ │ ├── application.yml
│ │ └── logback.xml
└── webflux
│ ├── README.md
│ ├── pom.xml
│ └── src
│ └── main
│ ├── java
│ └── top
│ │ └── ylonline
│ │ └── sb
│ │ └── webflux
│ │ ├── WebFluxApp.java
│ │ ├── config
│ │ └── JpaReactiveConfig.java
│ │ ├── controller
│ │ └── UserController.java
│ │ ├── entity
│ │ └── User.java
│ │ ├── repository
│ │ └── UserRepository.java
│ │ └── service
│ │ ├── UserService.java
│ │ └── UserServiceImpl.java
│ └── resources
│ ├── application.yml
│ ├── data-h2.sql
│ └── schema-h2.sql
├── sc-examples
├── pom.xml
└── sleuth
│ ├── pom.xml
│ └── src
│ └── main
│ ├── java
│ └── top
│ │ └── ylonline
│ │ └── sc
│ │ └── sleuth
│ │ ├── SleuthApp.java
│ │ ├── config
│ │ └── JpaReactiveConfig.java
│ │ ├── entity
│ │ └── User.java
│ │ ├── repository
│ │ └── UserRepository.java
│ │ └── service
│ │ ├── UserService.java
│ │ └── UserServiceImpl.java
│ └── resources
│ ├── application.yml
│ ├── bootstrap.yml
│ ├── data-h2.sql
│ └── schema-h2.sql
└── sentinel-examples
├── pom.xml
├── sentinel-cluster-example
├── README.md
├── pom.xml
├── sentinel-cluster-client
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── top
│ │ │ └── ylonline
│ │ │ └── sentinel
│ │ │ ├── SentinelClusterClientApp.java
│ │ │ └── init
│ │ │ └── NacosDatasourceInitFunc.java
│ │ └── resources
│ │ ├── META-INF
│ │ └── services
│ │ │ └── com.alibaba.csp.sentinel.init.InitFunc
│ │ ├── application.yml
│ │ ├── bootstrap.yml
│ │ └── logback-spring.xml
└── sentinel-cluster-server-alone
│ ├── pom.xml
│ └── src
│ └── main
│ ├── java
│ └── top
│ │ └── ylonline
│ │ └── sentinel
│ │ ├── SentinelClusterServerApp.java
│ │ └── init
│ │ └── NacosDatasourceInitFunc.java
│ └── resources
│ ├── META-INF
│ └── services
│ │ └── com.alibaba.csp.sentinel.init.InitFunc
│ ├── application.yml
│ ├── bootstrap.yml
│ └── logback-spring.xml
└── sentinel-spring-cloud-example
├── README.md
├── pom.xml
└── src
└── main
├── java
└── top
│ └── ylonline
│ └── sentinel
│ └── spring
│ └── cloud
│ └── example
│ └── SentinelApp.java
└── resources
├── application.yml
└── logback-spring.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | # maven ignore
2 | dependency-reduced-pom.xml
3 | .flattened-pom.xml
4 |
5 | target/
6 | !.mvn/wrapper/*
7 | *.zip
8 | *.tar
9 | *.tar.gz
10 |
11 | # eclipse ignore
12 | .settings/
13 | .project
14 | .classpath
15 |
16 | # idea ignore
17 | .idea/
18 | *.ipr
19 | *.iml
20 | *.iws
21 |
22 | # temp ignore
23 | *.log
24 | *.cache
25 | *.diff
26 | *.patch
27 | *.tmp
28 |
29 | # system ignore
30 | .DS_Store
31 | Thumbs.db
32 | *.orig
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # java-best-practice
2 |
3 | Java 的一些学习例子,最佳实践
4 |
5 | ## Examples
6 |
7 | > dubbo
8 | - [dubbo-v2.6.x](dubbo-examples/dubbo-v2.6.x) Dubbo-2.6.5 + Spring Boot:zk + nacos 注册中心
9 | - [dubbo-v2.7.x](dubbo-examples/dubbo-v2.7.x) Dubbo-2.7.0 + Spring Boot
10 | - [dubbo-sca](dubbo-examples/dubbo-sca) Dubbo-2.7.6 + Spring Boot.2.0.x + Spring Cloud.F
11 |
12 |
13 | > nacos
14 | - [nacos-spring-boot-example](nacos-examples/nacos-spring-boot-example) Nacos + Spring Boot 简单入门
15 | - [nacos-spring-cloud-example](nacos-examples/nacos-spring-cloud-example) Nacos + Spring Cloud 简单入门
16 |
17 |
18 | > sentinel
19 | - [sentinel-spring-cloud-example](sentinel-examples/sentinel-spring-cloud-example) sentinel 简单入门
20 | - [sentinel-cluster-example](sentinel-examples/sentinel-cluster-example) Sentinel 配置动态规则数据源(集群模式):Nacos 配置中心(zk、apollo同理)
21 |
22 |
23 | > spring-cloud-gateway
24 | - [gateway-simple](gateway-examples/gateway-simple) gateway 简单入门
25 | - [gateway-nacos](gateway-examples/gateway-nacos) gateway 实现动态路由规则:Nacos 配置中心
26 |
27 |
28 | > feign-examples
29 | - [openfeign](feign-examples/openfeign) openfeign 简单使用
30 |
31 |
32 | > dom4j
33 | - [dom4j-example](dom4j-example) dom4j 解析任意 xml 报文
34 |
35 |
36 | > 加解密
37 | - [frontend-backend-encrypt-with-rsa](encrypt-examples/frontend-backend-encrypt-with-rsa) 前后端分离数据加密传输
38 |
39 |
40 | > Spring Boot
41 | - [events-and-listeners](sb-examples/events-and-listeners) Spring 事件发布和监听
42 | - [webflux](sb-examples/webflux) webflux 简单入门,提供堵塞、响应式对比
43 |
44 |
45 | > Cache
46 |
47 | 自定义 Expired 注解,实现缓存的过期时间配置,并支持 SpEL 表达式配置动态过期时间
48 | - redis
49 | - [redis-v1](sb-examples/redis-v1)
50 | - [redis-v2.0](sb-examples/redis-v2.0)
51 |
52 | - memcached
53 | - [xmemcached-spring-boot-starter](https://github.com/foreveryang321/xmemcached-spring-boot-starter) Spring Boot Starter for XMemcached
54 |
--------------------------------------------------------------------------------
/common/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 | top.ylonline
7 | java-best-practice
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | common
13 |
14 | common
15 |
16 | http://www.example.com
17 |
18 |
19 | UTF-8
20 | 1.8
21 | 1.8
22 |
23 |
24 |
25 |
26 | org.springframework
27 | spring-core
28 | 4.3.22.RELEASE
29 | provided
30 | true
31 |
32 |
33 | org.springframework
34 | spring-context-support
35 | 4.3.22.RELEASE
36 | provided
37 | true
38 |
39 |
40 | org.slf4j
41 | slf4j-api
42 | 1.7.15
43 | provided
44 | true
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/common/src/main/java/top/ylonline/common/cache/annotation/Expired.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.common.cache.annotation;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Inherited;
6 | import java.lang.annotation.Retention;
7 | import java.lang.annotation.RetentionPolicy;
8 | import java.lang.annotation.Target;
9 |
10 | /**
11 | * 自定义缓存过期时间配置注解,过期时间单位:s(秒)
12 | *
13 | * 1、{@link Expired#el()}优先级比{@link Expired#value()}高,优先使用{@link Expired#el()}的配置
14 | *
15 | *
16 | * @author YL
17 | */
18 | @Target({ElementType.METHOD, ElementType.TYPE})
19 | @Retention(RetentionPolicy.RUNTIME)
20 | @Inherited
21 | @Documented
22 | public @interface Expired {
23 | /**
24 | * 过期时间,单位:秒,默认:-1(使用全局默认过期时间)
25 | *
26 | * 与 {@link #el()} 属性互斥,优先使用 {@link #el()} 配置。
27 | *
28 | */
29 | long value() default -1;
30 |
31 | /**
32 | * 过期时间,单位:秒
33 | * Spring Expression Language (SpEL) expression for computing the expiration time dynamically.
34 | *
35 | * 与 {@link #value()} 属性互斥,优先使用当前配置。
36 | *
37 | */
38 | String el() default "";
39 | }
40 |
--------------------------------------------------------------------------------
/common/src/main/java/top/ylonline/common/cache/interceptor/TCacheErrorHandler.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.common.cache.interceptor;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.cache.Cache;
5 | import org.springframework.cache.interceptor.CacheErrorHandler;
6 |
7 | /**
8 | * 自定义缓存异常处理程序
9 | *
10 | * 解决的问题:
11 | * Redis 容易出现缓存问题(超时、Redis 宕机等),当使用 spring cache 的注释 Cacheable、Cacheput 等处理缓存问题时,
12 | * 我们无法使用 try catch 处理出现的异常,所以最后导致结果是整个服务报错无法正常工作。
13 | * 通过自定义 {@link TCacheErrorHandler} 来处理异常可以解决这个问题。
14 | *
15 | *
16 | * 缓存仅仅是为了业务更快地查询而存在的,如果因为缓存操作失败导致正常的业务流程失败,有点得不偿失了。
17 | * 因此需要开发者自定义 CacheErrorHandler 处理缓存读写的异常。
18 | *
19 | *
20 | *
21 | * 如果缓存写发生了异常,就可能导致数据库的数据和缓存的数据不一致的问题。
22 | * 为了解决该问题,需要继续扩展 CacheErrorHandler 的 handleCachePutError 和 handleCacheEvictError 方法。
23 | * 思路就是将缓存写操作失败的 key 保存下来,通过重试任务删除这些 key 对应的缓存解决数据库数据与缓存数据不一致的问题。
24 | *
25 | *
26 | * @author YL
27 | */
28 | @Slf4j
29 | public class TCacheErrorHandler implements CacheErrorHandler {
30 |
31 | @Override
32 | public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
33 | log.error("key: {}, msg: {}", key, exception.getMessage(), exception);
34 | }
35 |
36 | @Override
37 | public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {
38 | log.error("key: {}, value: {}, msg: {}", key, value, exception.getMessage(), exception);
39 | // 写入失败时,尝试删除缓存,如果 evict 也出现异常,则可能会直接抛给应用,这里需要 try catch 处理一下
40 | try {
41 | cache.evict(key);
42 | } catch (Exception e) {
43 | // ignore
44 | }
45 | }
46 |
47 | @Override
48 | public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
49 | log.error("key: {}, msg: {}", key, exception.getMessage(), exception);
50 | }
51 |
52 | @Override
53 | public void handleCacheClearError(RuntimeException exception, Cache cache) {
54 | throw exception;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/common/src/main/java/top/ylonline/common/cache/interceptor/TKeyGenerator.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.common.cache.interceptor;
2 |
3 | import org.springframework.cache.interceptor.KeyGenerator;
4 | import org.springframework.util.StringUtils;
5 |
6 | import java.lang.reflect.Method;
7 |
8 | /**
9 | * spring-cache 自定义 key 生成规则
10 | *
11 | * @author YL
12 | */
13 | public class TKeyGenerator implements KeyGenerator {
14 |
15 | @Override
16 | public Object generate(Object o, Method method, Object... params) {
17 | StringBuilder sb = new StringBuilder(32);
18 | // 拼接规则:类名.函数名
19 | sb.append(o.getClass().getSimpleName());
20 | sb.append(".");
21 | sb.append(method.getName());
22 | if (params.length == 0) {
23 | return sb.toString();
24 | }
25 | if (params.length == 1) {
26 | Object param = params[0];
27 | if (param != null && !param.getClass().isArray()) {
28 | sb.append(compute(param));
29 | }
30 | return sb.toString();
31 | }
32 | // 参数拼接规则:类名#函数名#p1.p2.p3
33 | Object[] arr = new Object[params.length];
34 | System.arraycopy(params, 0, arr, 0, params.length);
35 | String str = StringUtils.arrayToDelimitedString(arr, ".");
36 | sb.append(compute(str));
37 | return sb.toString();
38 | }
39 |
40 | private String compute(Object str) {
41 | return "#" + str;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/common/src/main/java/top/ylonline/common/cache/util/CacheUtils.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.common.cache.util;
2 |
3 | /**
4 | * 缓存工具
5 | *
6 | * @author YL
7 | */
8 | public final class CacheUtils {
9 | private static final String SYMBOL = "#";
10 |
11 | /**
12 | * 构建一个新的 cacheName,以实现动态过期时间配置
13 | *
14 | * @param cacheName 原始 cacheName
15 | * @param ttl 过期时间
16 | */
17 | public static String buildCacheNameForTtl(String cacheName, long ttl) {
18 | return cacheName + SYMBOL + ttl;
19 | }
20 |
21 | public static String[] splitCacheNameForTtl(String cacheNameForTtl) {
22 | return cacheNameForTtl.split(SYMBOL, -1);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/common/src/main/java/top/ylonline/common/util/StrUtils.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.common.util;
2 |
3 | /**
4 | * @author YL
5 | */
6 | public abstract class StrUtils {
7 |
8 | public static boolean isEmpty(CharSequence cs) {
9 | return cs == null || cs.length() == 0;
10 | }
11 |
12 | public static boolean isNotEmpty(CharSequence cs) {
13 | return !isEmpty(cs);
14 | }
15 |
16 | public static boolean isBlank(CharSequence cs) {
17 | int strLen;
18 | if (cs != null && (strLen = cs.length()) != 0) {
19 | for (int i = 0; i < strLen; ++i) {
20 | if (!Character.isWhitespace(cs.charAt(i))) {
21 | return false;
22 | }
23 | }
24 |
25 | return true;
26 | } else {
27 | return true;
28 | }
29 | }
30 |
31 | public static boolean isNotBlank(CharSequence cs) {
32 | return !isBlank(cs);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/dom4j-example/README.md:
--------------------------------------------------------------------------------
1 | # dom4j
2 | `org.dom4j.2.1.0` 版本以前,使用 `DocumentHelper.parseText`会存在`XXE` 漏洞,代码如下
3 | ```java
4 | public static Document parseText(String text) throws DocumentException {
5 | SAXReader reader = new SAXReader();
6 | String encoding = getEncoding(text);
7 |
8 | InputSource source = new InputSource(new StringReader(text));
9 | source.setEncoding(encoding);
10 |
11 | Document result = reader.read(source);
12 |
13 | // if the XML parser doesn't provide a way to retrieve the encoding,
14 | // specify it manually
15 | if (result.getXMLEncoding() == null) {
16 | result.setXMLEncoding(encoding);
17 | }
18 |
19 | return result;
20 | }
21 | ```
22 | `org.dom4j.2.1.1` 版本以后,使用 `DocumentHelper.parseText`不会存在`XXE` 漏洞,代码如下
23 | ```java
24 | public static Document parseText(String text) throws DocumentException {
25 | SAXReader reader = new SAXReader();
26 | try {
27 | reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
28 | reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
29 | reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
30 | } catch (SAXException e) {
31 | //Parse with external resources downloading allowed.
32 | }
33 |
34 | String encoding = getEncoding(text);
35 |
36 | InputSource source = new InputSource(new StringReader(text));
37 | source.setEncoding(encoding);
38 |
39 | Document result = reader.read(source);
40 |
41 | // if the XML parser doesn't provide a way to retrieve the encoding,
42 | // specify it manually
43 | if (result.getXMLEncoding() == null) {
44 | result.setXMLEncoding(encoding);
45 | }
46 |
47 | return result;
48 | }
49 | ```
--------------------------------------------------------------------------------
/dom4j-example/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | top.ylonline
6 | java-best-practice
7 | 1.0-SNAPSHOT
8 |
9 | 4.0.0
10 |
11 | dom4j-example
12 | Java 最佳实践 :: dom4j
13 |
14 |
15 | UTF-8
16 | 1.8
17 | 1.8
18 |
19 |
20 |
21 |
22 | top.ylonline
23 | common
24 | ${project.parent.version}
25 |
26 |
27 | org.dom4j
28 | dom4j
29 | 2.1.1
30 |
31 |
32 |
33 | com.alibaba
34 | fastjson
35 | 1.2.54
36 | test
37 |
38 |
39 | commons-io
40 | commons-io
41 | 2.5
42 | test
43 |
44 |
45 | org.apache.commons
46 | commons-lang3
47 | 3.8.1
48 | test
49 |
50 |
51 | junit
52 | junit
53 | 4.12
54 | test
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/dom4j-example/src/main/java/top/ylonline/dom4j/XMLParserConfiguration.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dom4j;
2 |
3 | /**
4 | * @author YL
5 | */
6 | public class XMLParserConfiguration {
7 | // private static final String CDATA_TAG_NAME = "text";
8 |
9 | private boolean keepRoot;
10 |
11 | private boolean keepAttributes;
12 |
13 | /**
14 | * Default parser configuration. Does not keep strings, and the CDATA Tag Name is "text".
15 | */
16 | public XMLParserConfiguration() {
17 | this(false, false);
18 | }
19 |
20 | public XMLParserConfiguration(final boolean keepAttributes) {
21 | this(false, keepAttributes);
22 | }
23 |
24 | public XMLParserConfiguration(final boolean keepRoot, final boolean keepAttributes) {
25 | this.keepRoot = keepRoot;
26 | this.keepAttributes = keepAttributes;
27 | }
28 |
29 | public boolean isKeepRoot() {
30 | return keepRoot;
31 | }
32 |
33 | public boolean isKeepAttributes() {
34 | return keepAttributes;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/dom4j-example/src/test/java/top/ylonline/dom4j/CrmTest.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dom4j;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import org.junit.Test;
5 |
6 | /**
7 | * @author YL
8 | */
9 | public class CrmTest extends TestCase {
10 | private static final boolean KEEP_ATTRRIBUTES = false;
11 | private static final String ENCODING = "UTF-8";
12 |
13 | @Test
14 | public void crmReceive() {
15 | parse("crm.receive.txt");
16 | }
17 |
18 | @Test
19 | public void crmReceiveCdata() {
20 | parse("crm.receive.cdata.txt");
21 | }
22 |
23 | @Test
24 | public void crmSend() {
25 | parse("crm.send.txt");
26 | }
27 |
28 | @Test
29 | public void crmSendCdata() {
30 | parse("crm.send.cdata.txt");
31 | }
32 |
33 | private void parse(String fileName) {
34 | XMLParserConfiguration configuration = new XMLParserConfiguration(false, KEEP_ATTRRIBUTES);
35 | String xml = getByFile(fileName, ENCODING);
36 |
37 | // 去掉
38 | xml = xml.replaceAll("(<\\?[^<]*\\?>)?", "");
39 |
40 | String json = JSON.toJSONString(Dom4jUtils.parse(xml, configuration));
41 | System.out.println(fileName + " --->\n<--- " + json);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/dom4j-example/src/test/java/top/ylonline/dom4j/CspTest.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dom4j;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import org.junit.Test;
5 |
6 | /**
7 | * @author YL
8 | */
9 | public class CspTest extends TestCase {
10 | private static final boolean KEEP_ATTRRIBUTES = false;
11 | private static final String ENCODING = "UTF-8";
12 |
13 | @Test
14 | public void cpsReceive() {
15 | parse("csp.receive.txt");
16 | }
17 |
18 | @Test
19 | public void cpsReceiveCdata() {
20 | parse("csp.receive.cdata.txt");
21 | }
22 |
23 | @Test
24 | public void cpsSend() {
25 | parse("csp.send.txt");
26 | }
27 |
28 | @Test
29 | public void cpsSendCdata() {
30 | parse("csp.send.cdata.txt");
31 | }
32 |
33 | private void parse(String fileName) {
34 | XMLParserConfiguration configuration = new XMLParserConfiguration(false, KEEP_ATTRRIBUTES);
35 | String xml = getByFile(fileName, ENCODING);
36 | // if ("csp.receive.txt".equals(fileName)){
37 | // if (StringUtils.isNotBlank(xml)) {
38 | // String ir = "";
40 | // if (xml.contains(ir)) {
41 | // xml = xml.replace(ir, ir + "", "]]>");
43 | // }
44 | // }
45 | // }
46 |
47 | // 去掉
48 | xml = xml.replaceAll("(<\\?[^<]*\\?>)?", "");
49 |
50 | String json = JSON.toJSONString(Dom4jUtils.parse(xml, configuration));
51 | System.out.println(fileName + " --->\n<--- " + json);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/dom4j-example/src/test/java/top/ylonline/dom4j/TestCase.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dom4j;
2 |
3 | import org.apache.commons.io.IOUtils;
4 |
5 | import java.io.File;
6 | import java.io.FileInputStream;
7 | import java.io.IOException;
8 | import java.net.URL;
9 |
10 | /**
11 | * @author YL
12 | */
13 | public class TestCase {
14 | protected String getByFile(String fileName, String encoding) {
15 | ClassLoader classLoader = TestCase.class.getClassLoader();
16 | try {
17 | URL url = classLoader.getResource(fileName);
18 | return IOUtils.toString(new FileInputStream(new File(url.getFile())), encoding);
19 | } catch (IOException e) {
20 | e.printStackTrace();
21 | }
22 | return "";
23 | }
24 |
25 | protected String removeXmlStringNamespaceAndPreamble(String xmlString) {
26 | return xmlString//.replaceAll("(<\\?[^<]*\\?>)?", "") //去掉
27 | .replaceAll("xmlns.*?(\"|\').*?(\"|\')", "") //去掉xmlns:
28 | .replaceAll("(<)(\\w+:)", "$1") //去掉开头标签的冒号前的前缀
29 | .replaceAll("()(\\w+:)(.*?>)", "$1$3"); //去掉结尾标签的冒号前前缀
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/dom4j-example/src/test/resources/crm.receive.cdata.txt:
--------------------------------------------------------------------------------
1 |
2 | 0
3 | OK
4 |
5 |
6 |
7 | 3333333333
8 | 2222222222222222
9 | 姓名
10 | 10
11 | 2716872242
12 | 50
13 | 500101
14 | 02
15 |
16 |
17 |
18 | 0
19 | 0
20 | 0
21 |
22 | 03
23 | 5001
24 | 7777777A9F3AADBD
25 | 1
26 | 1
27 | UNDEF
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/dom4j-example/src/test/resources/crm.send.cdata.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 | admin20171120100304533
4 | admin
5 | admin123
6 | 1
7 | 200
8 | 接口组件名称
9 | 1
10 |
11 |
12 |
13 |
14 |
15 | root
16 | root123
17 | 200
18 |
19 |
20 |
21 |
22 | 2
23 | 18111111111
24 |
25 |
26 |
27 |
28 | 201
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/dom4j-example/src/test/resources/csp.receive.cdata.txt:
--------------------------------------------------------------------------------
1 |
2 | 0
3 | OK
4 |
5 |
6 | 0
7 | OK
8 | 201409移动话费促销包送话费(抵扣套外)_赠金﹏8538810489﹏1
10 |
11 |
14 | 5UI﹏-891﹏20170702013614﹏1544051565/无法找到对应营业厅﹏﹏13333333333﹏8344144030﹏20170601:20170630▕▏5UI﹏-3030﹏20170901213459﹏1544051565/无法找到对应营业厅﹏﹏13333333333﹏8344144030﹏20170801:20170831▕▏5UI﹏-2132﹏20170602025720﹏1544051565/无法找到对应营业厅﹏﹏13333333333﹏8344144030﹏20170501:20170531▕▏5UD﹏30000﹏20170321101415﹏STF_YEZB/余额帐本【接口】﹏IBSS充值(一次出发票,不可退,ib赠送使用)﹏﹏﹏20170301:20170331
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/dom4j-example/src/test/resources/csp.receive.txt:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 | 0
10 | OK
11 |
12 |
13 | 0
14 | OK
15 | 201409移动话费促销包送话费(抵扣套外)_赠金﹏8538810489﹏1
17 |
18 |
21 | 5UI﹏-891﹏20170702013614﹏1544051565/无法找到对应营业厅﹏﹏13333333333﹏8344144030﹏20170601:20170630▕▏5UI﹏-3030﹏20170901213459﹏1544051565/无法找到对应营业厅﹏﹏13333333333﹏8344144030﹏20170801:20170831▕▏5UI﹏-2132﹏20170602025720﹏1544051565/无法找到对应营业厅﹏﹏13333333333﹏8344144030﹏20170501:20170531▕▏5UD﹏30000﹏20170321101415﹏STF_YEZB/余额帐本【接口】﹏IBSS充值(一次出发票,不可退,ib赠送使用)﹏﹏﹏20170301:20170331
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/dom4j-example/src/test/resources/csp.send.cdata.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | admin
5 | admin123
6 | 接口组件名称
7 |
8 |
9 |
10 | 757
11 | 2040817707
12 | 20160923
13 | 20170922
14 |
15 |
16 |
--------------------------------------------------------------------------------
/dom4j-example/src/test/resources/csp.send.txt:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
9 |
10 |
11 | admin
12 | admin123
13 | 接口组件名称
14 |
15 |
16 |
17 | 757
18 | 2040817707
19 | 20160923
20 | 20170922
21 |
22 |
23 |
24 | ]]>
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-api/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | top.ylonline.dubbo
6 | dubbo-sca
7 | 1.0-SNAPSHOT
8 |
9 | 4.0.0
10 |
11 | dubbo-sca-api
12 | Java 最佳实践 :: dubbo(${project.artifactId})
13 |
14 |
15 | UTF-8
16 | 1.8
17 | 1.8
18 |
19 |
20 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-api/src/main/java/top/ylonline/dubbo/sca/api/DubboService.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.sca.api;
2 |
3 | /**
4 | * @author YL
5 | */
6 | public interface DubboService {
7 | /**
8 | * echo
9 | *
10 | * @param message msg
11 | *
12 | * @return 信息
13 | */
14 | String get(String message);
15 | }
16 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-api/src/main/java/top/ylonline/dubbo/sca/api/EchoService.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.sca.api;
2 |
3 | /**
4 | * @author YL
5 | */
6 | public interface EchoService {
7 | /**
8 | * echo
9 | *
10 | * @param message msg
11 | *
12 | * @return 信息
13 | */
14 | String echo(String message);
15 | }
16 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-api/src/main/java/top/ylonline/dubbo/sca/api/RestService.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.sca.api;
2 |
3 | /**
4 | * @author YL
5 | */
6 | public interface RestService {
7 | /**
8 | * 通过 id 获取用户名
9 | *
10 | * @param id 用户id
11 | *
12 | * @return 用户名
13 | */
14 | String getName(long id);
15 | }
16 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-consumer/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | top.ylonline.dubbo
6 | dubbo-sca
7 | 1.0-SNAPSHOT
8 |
9 | 4.0.0
10 |
11 | dubbo-sca-consumer
12 | Java 最佳实践 :: dubbo(${project.artifactId})
13 |
14 |
15 | UTF-8
16 | 1.8
17 | 1.8
18 |
19 |
20 |
21 |
22 | top.ylonline.dubbo
23 | dubbo-sca-api
24 | ${project.parent.version}
25 |
26 |
27 | com.alibaba.cloud
28 | spring-cloud-starter-dubbo
29 |
30 |
31 |
32 |
33 | org.springframework.cloud
34 | spring-cloud-starter-zookeeper-discovery
35 |
36 |
37 | org.springframework.cloud
38 | spring-cloud-starter-netflix-ribbon
39 |
40 |
41 |
42 |
43 |
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-starter-test
51 | test
52 |
53 |
54 |
55 |
56 |
57 |
58 | org.springframework.boot
59 | spring-boot-maven-plugin
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-consumer/src/main/resources/application-consul.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8080
3 | feign:
4 | hystrix:
5 | enabled: true
6 | dubbo:
7 | # scan:
8 | # base-packages: top.ylonline.dubbo.sca.service
9 | registry:
10 | address: spring-cloud://localhost
11 | protocols:
12 | dubbo:
13 | name: dubbo
14 | port: -1
15 | rest:
16 | name: rest
17 | port: 8081
18 | server: netty
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-consumer/src/main/resources/application-zk.yml:
--------------------------------------------------------------------------------
1 | #server:
2 | # port: 0
3 | dubbo:
4 | application:
5 | id: dubbo-sca-consumer
6 | name: dubbo-sca-consumer
7 | qos-enable: false
8 | registry:
9 | address: spring-cloud://localhost
10 | consumer:
11 | check: false
12 | cloud:
13 | subscribed-services: dubbo-sca-provider
14 | #provider:
15 | # application:
16 | # name: dubbo-sca-provider
17 | spring:
18 | cloud:
19 | service-registry:
20 | auto-registration:
21 | # 要禁用这个,否则需要web环境才能启动
22 | enabled: false
23 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-consumer/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: dubbo-sca-consumer
4 | ---
5 | spring:
6 | profiles: zk
7 | cloud:
8 | zookeeper:
9 | enabled: true
10 | connect-string: 192.168.56.101:2181
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-consumer/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 | ${logger.pattern}
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-provider/src/main/java/top/ylonline/dubbo/sca/DubboScaProviderApp.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.sca;
2 |
3 | import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan;
4 | import org.springframework.boot.WebApplicationType;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.boot.builder.SpringApplicationBuilder;
7 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
8 |
9 | /**
10 | * @author YL
11 | */
12 | @SpringBootApplication
13 | @DubboComponentScan(basePackages = "top.ylonline.dubbo.sca")
14 | @EnableDiscoveryClient
15 | public class DubboScaProviderApp {
16 |
17 | public static void main(String[] args) {
18 | new SpringApplicationBuilder(DubboScaProviderApp.class)
19 | .properties("spring.profiles.active=zk")
20 | .web(WebApplicationType.NONE)
21 | .run(args);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-provider/src/main/java/top/ylonline/dubbo/sca/service/DubboServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.sca.service;
2 |
3 | import org.apache.dubbo.config.annotation.Service;
4 | import top.ylonline.dubbo.sca.api.DubboService;
5 |
6 | /**
7 | * @author YL
8 | */
9 | @Service(protocol = "dubbo")
10 | public class DubboServiceImpl implements DubboService {
11 |
12 | @Override
13 | public String get(String message) {
14 | return "Hello " + message;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-provider/src/main/java/top/ylonline/dubbo/sca/service/EchoServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.sca.service;
2 |
3 | import org.apache.dubbo.config.annotation.Service;
4 | import top.ylonline.dubbo.sca.api.EchoService;
5 |
6 | /**
7 | * @author YL
8 | */
9 | @Service(protocol = "dubbo")
10 | public class EchoServiceImpl implements EchoService {
11 |
12 | @Override
13 | public String echo(String message) {
14 | return "Echo, Hello " + message;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-provider/src/main/java/top/ylonline/dubbo/sca/service/RestServiceImpl.java:
--------------------------------------------------------------------------------
1 | // package top.ylonline.dubbo.sca.service;
2 | //
3 | // import org.apache.dubbo.config.annotation.Service;
4 | // import top.ylonline.dubbo.sca.api.RestService;
5 | //
6 | // import javax.ws.rs.GET;
7 | // import javax.ws.rs.Path;
8 | // import javax.ws.rs.QueryParam;
9 | //
10 | // /**
11 | // * @author YL
12 | // */
13 | // @Service(protocol = "rest")
14 | // @Path("/rest")
15 | // public class RestServiceImpl implements RestService {
16 | //
17 | // @GET
18 | // @Path("/get")
19 | // @Override
20 | // public String getName(@QueryParam("id") long id) {
21 | // return "user id: " + id;
22 | // }
23 | // }
24 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-provider/src/main/resources/application-consul.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8080
3 | feign:
4 | hystrix:
5 | enabled: true
6 | dubbo:
7 | # scan:
8 | # base-packages: top.ylonline.dubbo.sca.service
9 | registry:
10 | address: spring-cloud://localhost
11 | protocols:
12 | dubbo:
13 | name: dubbo
14 | port: -1
15 | rest:
16 | name: rest
17 | port: 8081
18 | server: netty
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-provider/src/main/resources/application-zk.yml:
--------------------------------------------------------------------------------
1 | #feign:
2 | # hystrix:
3 | # enabled: true
4 | dubbo:
5 | application:
6 | id: dubbo-sca-provider
7 | name: dubbo-sca-provider
8 | qos-enable: false
9 | # qos-port: 33333
10 | # qos:
11 | # enable: false
12 | # port: 33333
13 | # accept:
14 | # foreign:
15 | # ip: false
16 | registry:
17 | address: spring-cloud://localhost
18 | # address: zookeeper://192.168.56.101:2181
19 | protocol:
20 | name: dubbo
21 | port: -1
22 | # config:
23 | # multiple: true
24 | # protocols:
25 | # dubbo:
26 | # name: dubbo
27 | # port: -1
28 | # rest:
29 | # name: rest
30 | # port: 8081
31 | # server: netty
32 |
33 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-provider/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: dubbo-sca-provider
4 | ---
5 | spring:
6 | profiles: zk
7 | cloud:
8 | zookeeper:
9 | enabled: true
10 | connect-string: 192.168.56.101:2181
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-sca/dubbo-sca-provider/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 | ${logger.pattern}
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-api/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | top.ylonline.dubbo
6 | dubbo-v2.6.x
7 | 1.0-SNAPSHOT
8 |
9 | 4.0.0
10 |
11 | dubbo-v2.6.x-api
12 | Java 最佳实践 :: dubbo(${project.artifactId})
13 |
14 |
15 | UTF-8
16 | 1.8
17 | 1.8
18 |
19 |
20 |
21 |
22 |
23 | org.jboss.resteasy
24 | resteasy-jaxrs
25 | provided
26 | true
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-api/src/main/java/top/ylonline/dubbo/spring/boot/api/DubboService.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.spring.boot.api;
2 |
3 | import javax.ws.rs.QueryParam;
4 |
5 | /**
6 | * @author YL
7 | */
8 | public interface DubboService {
9 | /**
10 | * echo
11 | *
12 | * @param message msg
13 | *
14 | * @return 信息
15 | */
16 | String echo(@QueryParam("message") String message);
17 | }
18 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-api/src/main/java/top/ylonline/dubbo/spring/boot/api/MultipleService.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.spring.boot.api;
2 |
3 | import javax.ws.rs.GET;
4 | import javax.ws.rs.Path;
5 | import javax.ws.rs.QueryParam;
6 |
7 | /**
8 | * @author YL
9 | */
10 | @Path("/multiple")
11 | public interface MultipleService {
12 | /**
13 | * echo
14 | *
15 | * @param message msg
16 | *
17 | * @return 信息
18 | */
19 | @GET
20 | @Path("/echo")
21 | String echo(@QueryParam("message") String message);
22 | }
23 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-api/src/main/java/top/ylonline/dubbo/spring/boot/api/RestService.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.spring.boot.api;
2 |
3 | import javax.ws.rs.GET;
4 | import javax.ws.rs.Path;
5 | import javax.ws.rs.QueryParam;
6 |
7 | /**
8 | * @author YL
9 | */
10 | @Path("/single")
11 | public interface RestService {
12 | /**
13 | * echo
14 | *
15 | * @param message msg
16 | *
17 | * @return 信息
18 | */
19 | @GET
20 | @Path("/echo")
21 | String echo(@QueryParam("message") String message);
22 | }
23 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-consumer/src/main/java/top/ylonline/dubbo/spring/boot/DubboConsumer.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.spring.boot;
2 |
3 | import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.boot.builder.SpringApplicationBuilder;
7 | import org.springframework.context.annotation.ImportResource;
8 |
9 | import java.util.Collections;
10 |
11 | /**
12 | * Hello world!
13 | *
14 | * @author YL
15 | */
16 | @SpringBootApplication
17 | @ImportResource(locations = {"classpath:dubbo-consumer-${spring.profiles.active}.xml"})
18 | @DubboComponentScan(basePackages = {"top.ylonline.dubbo.spring.boot"})
19 | @Slf4j
20 | public class DubboConsumer {
21 |
22 | /**
23 | * Common
24 | */
25 | private static SpringApplicationBuilder configureSpringBuilder(SpringApplicationBuilder builder) {
26 | // builder.application().addListeners(new EnvironmentPreparedEventListener());
27 | builder.application().addPrimarySources(Collections.singletonList(DubboConsumer.class));
28 | return builder.sources(DubboConsumer.class);
29 | }
30 |
31 | public static void main(String[] args) {
32 | configureSpringBuilder(new SpringApplicationBuilder())
33 | .application()
34 | .run(args);
35 | }
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-consumer/src/main/java/top/ylonline/dubbo/spring/boot/controller/DemoController.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.spring.boot.controller;
2 |
3 | import org.springframework.web.bind.annotation.GetMapping;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RequestParam;
6 | import org.springframework.web.bind.annotation.RestController;
7 | import top.ylonline.dubbo.spring.boot.api.DubboService;
8 | import top.ylonline.dubbo.spring.boot.api.MultipleService;
9 | import top.ylonline.dubbo.spring.boot.api.RestService;
10 |
11 | import javax.annotation.Resource;
12 |
13 | /**
14 | * @author YL
15 | */
16 | @RestController
17 | @RequestMapping("/demo")
18 | public class DemoController {
19 | /**
20 | * dubbo-2.6.5及以下版本的Reference还不支持protocol属性
21 | */
22 | @Resource
23 | private MultipleService multipleService;
24 | @Resource
25 | private DubboService dubboService;
26 | @Resource
27 | private RestService restService;
28 |
29 | @GetMapping("/multiple")
30 | public String user(@RequestParam String message) {
31 | return multipleService.echo(message);
32 | }
33 |
34 | @GetMapping("/dubbo")
35 | public String dubbo(@RequestParam String message) {
36 | return dubboService.echo(message);
37 | }
38 |
39 | @GetMapping("/rest")
40 | public String rest(@RequestParam String message) {
41 | return restService.echo(message);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-consumer/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8080
3 | servlet:
4 | context-path: /
5 | spring:
6 | profiles:
7 | active: zk
8 | application:
9 | name: dubbo-consumer
10 | #dubbo:
11 | # application:
12 | # name: dubbo-consumer
13 | # qos-enable: false
14 | # registry:
15 | # address: zookeeper://192.168.56.101:2181
16 | # client: curator
17 | # consumer:
18 | # check: 'false'
19 | # client: netty4
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-consumer/src/main/resources/dubbo-consumer-nacos.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
21 |
23 |
25 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-consumer/src/main/resources/dubbo-consumer-zk.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
21 |
23 |
25 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-consumer/src/main/resources/logback-spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 |
9 |
10 | ${logger.pattern}
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-provider/src/main/java/top/ylonline/dubbo/spring/boot/DubboProvider.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.spring.boot;
2 |
3 | import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.boot.builder.SpringApplicationBuilder;
7 |
8 | import java.util.Collections;
9 |
10 | /**
11 | * Hello world!
12 | *
13 | * @author YL
14 | */
15 | @SpringBootApplication
16 | @DubboComponentScan(basePackages = {"top.ylonline.dubbo.spring.boot"})
17 | @Slf4j
18 | public class DubboProvider {
19 |
20 | /**
21 | * Common
22 | */
23 | private static SpringApplicationBuilder configureSpringBuilder(SpringApplicationBuilder builder) {
24 | // builder.application().addListeners(new EnvironmentPreparedEventListener());
25 | builder.application().addPrimarySources(Collections.singletonList(DubboProvider.class));
26 | return builder.sources(DubboProvider.class);
27 | }
28 |
29 | public static void main(String[] args) {
30 | configureSpringBuilder(new SpringApplicationBuilder())
31 | .application()
32 | .run(args);
33 | }
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-provider/src/main/java/top/ylonline/dubbo/spring/boot/service/DubboServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.spring.boot.service;
2 |
3 | import com.alibaba.dubbo.config.annotation.Service;
4 | import com.alibaba.dubbo.rpc.RpcContext;
5 | import top.ylonline.dubbo.spring.boot.api.DubboService;
6 |
7 | import javax.ws.rs.QueryParam;
8 |
9 | /**
10 | * @author YL
11 | */
12 | @Service(protocol = {"dubbo"})
13 | public class DubboServiceImpl implements DubboService {
14 |
15 | @Override
16 | public String echo(@QueryParam("message") String message) {
17 | return "{\"message\": \"" + message + "\", \"protocol\": \"dubbo\", \"url\": \""
18 | + RpcContext.getContext().getUrl() + "\"}";
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-provider/src/main/java/top/ylonline/dubbo/spring/boot/service/MultipleServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.spring.boot.service;
2 |
3 | import com.alibaba.dubbo.config.annotation.Service;
4 | import com.alibaba.dubbo.rpc.RpcContext;
5 | import top.ylonline.dubbo.spring.boot.api.MultipleService;
6 |
7 | import javax.ws.rs.QueryParam;
8 |
9 | /**
10 | * @author YL
11 | */
12 | @Service(protocol = {"dubbo", "rest"})
13 | // @Path("/multiple")
14 | public class MultipleServiceImpl implements MultipleService {
15 |
16 | // @GET
17 | // @Path("/echo")
18 | @Override
19 | public String echo(@QueryParam("message") String message) {
20 | return "{\"message\": \""
21 | + message + "\", \"protocol\": \"dubbo + rest\", \"url\": \""
22 | + RpcContext.getContext().getUrl() + "\"}";
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-provider/src/main/java/top/ylonline/dubbo/spring/boot/service/RestServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo.spring.boot.service;
2 |
3 | import com.alibaba.dubbo.config.annotation.Service;
4 | import com.alibaba.dubbo.rpc.RpcContext;
5 | import top.ylonline.dubbo.spring.boot.api.RestService;
6 |
7 | import javax.ws.rs.QueryParam;
8 |
9 | /**
10 | * @author YL
11 | */
12 | @Service(protocol = {"rest"})
13 | // @Path("/single")
14 | public class RestServiceImpl implements RestService {
15 |
16 | // @GET
17 | // @Path("/echo")
18 | @Override
19 | public String echo(@QueryParam("message") String message) {
20 | return "{\"message\": \"" + message + "\", \"protocol\": \"rest\", \"url\": \""
21 | + RpcContext.getContext().getUrl() + "\"}";
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-provider/src/main/resources/application-nacos.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: dubbo-provider
4 | dubbo:
5 | application:
6 | name: dubbo-provider
7 | qos-enable: false
8 | registry:
9 | address: nacos://192.168.56.101:8848
10 | # register: false
11 | # protocol:
12 | # name: dubbo
13 | # port: 20880
14 | # server: netty4
15 | # protocol:
16 | # name: rest
17 | # port: 9090
18 | # server: netty
19 | config:
20 | multiple: true
21 | protocols:
22 | dubbo:
23 | name: dubbo
24 | port: -1
25 | server: netty4
26 | rest:
27 | name: rest
28 | port: 9090
29 | server: netty
30 | provider:
31 | delay: -1
32 | timeout: 20000
33 | retries: 0
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-provider/src/main/resources/application-zk.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: dubbo-provider
4 | dubbo:
5 | application:
6 | name: dubbo-provider
7 | qos-enable: false
8 | registry:
9 | address: zookeeper://192.168.56.101:2181
10 | client: curator
11 | # protocol:
12 | # name: dubbo
13 | # port: 20880
14 | # server: netty4
15 | # protocol:
16 | # name: rest
17 | # port: 9090
18 | # server: netty
19 | config:
20 | multiple: true
21 | protocols:
22 | dubbo:
23 | name: dubbo
24 | port: -1
25 | server: netty4
26 | rest:
27 | name: rest
28 | port: 9090
29 | server: netty
30 | provider:
31 | delay: -1
32 | timeout: 20000
33 | retries: 0
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-provider/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | profiles:
3 | active: zk
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.6.x/dubbo-v2.6.x-provider/src/main/resources/logback-spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 |
9 |
10 | ${logger.pattern}
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/README.md:
--------------------------------------------------------------------------------
1 | # dubbo-v2.7.x
2 | > 环境:
3 | > dubbo 2.7.1
4 | > duboo-spring-boot-starter 2.7.1
5 |
6 |
7 |
8 | ## 启动 provider
9 |
10 | 访问以下地址来判断`provider`端使用多协议是否正常
11 |
12 | [http://localhost:9090/single/echo?message=rest-protocol](http://localhost:9090/single/echo?message=rest-protocol)
13 |
14 | [http://localhost:9090//multiple/echo?message=dubbo-or-rest-protocol](http://localhost:9090/multiple/echo?message=dubbo-or-rest-protocol)
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ## 启动 consumer
23 |
24 | 分别访问以下地址来判断`consumer`端使用多协议是否正常
25 | - [http://localhost:8080/demo/dubbo?message=dubbo-protocol](http://localhost:8080/demo/dubbo?message=dubbo-protocol)
26 | - [http://localhost:8080/demo/rest?message=rest-protocol](http://localhost:8080/demo/rest?message=rest-protocol)
27 | - [http://localhost:8080/demo/multiple?message=dubbo-or-rest-protocol](http://localhost:8080/demo/multiple?message=dubbo-or-rest-protocol)
28 |
29 |
30 |
31 | ## 异常问题
32 |
33 | ### java.lang.NoClassDefFoundError: org/jboss/resteasy/client/jaxrs/engines/ApacheHttpClient4Engine
34 |
35 | > 需要添加以下依赖包,该依赖 provider 端无需依赖,consumer 端需要依赖
36 |
37 | ```xml
38 |
39 | org.jboss.resteasy
40 | resteasy-client
41 | ${resteasy-client.version}
42 |
43 | ```
44 |
45 |
46 |
47 | ### java.lang.RuntimeException: You must use at least one, but no more than one http method annotation on: top.ylonline
48 | .dubbo.spring.boot.example.api.EchoService.echo..
49 |
50 | > 出现这个异常,说明要在使用的接口标注:@Path、@POST、@Get等javax.ws.rs.*这个路径下相关注解,不应该在实现类标注
51 |
52 |
53 |
54 | ```java
55 | package top.ylonline.dubbo.spring.boot.api;
56 |
57 | import javax.ws.rs.GET;
58 | import javax.ws.rs.Path;
59 | import javax.ws.rs.QueryParam;
60 |
61 | /**
62 | * @author YL
63 | */
64 | @Path("/single")
65 | public interface RestService {
66 | /**
67 | * echo
68 | *
69 | * @param message msg
70 | *
71 | * @return 信息
72 | */
73 | @GET
74 | @Path("/echo")
75 | String echo(@QueryParam("message") String message);
76 | }
77 | ```
78 |
79 | ### Duplicate application configs
80 | 当使用`org.apache.dubbo:dubbo-spring-boot-starter` 2.7.0,同时使用xml作为`dubbo`的配置时,会出现以下异常:
81 | ```text
82 | Caused by: java.lang.IllegalStateException: Duplicate application configs: and
83 | ```
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-api/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | top.ylonline.dubbo
6 | dubbo-v2.7.x
7 | 1.0-SNAPSHOT
8 |
9 | 4.0.0
10 |
11 | dubbo-v2.7.x-api
12 | Java 最佳实践 :: dubbo(${project.artifactId})
13 |
14 |
15 | UTF-8
16 | 1.8
17 | 1.8
18 |
19 |
20 |
21 |
22 |
23 | org.jboss.resteasy
24 | resteasy-jaxrs
25 | provided
26 | true
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-api/src/main/java/top/ylonline/dubbo27x/api/DubboService.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo27x.api;
2 |
3 | /**
4 | * @author YL
5 | */
6 | public interface DubboService {
7 | /**
8 | * echo
9 | *
10 | * @param message msg
11 | *
12 | * @return 信息
13 | */
14 | String echo(String message);
15 | }
16 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-api/src/main/java/top/ylonline/dubbo27x/api/MultipleService.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo27x.api;
2 |
3 | import javax.ws.rs.GET;
4 | import javax.ws.rs.Path;
5 | import javax.ws.rs.QueryParam;
6 |
7 | /**
8 | * @author YL
9 | */
10 | @Path("/multiple")
11 | public interface MultipleService {
12 | /**
13 | * echo
14 | *
15 | * @param message msg
16 | *
17 | * @return 信息
18 | */
19 | @GET
20 | @Path("/echo")
21 | String echo(@QueryParam("message") String message);
22 | }
23 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-api/src/main/java/top/ylonline/dubbo27x/api/RestService.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo27x.api;
2 |
3 | import javax.ws.rs.GET;
4 | import javax.ws.rs.Path;
5 | import javax.ws.rs.QueryParam;
6 |
7 | /**
8 | * @author YL
9 | */
10 | @Path("/single")
11 | public interface RestService {
12 | /**
13 | * echo
14 | *
15 | * @param message msg
16 | *
17 | * @return 信息
18 | */
19 | @GET
20 | @Path("/echo")
21 | String echo(@QueryParam("message") String message);
22 | }
23 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-consumer/src/main/java/top/ylonline/dubbo27x/DubboConsumer270.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo27x;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
6 | import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
7 | import org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration;
8 |
9 | /**
10 | * @author YL
11 | */
12 | @SpringBootApplication(
13 | exclude = {
14 | DataSourceAutoConfiguration.class,
15 | WebSocketServletAutoConfiguration.class,
16 | JmxAutoConfiguration.class
17 | }
18 | )
19 | // @ImportResource(locations = {"classpath:dubbo-consumer-${spring.profiles.active}.xml"})
20 | public class DubboConsumer270 {
21 |
22 | public static void main(String[] args) {
23 | SpringApplication.run(DubboConsumer270.class, args);
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-consumer/src/main/java/top/ylonline/dubbo27x/controller/DemoController.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo27x.controller;
2 |
3 | import org.apache.dubbo.config.annotation.Reference;
4 | import org.springframework.web.bind.annotation.GetMapping;
5 | import org.springframework.web.bind.annotation.RequestMapping;
6 | import org.springframework.web.bind.annotation.RequestParam;
7 | import org.springframework.web.bind.annotation.RestController;
8 | import top.ylonline.dubbo27x.api.DubboService;
9 | import top.ylonline.dubbo27x.api.MultipleService;
10 | import top.ylonline.dubbo27x.api.RestService;
11 |
12 | /**
13 | * @author YL
14 | */
15 | @RestController
16 | @RequestMapping("/demo")
17 | public class DemoController {
18 | // @Resource
19 | // private MultipleService multipleService;
20 | // @Resource
21 | // private DubboService dubboService;
22 | // @Resource
23 | // private RestService restService;
24 |
25 | @Reference(protocol = "dubbo")
26 | private MultipleService multipleService;
27 | @Reference
28 | private DubboService dubboService;
29 | @Reference
30 | private RestService restService;
31 |
32 | @GetMapping("/multiple")
33 | public String user(@RequestParam String message) {
34 | return multipleService.echo(message);
35 | }
36 |
37 | @GetMapping("/dubbo")
38 | public String dubbo(@RequestParam String message) {
39 | return dubboService.echo(message);
40 | }
41 |
42 | @GetMapping("/rest")
43 | public String rest(@RequestParam String message) {
44 | return restService.echo(message);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-consumer/src/main/resources/application-zk.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8080
3 | servlet:
4 | context-path: /
5 | spring:
6 | application:
7 | name: dubbo-consumer-2.7.x
8 | dubbo:
9 | scan:
10 | base-packages: top.ylonline.dubbo27x
11 | application:
12 | name: ${spring.application.name}
13 | qos-enable: false
14 | registry:
15 | address: zookeeper://192.168.56.101:2181
16 | client: curator
17 | simplified: true
18 | metadata-report:
19 | address: ${dubbo.registry.address}
20 | consumer:
21 | check: false
22 | client: netty
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-consumer/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | profiles:
3 | active: zk
4 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-consumer/src/main/resources/dubbo-consumer-zk.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
20 |
22 |
24 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-consumer/src/main/resources/logback-spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 |
9 |
10 | ${logger.pattern}
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-provider/src/main/java/top/ylonline/dubbo27x/DubboProvider270.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo27x;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | /**
7 | * @author YL
8 | */
9 | @SpringBootApplication
10 | public class DubboProvider270 {
11 |
12 | public static void main(String[] args) {
13 | SpringApplication.run(DubboProvider270.class, args);
14 | }
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-provider/src/main/java/top/ylonline/dubbo27x/service/DubboServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo27x.service;
2 |
3 | import org.apache.dubbo.config.annotation.Service;
4 | import org.apache.dubbo.rpc.RpcContext;
5 | import top.ylonline.dubbo27x.api.DubboService;
6 |
7 | /**
8 | * @author YL
9 | */
10 | @Service(protocol = {"dubbo"})
11 | public class DubboServiceImpl implements DubboService {
12 |
13 | @Override
14 | public String echo(String message) {
15 | return "{\"message\": \"" + message + "\", \"protocol\": \"dubbo\", \"url\": \""
16 | + RpcContext.getContext().getUrl() + "\"}";
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-provider/src/main/java/top/ylonline/dubbo27x/service/MultipleServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo27x.service;
2 |
3 | import org.apache.dubbo.config.annotation.Service;
4 | import org.apache.dubbo.rpc.RpcContext;
5 | import top.ylonline.dubbo27x.api.MultipleService;
6 |
7 | import javax.ws.rs.QueryParam;
8 |
9 | /**
10 | * @author YL
11 | */
12 | @Service(protocol = {"dubbo", "rest"})
13 | // @Path("/multiple")
14 | public class MultipleServiceImpl implements MultipleService {
15 |
16 | // @GET
17 | // @Path("/echo")
18 | @Override
19 | public String echo(@QueryParam("message") String message) {
20 | return "{\"message\": \""
21 | + message + "\", \"protocol\": \"dubbo + rest\", \"url\": \""
22 | + RpcContext.getContext().getUrl() + "\"}";
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-provider/src/main/java/top/ylonline/dubbo27x/service/RestServiceImpl.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.dubbo27x.service;
2 |
3 | import org.apache.dubbo.config.annotation.Service;
4 | import org.apache.dubbo.rpc.RpcContext;
5 | import top.ylonline.dubbo27x.api.RestService;
6 |
7 | import javax.ws.rs.QueryParam;
8 |
9 | /**
10 | * @author YL
11 | */
12 | @Service(protocol = {"rest"})
13 | // @Path("/single")
14 | public class RestServiceImpl implements RestService {
15 |
16 | // @GET
17 | // @Path("/echo")
18 | @Override
19 | public String echo(@QueryParam("message") String message) {
20 | return "{\"message\": \"" + message + "\", \"protocol\": \"rest\", \"url\": \""
21 | + RpcContext.getContext().getUrl() + "\"}";
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-provider/src/main/resources/application-nacos.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: dubbo-provider-2.7.x
4 | dubbo:
5 | scan:
6 | base-packages: top.ylonline.dubbo27x
7 | application:
8 | name: dubbo-provider-2.7.x
9 | qos-enable: false
10 | registry:
11 | address: nacos://192.168.56.101:8848
12 | # register: false
13 | # protocol:
14 | # name: dubbo
15 | # port: 20880
16 | # server: netty4
17 | # protocol:
18 | # name: rest
19 | # port: 9090
20 | # server: netty
21 | config:
22 | multiple: true
23 | protocols:
24 | dubbo:
25 | name: dubbo
26 | port: -1
27 | server: netty
28 | rest:
29 | name: rest
30 | port: 9090
31 | server: netty
32 | provider:
33 | delay: -1
34 | timeout: 20000
35 | retries: 0
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-provider/src/main/resources/application-zk.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: dubbo-provider-2.7.x
4 | dubbo:
5 | scan:
6 | base-packages: top.ylonline.dubbo27x
7 | application:
8 | name: ${spring.application.name}
9 | qos-enable: false
10 | registry:
11 | address: zookeeper://192.168.56.101:2181
12 | client: curator
13 | simplified: true
14 | metadata-report:
15 | address: ${dubbo.registry.address}
16 | # protocol:
17 | # name: dubbo
18 | # port: -1
19 | # server: netty
20 | # protocol:
21 | # name: rest
22 | # port: 9090
23 | # server: netty
24 | config:
25 | multiple: true
26 | protocols:
27 | dubbo:
28 | name: dubbo
29 | port: -1
30 | server: netty
31 | rest:
32 | name: rest
33 | port: 9090
34 | server: netty
35 | provider:
36 | delay: -1
37 | timeout: 20000
38 | retries: 0
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-provider/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | profiles:
3 | active: zk
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/dubbo-v2.7.x-provider/src/main/resources/logback-spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 |
9 |
10 | ${logger.pattern}
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/dubbo-examples/dubbo-v2.7.x/元数据中心配置.md:
--------------------------------------------------------------------------------
1 | # 元数据中心配置
2 | > 环境:
3 | > dubbo 2.7.0
4 | > duboo-spring-boot-starter 2.7.0
5 |
6 | ## zookeeper
7 | ```yaml
8 | dubbo:
9 | scan:
10 | base-packages: top.ylonline.dubbo27x
11 | application:
12 | name: dubbo-provider-2.7.x
13 | qos-enable: false
14 | registry:
15 | address: zookeeper://192.168.56.101:2181
16 | client: curator
17 | simplified: true
18 | metadata-report:
19 | address: ${dubbo.registry.address}
20 | ```
21 |
22 | ```xml
23 |
24 |
25 | org.apache.dubbo
26 | dubbo
27 |
28 |
29 |
30 | com.google.code.gson
31 | gson
32 |
33 | ```
34 |
35 | ## redis
36 | ```yaml
37 | dubbo:
38 | scan:
39 | base-packages: top.ylonline.dubbo27x
40 | application:
41 | name: dubbo-provider-2.7.x
42 | qos-enable: false
43 | registry:
44 | address: zookeeper://192.168.56.101:2181
45 | client: curator
46 | simplified: true
47 | metadata-report:
48 | address: redis://192.168.56.101:6379
49 | ```
50 |
51 | ```xml
52 |
53 |
54 | org.apache.dubbo
55 | dubbo
56 |
57 |
58 |
59 | com.google.code.gson
60 | gson
61 |
62 |
63 | redis.clients
64 | jedis
65 |
66 | ```
--------------------------------------------------------------------------------
/dubbo-examples/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | top.ylonline
6 | java-best-practice
7 | 1.0-SNAPSHOT
8 |
9 | 4.0.0
10 |
11 | top.ylonline.dubbo
12 | dubbo-examples
13 | Java 最佳实践 :: dubbo
14 | pom
15 |
16 |
17 | dubbo-v2.6.x
18 | dubbo-v2.7.x
19 | dubbo-sca
20 |
21 |
22 |
23 | UTF-8
24 | 1.8
25 | 1.8
26 |
27 |
28 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/README.md:
--------------------------------------------------------------------------------
1 | # 前后端分离数据加密传输
2 |
3 | ## RSA 非对称加密算法
4 | 1977年,三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。
5 |
6 |
7 | 这种算法非常可靠,密钥越长,它就越难破解。根据已经披露的文献,目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。
8 |
9 | > 本例子使用的密钥长度为:1024
10 | > 请看 RsaUtils 类 KEY_SIZE 变量
11 |
12 |
13 | ## 原理
14 |
15 | > 后端传输到前端
16 |
17 | 后端使用`AES`加密数据,并使用`RSA私钥`加密`AES密钥`;
18 |
19 | 前端使用`RSA公钥`解密`AES密钥`,再使用解密后的`AES密钥`解密数据。
20 |
21 | > 前端传输到后端
22 |
23 | 前端使用`AES`加密数据,并使用`RSA公钥`加密`AES密钥`;
24 |
25 | 后端使用`RSA私钥`解密前端传过来的`AES密钥`,再使用`RSA`解密后的`AES 密钥`解密数据。
26 |
27 |
28 | ## 为什么使用 RSA 加密 AES 的密钥
29 | 用对称加密算法(比如:`AES`)来加密消息,然后利用`RSA
30 | `称加密算法加密密钥传递。因为在同等安全等级下,`RSA`加密算法作为一种非对称密码学系统,通常比对称加密体制要慢。对称加密算法的密钥和要传递的消息相比通常要短得多,所以相比之下使用`RSA`加密密钥然后用对称加密来加密任意长度的消息,这样要更快很多。
31 |
32 |
33 | ## AES demo
34 | [http://localhost:8087/demo/aes](http://localhost:8087/demo/aes),打开浏览器控制台查看日志输出
35 |
36 |
37 | ## RSA demo
38 | [http://localhost:8087/demo/rsa](http://localhost:8087/demo/rsa),打开浏览器控制台查看日志输出
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/java/top/ylonline/encrypt/FrontendBackendEncryptWithRsaApp.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.encrypt;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | /**
7 | * Hello world!
8 | *
9 | * @author YL
10 | */
11 | @SpringBootApplication
12 | public class FrontendBackendEncryptWithRsaApp {
13 |
14 | public static void main(String[] args) {
15 | SpringApplication.run(FrontendBackendEncryptWithRsaApp.class, args);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/java/top/ylonline/encrypt/common/Const.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.encrypt.common;
2 |
3 | /**
4 | * @author YL
5 | */
6 | public class Const {
7 | /**
8 | * 原始字符串:明文
9 | */
10 | public static final String STR = "测试123abc";
11 |
12 | /**
13 | * rsa 模
14 | */
15 | public static final String MODULUS =
16 | "bdfb837d5fc8de0a6408b8720cdd557e08b4af0ebf9552311e8e89352fc7390b91ce3d84b20a36fe80c1aae279a68b04338724565b47052f19fc57c109e54bbeba5318b55ed472f6798a2828d1e8b61984b8d586e932ee2cfbc26155f3ae47df6aa1993d38d80d9c061c016e514d78f296055a44299b7c5de6cc74a376fa535f";
17 | /**
18 | * rsa 私钥指数
19 | */
20 | public static final String PRIVATE_EXPONENT =
21 | "7414f626e91be6f01a6769abe648673077494f9d875a49ba519d6e20dd6cb1626c58c4260c53497f00555580c42c0acd2a5eecc90744c1da21da9a140d63d97f45f92a1d05cc177edf19a2f360786d06058d5aee21ec7527b0006531497986498dd8204aa45eecebcc73c63454617d482a1144cf6f6e3fd85098d3d163aa2421";
22 | /**
23 | * rsa 公钥指数
24 | */
25 | public static final String PUBLIC_EXPONENT = "10001";
26 | }
27 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/java/top/ylonline/encrypt/controller/DemoController.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.encrypt.controller;
2 |
3 | import org.springframework.stereotype.Controller;
4 | import org.springframework.ui.Model;
5 | import org.springframework.web.bind.annotation.GetMapping;
6 | import org.springframework.web.bind.annotation.RequestMapping;
7 | import top.ylonline.encrypt.common.Const;
8 | import top.ylonline.encrypt.util.AesUtils;
9 | import top.ylonline.encrypt.util.RsaUtils;
10 |
11 | /**
12 | * @author YL
13 | */
14 | @Controller
15 | @RequestMapping("/demo")
16 | public class DemoController {
17 |
18 | @GetMapping("/aes")
19 | public String aes(Model model) {
20 | model.addAttribute("str", Const.STR);
21 | String key = AesUtils.randomKey();
22 | model.addAttribute("key", key);
23 | // 加密后的明文
24 | model.addAttribute("encrypt", AesUtils.encrypt(key, "UTF-8", Const.STR));
25 | return "aes";
26 | }
27 |
28 | @GetMapping("/rsa")
29 | public String rsa(Model model) {
30 | model.addAttribute("str", Const.STR);
31 | model.addAttribute("modulus", Const.MODULUS);
32 | // todo 私钥禁止传到前端(这里是为了测试),公钥可以传到前端
33 | model.addAttribute("privateExponent", Const.PRIVATE_EXPONENT);
34 | model.addAttribute("publicExponent", Const.PUBLIC_EXPONENT);
35 |
36 | // 私钥加密后的明文
37 | model.addAttribute("encrypt", RsaUtils.encryptPrivate(Const.MODULUS, Const.PRIVATE_EXPONENT, Const.STR));
38 | return "rsa";
39 | }
40 |
41 | @GetMapping("/rsa-and-aes")
42 | public String rsaAndAes(Model model) {
43 | String aesKey = "";
44 | model.addAttribute("str", Const.STR);
45 | model.addAttribute("modulus", Const.MODULUS);
46 | // todo 私钥禁止传到前端(这里是为了测试),公钥可以传到前端
47 | model.addAttribute("privateExponent", Const.PRIVATE_EXPONENT);
48 | model.addAttribute("publicExponent", Const.PUBLIC_EXPONENT);
49 |
50 | // aes 加密数据
51 | model.addAttribute("encryptData", AesUtils.encrypt(aesKey, "UTF-8", Const.STR));
52 |
53 | // rsa 加密 aes 密钥
54 | model.addAttribute("encryptAesKey", RsaUtils.encryptPrivate(Const.MODULUS, Const.PRIVATE_EXPONENT, aesKey));
55 | return "rsa-and-aes";
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/java/top/ylonline/encrypt/util/EncryptException.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.encrypt.util;
2 |
3 | /**
4 | * 统一异常封装
5 | *
6 | * @author YL
7 | */
8 | public class EncryptException extends RuntimeException {
9 | private static final long serialVersionUID = 1L;
10 |
11 | public EncryptException(String msg) {
12 | super(msg);
13 | }
14 |
15 | public EncryptException(Exception cause) {
16 | super(cause);
17 | }
18 |
19 | public EncryptException(String msg, Exception cause) {
20 | super(msg, cause);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8087
3 | servlet:
4 | context-path: /
5 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 | ${logger.pattern}
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/format-hex.js:
--------------------------------------------------------------------------------
1 | (function (undefined) {
2 | // Shortcuts
3 | var C = CryptoJS;
4 | var C_lib = C.lib;
5 | var CipherParams = C_lib.CipherParams;
6 | var C_enc = C.enc;
7 | var Hex = C_enc.Hex;
8 | var C_format = C.format;
9 |
10 | var HexFormatter = C_format.Hex = {
11 | /**
12 | * Converts the ciphertext of a cipher params object to a hexadecimally encoded string.
13 | *
14 | * @param {CipherParams} cipherParams The cipher params object.
15 | *
16 | * @return {string} The hexadecimally encoded string.
17 | *
18 | * @static
19 | *
20 | * @example
21 | *
22 | * var hexString = CryptoJS.format.Hex.stringify(cipherParams);
23 | */
24 | stringify: function (cipherParams) {
25 | return cipherParams.ciphertext.toString(Hex);
26 | },
27 |
28 | /**
29 | * Converts a hexadecimally encoded ciphertext string to a cipher params object.
30 | *
31 | * @param {string} input The hexadecimally encoded string.
32 | *
33 | * @return {CipherParams} The cipher params object.
34 | *
35 | * @static
36 | *
37 | * @example
38 | *
39 | * var cipherParams = CryptoJS.format.Hex.parse(hexString);
40 | */
41 | parse: function (input) {
42 | var ciphertext = Hex.parse(input);
43 | return CipherParams.create({ ciphertext: ciphertext });
44 | }
45 | };
46 | }());
47 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/lib-typedarrays.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | // Check if typed arrays are supported
3 | if (typeof ArrayBuffer != 'function') {
4 | return;
5 | }
6 |
7 | // Shortcuts
8 | var C = CryptoJS;
9 | var C_lib = C.lib;
10 | var WordArray = C_lib.WordArray;
11 |
12 | // Reference original init
13 | var superInit = WordArray.init;
14 |
15 | // Augment WordArray.init to handle typed arrays
16 | var subInit = WordArray.init = function (typedArray) {
17 | // Convert buffers to uint8
18 | if (typedArray instanceof ArrayBuffer) {
19 | typedArray = new Uint8Array(typedArray);
20 | }
21 |
22 | // Convert other array views to uint8
23 | if (
24 | typedArray instanceof Int8Array ||
25 | (typeof Uint8ClampedArray !== "undefined" && typedArray instanceof Uint8ClampedArray) ||
26 | typedArray instanceof Int16Array ||
27 | typedArray instanceof Uint16Array ||
28 | typedArray instanceof Int32Array ||
29 | typedArray instanceof Uint32Array ||
30 | typedArray instanceof Float32Array ||
31 | typedArray instanceof Float64Array
32 | ) {
33 | typedArray = new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength);
34 | }
35 |
36 | // Handle Uint8Array
37 | if (typedArray instanceof Uint8Array) {
38 | // Shortcut
39 | var typedArrayByteLength = typedArray.byteLength;
40 |
41 | // Extract bytes
42 | var words = [];
43 | for (var i = 0; i < typedArrayByteLength; i++) {
44 | words[i >>> 2] |= typedArray[i] << (24 - (i % 4) * 8);
45 | }
46 |
47 | // Initialize this word array
48 | superInit.call(this, words, typedArrayByteLength);
49 | } else {
50 | // Else call normal init
51 | superInit.apply(this, arguments);
52 | }
53 | };
54 |
55 | subInit.prototype = WordArray;
56 | }());
57 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/mode-cfb.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Cipher Feedback block mode.
3 | */
4 | CryptoJS.mode.CFB = (function () {
5 | var CFB = CryptoJS.lib.BlockCipherMode.extend();
6 |
7 | CFB.Encryptor = CFB.extend({
8 | processBlock: function (words, offset) {
9 | // Shortcuts
10 | var cipher = this._cipher;
11 | var blockSize = cipher.blockSize;
12 |
13 | generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
14 |
15 | // Remember this block to use with next block
16 | this._prevBlock = words.slice(offset, offset + blockSize);
17 | }
18 | });
19 |
20 | CFB.Decryptor = CFB.extend({
21 | processBlock: function (words, offset) {
22 | // Shortcuts
23 | var cipher = this._cipher;
24 | var blockSize = cipher.blockSize;
25 |
26 | // Remember this block to use with next block
27 | var thisBlock = words.slice(offset, offset + blockSize);
28 |
29 | generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
30 |
31 | // This block becomes the previous block
32 | this._prevBlock = thisBlock;
33 | }
34 | });
35 |
36 | function generateKeystreamAndEncrypt(words, offset, blockSize, cipher) {
37 | // Shortcut
38 | var iv = this._iv;
39 |
40 | // Generate keystream
41 | if (iv) {
42 | var keystream = iv.slice(0);
43 |
44 | // Remove IV for subsequent blocks
45 | this._iv = undefined;
46 | } else {
47 | var keystream = this._prevBlock;
48 | }
49 | cipher.encryptBlock(keystream, 0);
50 |
51 | // Encrypt
52 | for (var i = 0; i < blockSize; i++) {
53 | words[offset + i] ^= keystream[i];
54 | }
55 | }
56 |
57 | return CFB;
58 | }());
59 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/mode-ctr-gladman.js:
--------------------------------------------------------------------------------
1 | /** @preserve
2 | * Counter block mode compatible with Dr Brian Gladman fileenc.c
3 | * derived from CryptoJS.mode.CTR
4 | * Jan Hruby jhruby.web@gmail.com
5 | */
6 | CryptoJS.mode.CTRGladman = (function () {
7 | var CTRGladman = CryptoJS.lib.BlockCipherMode.extend();
8 |
9 | function incWord(word)
10 | {
11 | if (((word >> 24) & 0xff) === 0xff) { //overflow
12 | var b1 = (word >> 16)&0xff;
13 | var b2 = (word >> 8)&0xff;
14 | var b3 = word & 0xff;
15 |
16 | if (b1 === 0xff) // overflow b1
17 | {
18 | b1 = 0;
19 | if (b2 === 0xff)
20 | {
21 | b2 = 0;
22 | if (b3 === 0xff)
23 | {
24 | b3 = 0;
25 | }
26 | else
27 | {
28 | ++b3;
29 | }
30 | }
31 | else
32 | {
33 | ++b2;
34 | }
35 | }
36 | else
37 | {
38 | ++b1;
39 | }
40 |
41 | word = 0;
42 | word += (b1 << 16);
43 | word += (b2 << 8);
44 | word += b3;
45 | }
46 | else
47 | {
48 | word += (0x01 << 24);
49 | }
50 | return word;
51 | }
52 |
53 | function incCounter(counter)
54 | {
55 | if ((counter[0] = incWord(counter[0])) === 0)
56 | {
57 | // encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8
58 | counter[1] = incWord(counter[1]);
59 | }
60 | return counter;
61 | }
62 |
63 | var Encryptor = CTRGladman.Encryptor = CTRGladman.extend({
64 | processBlock: function (words, offset) {
65 | // Shortcuts
66 | var cipher = this._cipher
67 | var blockSize = cipher.blockSize;
68 | var iv = this._iv;
69 | var counter = this._counter;
70 |
71 | // Generate keystream
72 | if (iv) {
73 | counter = this._counter = iv.slice(0);
74 |
75 | // Remove IV for subsequent blocks
76 | this._iv = undefined;
77 | }
78 |
79 | incCounter(counter);
80 |
81 | var keystream = counter.slice(0);
82 | cipher.encryptBlock(keystream, 0);
83 |
84 | // Encrypt
85 | for (var i = 0; i < blockSize; i++) {
86 | words[offset + i] ^= keystream[i];
87 | }
88 | }
89 | });
90 |
91 | CTRGladman.Decryptor = Encryptor;
92 |
93 | return CTRGladman;
94 | }());
95 |
96 |
97 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/mode-ctr.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Counter block mode.
3 | */
4 | CryptoJS.mode.CTR = (function () {
5 | var CTR = CryptoJS.lib.BlockCipherMode.extend();
6 |
7 | var Encryptor = CTR.Encryptor = CTR.extend({
8 | processBlock: function (words, offset) {
9 | // Shortcuts
10 | var cipher = this._cipher
11 | var blockSize = cipher.blockSize;
12 | var iv = this._iv;
13 | var counter = this._counter;
14 |
15 | // Generate keystream
16 | if (iv) {
17 | counter = this._counter = iv.slice(0);
18 |
19 | // Remove IV for subsequent blocks
20 | this._iv = undefined;
21 | }
22 | var keystream = counter.slice(0);
23 | cipher.encryptBlock(keystream, 0);
24 |
25 | // Increment counter
26 | counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0
27 |
28 | // Encrypt
29 | for (var i = 0; i < blockSize; i++) {
30 | words[offset + i] ^= keystream[i];
31 | }
32 | }
33 | });
34 |
35 | CTR.Decryptor = Encryptor;
36 |
37 | return CTR;
38 | }());
39 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/mode-ecb.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Electronic Codebook block mode.
3 | */
4 | CryptoJS.mode.ECB = (function () {
5 | var ECB = CryptoJS.lib.BlockCipherMode.extend();
6 |
7 | ECB.Encryptor = ECB.extend({
8 | processBlock: function (words, offset) {
9 | this._cipher.encryptBlock(words, offset);
10 | }
11 | });
12 |
13 | ECB.Decryptor = ECB.extend({
14 | processBlock: function (words, offset) {
15 | this._cipher.decryptBlock(words, offset);
16 | }
17 | });
18 |
19 | return ECB;
20 | }());
21 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/mode-ofb.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Output Feedback block mode.
3 | */
4 | CryptoJS.mode.OFB = (function () {
5 | var OFB = CryptoJS.lib.BlockCipherMode.extend();
6 |
7 | var Encryptor = OFB.Encryptor = OFB.extend({
8 | processBlock: function (words, offset) {
9 | // Shortcuts
10 | var cipher = this._cipher
11 | var blockSize = cipher.blockSize;
12 | var iv = this._iv;
13 | var keystream = this._keystream;
14 |
15 | // Generate keystream
16 | if (iv) {
17 | keystream = this._keystream = iv.slice(0);
18 |
19 | // Remove IV for subsequent blocks
20 | this._iv = undefined;
21 | }
22 | cipher.encryptBlock(keystream, 0);
23 |
24 | // Encrypt
25 | for (var i = 0; i < blockSize; i++) {
26 | words[offset + i] ^= keystream[i];
27 | }
28 | }
29 | });
30 |
31 | OFB.Decryptor = Encryptor;
32 |
33 | return OFB;
34 | }());
35 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/pad-ansix923.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ANSI X.923 padding strategy.
3 | */
4 | CryptoJS.pad.AnsiX923 = {
5 | pad: function (data, blockSize) {
6 | // Shortcuts
7 | var dataSigBytes = data.sigBytes;
8 | var blockSizeBytes = blockSize * 4;
9 |
10 | // Count padding bytes
11 | var nPaddingBytes = blockSizeBytes - dataSigBytes % blockSizeBytes;
12 |
13 | // Compute last byte position
14 | var lastBytePos = dataSigBytes + nPaddingBytes - 1;
15 |
16 | // Pad
17 | data.clamp();
18 | data.words[lastBytePos >>> 2] |= nPaddingBytes << (24 - (lastBytePos % 4) * 8);
19 | data.sigBytes += nPaddingBytes;
20 | },
21 |
22 | unpad: function (data) {
23 | // Get number of padding bytes from last byte
24 | var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
25 |
26 | // Remove padding
27 | data.sigBytes -= nPaddingBytes;
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/pad-iso10126.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ISO 10126 padding strategy.
3 | */
4 | CryptoJS.pad.Iso10126 = {
5 | pad: function (data, blockSize) {
6 | // Shortcut
7 | var blockSizeBytes = blockSize * 4;
8 |
9 | // Count padding bytes
10 | var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
11 |
12 | // Pad
13 | data.concat(CryptoJS.lib.WordArray.random(nPaddingBytes - 1)).
14 | concat(CryptoJS.lib.WordArray.create([nPaddingBytes << 24], 1));
15 | },
16 |
17 | unpad: function (data) {
18 | // Get number of padding bytes from last byte
19 | var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
20 |
21 | // Remove padding
22 | data.sigBytes -= nPaddingBytes;
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/pad-iso97971.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ISO/IEC 9797-1 Padding Method 2.
3 | */
4 | CryptoJS.pad.Iso97971 = {
5 | pad: function (data, blockSize) {
6 | // Add 0x80 byte
7 | data.concat(CryptoJS.lib.WordArray.create([0x80000000], 1));
8 |
9 | // Zero pad the rest
10 | CryptoJS.pad.ZeroPadding.pad(data, blockSize);
11 | },
12 |
13 | unpad: function (data) {
14 | // Remove zero padding
15 | CryptoJS.pad.ZeroPadding.unpad(data);
16 |
17 | // Remove one more byte -- the 0x80 byte
18 | data.sigBytes--;
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/pad-nopadding.js:
--------------------------------------------------------------------------------
1 | /**
2 | * A noop padding strategy.
3 | */
4 | CryptoJS.pad.NoPadding = {
5 | pad: function () {
6 | },
7 |
8 | unpad: function () {
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/pad-zeropadding.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Zero padding strategy.
3 | */
4 | CryptoJS.pad.ZeroPadding = {
5 | pad: function (data, blockSize) {
6 | // Shortcut
7 | var blockSizeBytes = blockSize * 4;
8 |
9 | // Pad
10 | data.clamp();
11 | data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes);
12 | },
13 |
14 | unpad: function (data) {
15 | // Shortcut
16 | var dataWords = data.words;
17 |
18 | // Unpad
19 | var i = data.sigBytes - 1;
20 | while (!((dataWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff)) {
21 | i--;
22 | }
23 | data.sigBytes = i + 1;
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/sha224.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | // Shortcuts
3 | var C = CryptoJS;
4 | var C_lib = C.lib;
5 | var WordArray = C_lib.WordArray;
6 | var C_algo = C.algo;
7 | var SHA256 = C_algo.SHA256;
8 |
9 | /**
10 | * SHA-224 hash algorithm.
11 | */
12 | var SHA224 = C_algo.SHA224 = SHA256.extend({
13 | _doReset: function () {
14 | this._hash = new WordArray.init([
15 | 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
16 | 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
17 | ]);
18 | },
19 |
20 | _doFinalize: function () {
21 | var hash = SHA256._doFinalize.call(this);
22 |
23 | hash.sigBytes -= 4;
24 |
25 | return hash;
26 | }
27 | });
28 |
29 | /**
30 | * Shortcut function to the hasher's object interface.
31 | *
32 | * @param {WordArray|string} message The message to hash.
33 | *
34 | * @return {WordArray} The hash.
35 | *
36 | * @static
37 | *
38 | * @example
39 | *
40 | * var hash = CryptoJS.SHA224('message');
41 | * var hash = CryptoJS.SHA224(wordArray);
42 | */
43 | C.SHA224 = SHA256._createHelper(SHA224);
44 |
45 | /**
46 | * Shortcut function to the HMAC's object interface.
47 | *
48 | * @param {WordArray|string} message The message to hash.
49 | * @param {WordArray|string} key The secret key.
50 | *
51 | * @return {WordArray} The HMAC.
52 | *
53 | * @static
54 | *
55 | * @example
56 | *
57 | * var hmac = CryptoJS.HmacSHA224(message, key);
58 | */
59 | C.HmacSHA224 = SHA256._createHmacHelper(SHA224);
60 | }());
61 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/static/crypto-js/sha384.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | // Shortcuts
3 | var C = CryptoJS;
4 | var C_x64 = C.x64;
5 | var X64Word = C_x64.Word;
6 | var X64WordArray = C_x64.WordArray;
7 | var C_algo = C.algo;
8 | var SHA512 = C_algo.SHA512;
9 |
10 | /**
11 | * SHA-384 hash algorithm.
12 | */
13 | var SHA384 = C_algo.SHA384 = SHA512.extend({
14 | _doReset: function () {
15 | this._hash = new X64WordArray.init([
16 | new X64Word.init(0xcbbb9d5d, 0xc1059ed8), new X64Word.init(0x629a292a, 0x367cd507),
17 | new X64Word.init(0x9159015a, 0x3070dd17), new X64Word.init(0x152fecd8, 0xf70e5939),
18 | new X64Word.init(0x67332667, 0xffc00b31), new X64Word.init(0x8eb44a87, 0x68581511),
19 | new X64Word.init(0xdb0c2e0d, 0x64f98fa7), new X64Word.init(0x47b5481d, 0xbefa4fa4)
20 | ]);
21 | },
22 |
23 | _doFinalize: function () {
24 | var hash = SHA512._doFinalize.call(this);
25 |
26 | hash.sigBytes -= 16;
27 |
28 | return hash;
29 | }
30 | });
31 |
32 | /**
33 | * Shortcut function to the hasher's object interface.
34 | *
35 | * @param {WordArray|string} message The message to hash.
36 | *
37 | * @return {WordArray} The hash.
38 | *
39 | * @static
40 | *
41 | * @example
42 | *
43 | * var hash = CryptoJS.SHA384('message');
44 | * var hash = CryptoJS.SHA384(wordArray);
45 | */
46 | C.SHA384 = SHA512._createHelper(SHA384);
47 |
48 | /**
49 | * Shortcut function to the HMAC's object interface.
50 | *
51 | * @param {WordArray|string} message The message to hash.
52 | * @param {WordArray|string} key The secret key.
53 | *
54 | * @return {WordArray} The HMAC.
55 | *
56 | * @static
57 | *
58 | * @example
59 | *
60 | * var hmac = CryptoJS.HmacSHA384(message, key);
61 | */
62 | C.HmacSHA384 = SHA512._createHmacHelper(SHA384);
63 | }());
64 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/templates/error/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 404
5 |
6 |
7 |
8 |
9 | 404
10 |
11 |
12 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/main/resources/templates/error/500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 500
5 |
6 |
7 |
8 |
9 | 500
10 |
11 |
12 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/test/java/top/ylonline/encrypt/AppTest.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.encrypt;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertTrue;
6 |
7 | /**
8 | * Unit test for simple App.
9 | */
10 | public class AppTest {
11 | /**
12 | * Rigorous Test :-)
13 | */
14 | @Test
15 | public void shouldAnswerWithTrue() {
16 | assertTrue(true);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/encrypt-examples/frontend-backend-encrypt-with-rsa/src/test/java/top/ylonline/encrypt/util/AesUtilsTest.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.encrypt.util;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 | import top.ylonline.encrypt.common.Const;
6 |
7 | /**
8 | * @author YL
9 | */
10 | public class AesUtilsTest {
11 |
12 | @Test
13 | public void backend() {
14 | String str = Const.STR;
15 |
16 | String key = AesUtils.randomKey();
17 | System.out.println("key: " + key);
18 | String encrypt = AesUtils.encrypt(key, "UTF-8", str);
19 | System.out.println("encrypt: " + encrypt);
20 | String decrypt = AesUtils.decrypt(key, "UTF-8", encrypt);
21 | System.out.println("decrypt: " + decrypt);
22 | Assert.assertEquals(str, decrypt);
23 | }
24 |
25 | /**
26 | * 前端解密,后端解密
27 | */
28 | @Test
29 | public void frontend() {
30 | String key = "NHXGgRvVrvLv4GaB";
31 | String encrypt = "Eq8kNQVlgaz+JbpR3R/Z0Q==";
32 | String decrypt = AesUtils.decrypt(key, "UTF-8", encrypt);
33 | System.out.println("decrypt: " + decrypt);
34 | Assert.assertEquals(Const.STR, decrypt);
35 | }
36 | }
--------------------------------------------------------------------------------
/encrypt-examples/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | top.ylonline
6 | java-best-practice
7 | 1.0-SNAPSHOT
8 |
9 | 4.0.0
10 |
11 | top.ylonline.encrypt
12 | encrypt-examples
13 | Java 最佳实践 :: encrypt
14 | pom
15 |
16 |
17 | frontend-backend-encrypt-with-rsa
18 |
19 |
20 |
21 | UTF-8
22 | 1.8
23 | 1.8
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/feign-examples/openfeign/src/main/java/top/ylonline/feign/OpenFeignApp.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.feign;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.openfeign.EnableFeignClients;
6 |
7 | /**
8 | * @author YL
9 | */
10 | @SpringBootApplication
11 | @EnableFeignClients
12 | public class OpenFeignApp {
13 |
14 | public static void main(String[] args) {
15 | SpringApplication.run(OpenFeignApp.class, args);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/feign-examples/openfeign/src/main/java/top/ylonline/feign/client/CspClient.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.feign.client;
2 |
3 | import org.springframework.cloud.openfeign.FeignClient;
4 | import org.springframework.web.bind.annotation.PostMapping;
5 | import org.springframework.web.bind.annotation.RequestBody;
6 |
7 | /**
8 | * @author YL
9 | */
10 | @FeignClient(
11 | name = "ic",
12 | url = "http://127.0.0.1:8888/ic/services/ws"
13 | )
14 | public interface CspClient {
15 |
16 | /**
17 | * 调用 ic 平台接口
18 | *
19 | * @param xml 入参
20 | *
21 | * @return 接口出参
22 | */
23 | @PostMapping(headers = {"SOAPAction=\"\"", "Content-Type=text/xml; charset=gbk"})
24 | String call(@RequestBody String xml);
25 | }
26 |
--------------------------------------------------------------------------------
/feign-examples/openfeign/src/main/java/top/ylonline/feign/client/Github.java:
--------------------------------------------------------------------------------
1 | package top.ylonline.feign.client;
2 |
3 | import feign.Param;
4 | import feign.RequestLine;
5 |
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | /**
10 | * @author YL
11 | */
12 | public interface Github {
13 | /**
14 | * 获取 github 仓库的贡献者
15 | *
16 | * @param owner github 拥有者
17 | * @param repo github repository name
18 | *
19 | * @return 贡献者列表
20 | */
21 | @RequestLine("GET /repos/{owner}/{repo}/contributors")
22 | List