本篇文章給大家帶來的內容是關於使用Spring Cloud Netflix Zuul代理網關訪問後台REST服務的實現(代碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所協助。
1.概述
在本文中,我們將探討如何在互相單獨部署的前端應用程式和後端REST API服務之間進行通訊。目的是解決瀏覽器的跨域資源訪問和同源策略限制,允許頁面UI能夠調用背景API,即使它們不在同一個伺服器中。
我們在這裡建立了兩個獨立的應用程式 - 一個UI應用程式和一個簡單的REST API,我們將在UI應用程式中使用Zuul代理來代理對REST API的調用。Zuul是Netflix基於JVM的路由器和伺服器端負載平衡器。Spring Cloud與嵌入式Zuul代理有很好的整合。
2.REST應用
我們的REST API應用程式是一個簡單的Spring Boot應用程式。在本文中將在連接埠8081上運行伺服器中部署的API 。
設定檔
server.contextPath=/spring-zuul-foos-resourceserver.port=8081
讓我們首先為我們將要使用的資源定義基本DTO:
public class Foo { private long id; private String name; // standard getters and setters }
定義一個簡單的控制器:
@Controllerpublic class FooController { @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}") @ResponseBody public Foo findById( @PathVariable long id, HttpServletRequest req, HttpServletResponse res) { return new Foo(Long.parseLong(randomNumeric(2)), randomAlphabetic(4)); }}
3. 前端應用程式
我們的UI應用程式也是一個簡單的Spring Boot應用程式。在本文中此應用運行在連接埠8080上。
首先,我們需要通過Spring Cloud向我們的UI應用程式的pom.xml添加對zuul支援的依賴:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency>
接下來 - 我們需要配置Zuul,因為我們正在使用Spring Boot,所以我們將在application.yml中執行此操作:
zuul: routes: foos: path: /foos/** url: http://localhost:8081/spring-zuul-foos-resource/foos
注意:
然後編寫我們的首頁面index.html — 這裡使用一些AngularJS:
<html><body ng-app="myApp" ng-controller="mainCtrl"><script src="angular.min.js"></script><script src="angular-resource.min.js"></script><script>var app = angular.module('myApp', ["ngResource"]);app.controller('mainCtrl', function($scope,$resource,$http) { $scope.foo = {id:0 , name:"sample foo"}; $scope.foos = $resource("/foos/:fooId",{fooId:'@id'}); $scope.getFoo = function(){ $scope.foo = $scope.foos.get({fooId:$scope.foo.id}); } });</script><p> <h1>Foo Details</h1> <span>{{foo.id}}</span> <span>{{foo.name}}</span> <a href="#" ng-click="getFoo()">New Foo</a> </p> </body> </html>
這裡最重要的方面是我們如何使用相對URL訪問API !
請記住,API應用程式未部署在與UI應用程式相同的伺服器上,因此相對URL不起作用,並且在沒有代理的情況下不起作用。
但是,通過代理,我們通過Zuul代理訪問Foo資源,Zuul代理配置為將這些請求路由到實際部署API的位置。
最後,啟用Boot的應用程式:
@EnableZuulProxy@SpringBootApplicationpublic class UiApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(UiApplication.class, args); }}
這裡使用@EnableZuulProxy註解來啟動Zuul代理,這非常乾淨和簡潔。
4.運行測試
分別啟動2個應用系統,在瀏覽器中輸入http://localhost:8080/index
每點擊一次“New Foo”按鈕就訪問後台REST API一次。
5.定製Zuul過濾器
有多個Zuul過濾器可用,我們也可以建立自己的定製過濾器:
@Componentpublic class CustomZuulFilter extends ZuulFilter { @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); ctx.addZuulRequestHeader("Test", "TestSample"); return null; } @Override public boolean shouldFilter() { return true; } // ...}
這個簡單的過濾器只是在要求標頭中添加了一個名為“ Test ” 的屬性- 當然,我們可以根據需要增加我們的請求。
6.測試自訂Zuul過濾器
最後,讓我們測試一下,確保我們的自訂過濾器正常工作 - 首先我們將在Foos資原始伺服器上修改我們的FooController:
@Controllerpublic class FooController { @GetMapping("/foos/{id}") @ResponseBody public Foo findById( @PathVariable long id, HttpServletRequest req, HttpServletResponse res) { if (req.getHeader("Test") != null) { res.addHeader("Test", req.getHeader("Test")); } return new Foo(Long.parseLong(randomNumeric(2)), randomAlphabetic(4)); }}
現在 - 讓我們測試一下:
@Testpublic void whenSendRequest_thenHeaderAdded() { Response response = RestAssured.get("http://localhost:8080/foos/1"); assertEquals(200, response.getStatusCode()); assertEquals("TestSample", response.getHeader("Test"));}
7.結論
在這篇文章中,我們專註於使用Zuul將請求從UI應用程式路由到REST API。我們成功地解決了CORS和同源策略,我們還設法定製和擴充了傳輸中的HTTP請求。