新聞中心
而http調(diào)用通常都是使用httpclient等相關(guān)類庫(kù),這些在使用上并沒(méi)有問(wèn)題,但API都是分散在整個(gè)工程的各個(gè)地方,如果HTTP調(diào)用也可以使用類似Dubbo服務(wù)的表示方法,采用聲明式定義就好了。

10年積累的成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有天峻免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
在開源的世界中只有想不到,沒(méi)有找不到,為了解決Feign的聲明式服務(wù)化管理,F(xiàn)eign框架應(yīng)運(yùn)而生,本文主要介紹如何使用Feign實(shí)現(xiàn)Http服務(wù)聲明化管理與調(diào)用。
1.什么是Feign
Feign是一個(gè)http請(qǐng)求調(diào)用的輕量級(jí)框架,可以以Java接口注解的方式調(diào)用Http請(qǐng)求。Feign通過(guò)注解,將請(qǐng)求模板化,當(dāng)實(shí)際調(diào)用的時(shí)候,傳入?yún)?shù),根據(jù)參數(shù)再應(yīng)用到請(qǐng)求上,進(jìn)而轉(zhuǎn)化成真正的請(qǐng)求,封裝了http調(diào)用流程。
2、快速入門實(shí)例
2.1定義客戶端
首先要引入Feign的maven依賴,如下圖所示:
com.netflix.feign
feign-core
8.18.0
2.2 定義服務(wù)調(diào)用API(類似Dubbo API)
服務(wù)調(diào)用的API聲明代碼如下所示:
@FeignClient
public interface HelloControllerApi {
@RequestLine("GET /api/hello?name={name}")
String hello(@Param(value = "name") String name);
}
這里的要點(diǎn)是使用@FeignClient進(jìn)行聲明。聲明后就可以通過(guò)HelloControllerApi進(jìn)行遠(yuǎn)程HTTP調(diào)用,示例代碼如下:
public class HelloControllerApiTest {
private HelloControllerApi service;
@Before
public void before(){
service = Feign.builder()
.options(new Request.Options(1000, 3500))
.retryer(new Retryer.Default(5000, 5000, 3))
.target(HelloControllerApi.class, "http://127.0.0.1:8080");
}
@Test
public void hello(){
// 調(diào)用http://127.0.0.1:8080/api/hello?name=world 的http接口
System.out.println(service.hello("world"));
}
}當(dāng)然需要在調(diào)用方的啟動(dòng)類上增加@EnableFeignClients(defaultConfiguration = FeignConfiguration.class)注解。
2.3定義服務(wù)端
服務(wù)端與Feign并無(wú)關(guān)系,主要按照API的方式實(shí)現(xiàn)即可,服務(wù)端實(shí)現(xiàn)代碼如下所示:
@Controller
@RequestMapping(value = "api")
public class HelloController {
@RequestMapping(value = "/hello", method = {RequestMethod.GET})
@ResponseBody
public String list(@RequestParam String name) {
return "Hello " + name;
}
}
//啟動(dòng)類
@SpringBootApplication(scanBasePackages = {"com.vhicool.manager"})
public class ManagerApplication {
public static void main(String[] args) {
SpringApplication.run(ManagerApplication.class, args);
}
}
3.實(shí)現(xiàn)簽名校驗(yàn)
上述只是簡(jiǎn)單實(shí)用Feign,接下來(lái)以實(shí)現(xiàn)簽名校驗(yàn)為例展示Feign的擴(kuò)展機(jī)制。
簽名驗(yàn)證是最常見的安全機(jī)制,首先在客戶端定義一個(gè)簽名攔截器,用于生成簽名信息,示范代碼如下圖所示:
public class AuthRequestInterceptor implements feign.RequestInterceptor {
private TokenService tokenService;
public AuthRequestInterceptor(TokenService tokenService) {
this.tokenService = tokenService;
}
@Override
public void apply(RequestTemplate template) {
template.header("token", tokenService.getToken());
}
}并且在Feign的全局配置文件中創(chuàng)建對(duì)應(yīng)的攔截器,示例代碼如下:
public class FeignConfiguration {
@Bean
public RequestInterceptor authRequestInterceptor(ResourceIdentity resourceIdentity) {
AuthRequestInterceptor authRequestInterceptor = new AuthRequestInterceptor(resourceIdentity);
authRequestInterceptor.setErrorEncodeType(errorEncodeType);
return authRequestInterceptor;
}
}同時(shí)在服務(wù)端獲取token并對(duì)token進(jìn)行校驗(yàn),示例代碼如下:
@Component
public class AuthFilter implements Filter {
@Autowired
private TokenService tokeService;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String remoteToken = ((HttpServletRequest) servletRequest).getHeader("token");
if(!tokeService.valid(token)) {
//異常處理邏輯
return;
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
4.服務(wù)端自動(dòng)生成Feign
上面的示例雖然實(shí)現(xiàn)了服務(wù)接口的聲明式管理,但調(diào)用端、客戶端并沒(méi)有顯示的約束關(guān)系,接下來(lái)展示如何使用客戶端、服務(wù)端使用繼承方式定義服務(wù)調(diào)用API。
例如要實(shí)現(xiàn)如下圖的效果:
原生的Feign無(wú)法實(shí)現(xiàn)該效果,我們需要使用OpenFeign類庫(kù),兩者之間的對(duì)比如下圖所示:
接下來(lái)詳細(xì)介紹具體實(shí)現(xiàn)方法。
4.1 提取公共API
首先使用一個(gè)模塊定義公共API,需要引入maven依賴,代碼示例如下所示:
org.springframework.boot
spring-boot-starter-web
接下來(lái)定義公共的服務(wù)接口,客戶端、服務(wù)端都需要實(shí)現(xiàn)該接口,公共服務(wù)端接口定義如下:
public interface IUserController {
@RequestMapping(value = "user/list-all", method = {RequestMethod.GET})
List listAll(@RequestParam String name);
} 4.2 服務(wù)端實(shí)現(xiàn)公共API
首先需要添加相應(yīng)的maven依賴,代碼如下:
org.springframework.boot
spring-boot-starter-web
com.vhicool
feign-api
1.0-SNAPSHOT
compile
服務(wù)端采用繼承方式實(shí)現(xiàn),具體代碼如下所示:
@Controller
@RequestMapping
public class UserController implements IUserController {
@Override
@ResponseBody
public ListlistAll(String name) {
ArrayListlist = new ArrayList<>();
list.add("達(dá)菲");
list.add("olu");
list.add(name);
return list;
}
}
4.3 客戶端實(shí)現(xiàn)公共API
客戶端首先同樣需要增加相應(yīng)的依賴,具體代碼如下所示:
org.springframework.cloud
spring-cloud-starter-openfeign
2.1.5.RELEASE
junit
junit
4.12
compile
com.vhicool
feign-api
1.0-SNAPSHOT
compile
客戶端服務(wù)調(diào)用類需要繼承公共API:
@FeignClient(value = "user", url = "http://localhost:8080")
public interface UserApi extends IUserController {
}
同時(shí)客戶端啟動(dòng)類需要增加@EnableFeignClients注解,具體示例代碼如下所示:
@SpringBootApplication
@EnableFeignClients
public class ManagerApplication {
public static void main(String[] args) {
SpringApplication.run(ManagerApplication.class, args);
}
}
同樣基于Springboot編程方式,可以為Feign配置全局參數(shù),具體如下:
@Configuration
public class FeignConfiguration {
/**
* 請(qǐng)求超時(shí)時(shí)間
* @return
*/
@Bean
public Request.Options options() {
return new Request.Options(2000, 3500);
}
//攔截器等定義
}
接下來(lái)客戶端就可以用如下方式進(jìn)行調(diào)用:
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserControllerTest {
@Autowired
private UserApi userApi;
@Test
public void listAll() {
System.out.println(userApi.listAll("餅餅"));
}
}
時(shí),當(dāng)前項(xiàng)目編譯的jar包,類也已經(jīng)被替換成我們自定義的類,目標(biāo)達(dá)成。
作者介紹:李大偉,現(xiàn)任中通快遞中間件高級(jí)架構(gòu)師,對(duì)消息中間件、Flink有著非常豐富的實(shí)踐經(jīng)驗(yàn)。
標(biāo)題名稱:聊聊Http服務(wù)化改造實(shí)踐
文章起源:http://www.dlmjj.cn/article/cosodpo.html


咨詢
建站咨詢
