Spring Cloud开发实践 - 03 - 接口实现和下游调用
接口实现 Scot Commons Impl
接口实现模块 scot-commons-impl, 一方面实现了 scot-commons-api 的接口, 一方面将自己暴露为 REST 服务. 有4个文件, 分别为 pom.xml, application.yml, ServiceImplApplication.xml 和 UserDTOServiceImpl.java
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <parent>
<groupId>com.rockbb</groupId>
<artifactId>scot</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../scot/pom.xml</relativePath>
</parent>
<artifactId>scot-commons-impl</artifactId>
<packaging>jar</packaging> <name>Scot: Commons Implementation</name> <dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>com.rockbb</groupId>
<artifactId>scot-commons-api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies> <build>
<finalName>scot-commons</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
server:
port: ${PORT:} spring:
application:
name: scot-commons eureka:
client:
serviceUrl:
defaultZone: http://localhost:/eureka/
ServiceImplApplication.java
这里不能引入FeignClient, 以免激活api中的注解.
@EnableEurekaClient
@SpringBootApplication
public class ServiceImplApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceImplApplication.class, args);
}
}
UserDTOServiceImpl.java
在UserDTOServiceImpl.java中, 实现了UserDTOService的接口, 因为这里的RequestMapping就是FeignClient将要读取的路径, 所以可以原封不动地将UserDTOService中的定义复制到这里. 统一了接口与实现.
@RequestMapping("/user")
@RestController
public class UserDTOServiceImpl implements UserDTOService {
@Value("${spring.cloud.client.hostname}")
String ipAddress;
@Value("${server.port}")
String port;
@Value("${spring.application.name}")
String applicationName; @Override
@RequestMapping(value = "/diagnos", method = RequestMethod.GET)
public String diagnos(@RequestParam String name) {
return ipAddress+":"+port+":"+applicationName+": " + name;
} @Override
@RequestMapping(value = "/get", method = RequestMethod.GET)
public UserDTO get(@RequestParam String id) {
return new UserDTO().initialize("3utowired5nnotation9ean0osterocessor", "system");
} @Override
@RequestMapping(value = "/list", method = RequestMethod.GET)
public List<UserDTO> list() {
return new ArrayList<>();
} @Override
@RequestMapping(value = "/count", method = RequestMethod.GET)
public long count() {
return 99;
}
}
下游调用 Scot Web
在这个模块中主要实现了两个功能, 一是通过scot-commons-api的定义引用scot-commons-impl中的服务, 二是使用redis保存HttpSession. 这个模块一共有4个文件: pom.xml, application.yml, WebApplication.java 和 IndexController.java
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <parent>
<groupId>com.rockbb</groupId>
<artifactId>scot</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../scot/pom.xml</relativePath>
</parent>
<artifactId>scot-web</artifactId>
<packaging>jar</packaging>
<name>Scot: Web</name> <dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.rockbb</groupId>
<artifactId>scot-commons-api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies> <build>
<finalName>scot-web</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
server:
port: ${PORT:}
servlet:
session:
timeout: spring:
application:
name: scot-web
session:
store-type: redis
redis:
flush-mode: ON_SAVE
namespace: spring:session redis:
host: 127.0.0.1
port:
database:
password: foobar logging:
pattern:
console: '%d{yyMMdd HH:mm:ssSSS} %8.8thread %1.-1level %25.25logger{50}#%4.4line %msg%n'
level:
com.rockbb: DEBUG eureka:
client:
serviceUrl:
defaultZone: http://localhost:/eureka/
registerWithEureka: false
WebApplication.java
@EnableFeignClients 需要指定 basePackages, 否则不会去jar中扫描
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.rockbb.scot.commons.api"})
@SpringBootApplication
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
}
IndexController.java
这里可以直接Autowire或Resource引用scot-commons的服务.
直接用浏览器访问的话, 返回的格式实际上是根据request header来判断的, 如果要强制返回json格式, 需要加上 produces = "application/json"
@RestController
public class IndexController {
private static Logger logger = LoggerFactory.getLogger(IndexController.class); @Resource
private UserDTOService userDTOService; @RequestMapping(value = "/test1",method = RequestMethod.GET)
public String test1(@RequestParam String name){
logger.debug("/test1");
return userDTOService.diagnos(name);
} @RequestMapping(value = "/test11",method = RequestMethod.GET, produces = "application/json")
public String test11(@RequestParam String name){
return userDTOService.diagnos(name);
} @RequestMapping(value = "/test2",method = RequestMethod.GET)
public UserDTO test2(@RequestParam String id){
return userDTOService.get(id);
} @RequestMapping(value = "/test21",method = RequestMethod.GET, produces = "application/json")
public UserDTO test21(@RequestParam String id){
return userDTOService.get(id);
} @RequestMapping(value = "/test3",method = RequestMethod.GET)
public List<UserDTO> users(@RequestParam String id){
return userDTOService.list();
} @RequestMapping(value = "/test4",method = RequestMethod.GET)
public long users(){
return userDTOService.count();
} @GetMapping("/session")
public String session(HttpSession session) {
return session.getId();
}
}
Feign Client传参的坑
使用Date类型参数会产生14小时的时差
接口使用Date类型时, 会发现服务提供方收到的时间, 比调用方传递的时间要晚14个小时, 例如调用为 Thu Jul 04 19:00:00 CST 2019 收到的为 Fri Jul 05 09:00:00 CST 2019. 原因是服务端将接收的String类型日期转换为Date类型采用的是Date的默认构造器 new Date('Thu Jul 04 19:00:00 CST 2019'), 这里就产生错误了, 因为CTS代表的时区有四个Central Standard Time (USA) UT-6:00、Central Standard Time (Australia) UT+9:30、China Standard Time UT+8:00、Cuba Standard Time UT-4:00, 同时表示美澳中古巴四个国家的标准时间, jvm会将CTS理解成了美国中部时区, 而美国的-6和中国的+8正好相差14个小时.
解决方案:
1. 使用json化的对象传输, 不会有问题
2. 使用long类型的timestamp
3. 使用字符串, 自己做转换
.
Spring Cloud开发实践 - 03 - 接口实现和下游调用的更多相关文章
- Spring Cloud开发实践 - 01 - 简介和根模块
简介 使用Spring Boot的提升主要在于jar的打包形式给运维带来了很大的便利, 而Spring Cloud本身的优点不是那么明显, 相对于Dubbo而言, 可能体现在跨语言的交互性上(例如可以 ...
- Spring Cloud开发实践 - 02 - Eureka服务和接口定义
服务注册 EurekaServer Eureka服务模块只有三个文件, 分别是pom.xml, application.yml 和 EurekaServerApplication.java, 内容如下 ...
- Spring Cloud开发实践 - 04 - Docker部署
Docker的安装和命令可以参考 https://www.cnblogs.com/milton/p/9866963.html . 资源规划 这一步要区分传统资源和Docker资源, 为后面的细节定好基 ...
- Spring Cloud开发人员如何解决服务冲突和实例乱窜?(IP实现方案)
一.背景 在我上一篇文章<Spring Cloud开发人员如何解决服务冲突和实例乱窜?>中提到使用服务的元数据来实现隔离和路由,有朋友问到能不能直接通过IP来实现?本文就和大家一起来讨论一 ...
- Spring Cloud(三):服务提供与调用 Eureka【Finchley 版】
Spring Cloud(三):服务提供与调用 Eureka[Finchley 版] 发表于 2018-04-15 | 更新于 2018-05-07 | 上一篇文章我们介绍了 Eureka 服务 ...
- Spring AOP开发时如何得到某个方法内调用的方法的代理对象?
Spring AOP开发时如何得到某个方法内调用的方法的代理对象? 问题阅读起来拗口,看代码 在方法中调用其他方法很常见,也经常使用,如果在一个方法内部调用其他方法,比如 public class U ...
- Spring cloud项目实践(一)
链接地址:http://sail-y.github.io/2016/03/21/Spring-cloud%E9%A1%B9%E7%9B%AE%E5%AE%9E%E8%B7%B5/ 什么是Spring ...
- spring/spring boot/spring cloud开发总结
背景 针对RPC远程调用,都在使用dubbo.dubbox等,我们也是如此.由于社区暂停维护.应对未来发展,我们准备尝试新技术(或许这时候也不算什么新技术了吧),选择使用了spring ...
- Spring Cloud开发人员如何解决服务冲突和实例乱窜?
一.背景 在我们开发微服务架构系统时,虽然说每个微服务都是孤立的可以单独开发,但实际上并非如此,要调试和测试你的服务不仅需要您的微服务启动和运行,还需要它的上下文服务.依赖的基础服务等都要运行:但如果 ...
随机推荐
- OpenCV教程(46) 快速特征检测
在计算harris特征角时候,我们要在两个方向计算梯度,计算代价有点大.在paper The article by E. Rosten and T. Drummond, Machine lea ...
- 给Spring的placeholder设置默认值
问题:使用Spring时,可以方便地通过placeholder的形式${key}将key对应的properities定义value,注入到Bean中.但是如果在properities文件中,没有对ke ...
- SharePoint2010 对象模型 关联列表
有关列表的创建其实网上已经有很多文章了,其中练习 :利用Visual Studio 2010创建列表这篇文章个人感觉还不错,这里我强调的是对象模型来创建.在这之前我插入一点其他的东东,导入电子表格和数 ...
- [leetcode]Minimum Path Sum @ Python
原题地址:https://oj.leetcode.com/problems/minimum-path-sum/ 题意: Given a m x n grid filled with non-negat ...
- Nginx配置基于多域名、端口、IP的虚拟主机
原文:https://www.cnblogs.com/ssgeek/p/9220922.html ------------------------------- Nginx配置基于多域名.端口.IP的 ...
- 使用phpqrcode生成二维码
使用PHP语言生成二维码,还是挺有难度的,当然调用生成二维码图片的接口(比如:联图网http://www.liantu.com/的接口)除外,如果自己写代码生成,真的无从下手.然而,我们可以使用php ...
- [React] Use React.ReactNode for the children prop in React TypeScript components and Render Props
Because @types/react has to expose all its internal types, there can be a lot of confusion over how ...
- OpenGL ES 3.0顶点着色器(二)
#version es uniform mat4 u_mvpMatrix; in vec4 a_position; in vec4 a_color;out vec4 v_color;void main ...
- springboot升级到2.0后context-path配置不起作用
springboot升级到2.0后,context-path配置不起作用,改成了: server.servlet.context-path=/projname
- Swift 2.x 升为 swift 3后语法不兼容问题适配
[解决方法]设置 Build Settings —-> Use Legacy Swift Language Version —-> 改为YES