前文鏈接
[JavaEE] 搭建SpringCloud環(huán)境 進(jìn)入微服務(wù)時(shí)代
http://www.reibang.com/p/a0365a635975
溫馨提示:本文是基于前文的擴(kuò)展 沒(méi)有基礎(chǔ)的新手可以先去學(xué)習(xí)上文
一.簡(jiǎn)介
網(wǎng)關(guān)顧名思義很好理解 就是控制網(wǎng)絡(luò)請(qǐng)求出入的關(guān)卡 生活中參考海關(guān) 有些東西可以通行 但是有些國(guó)家嚴(yán)令禁止的東西 是過(guò)不去海關(guān)的
因?yàn)槲覀兒芎美斫?網(wǎng)關(guān)就是做一下過(guò)濾或攔截
操作 讓我們的服務(wù)更加安全 用戶訪問(wèn)我們服務(wù)的時(shí)候就要先通過(guò)網(wǎng)關(guān) 然后再由網(wǎng)關(guān)轉(zhuǎn)發(fā)到我們的微服務(wù)
二.快速開始
在SpringCloud
全家桶中使用Zuul來(lái)搭建網(wǎng)關(guān) 下面我們就來(lái)創(chuàng)建一個(gè)網(wǎng)關(guān)吧!
之后我們配置一下網(wǎng)關(guān)的配置文件
server:
#服務(wù)端口號(hào)
port: 8085
spring:
application:
#服務(wù)名稱 - 服務(wù)之間使用名稱進(jìn)行通訊
name: service-zuul
eureka:
client:
service-url:
#填寫注冊(cè)中心服務(wù)器地址
defaultZone: http://localhost:8081/eureka
zuul:
routes:
#設(shè)置服務(wù)a 路徑名稱 隨便起
service-a:
path: /service-a/**
#這里寫a服務(wù)的注冊(cè)名字
serviceId: service-objcat-a
#設(shè)置服務(wù)b 路徑名稱 隨便起
service-b:
path: /service-b/**
#這里寫b服務(wù)的注冊(cè)名字
serviceId: service-objcat-b
之后創(chuàng)建一個(gè)包 名字是com.objcat.filter
創(chuàng)建一個(gè)類TokenFilter
用來(lái)實(shí)現(xiàn)過(guò)濾規(guī)則
類需要繼承于ZuulFilter
之后我們重寫ZuulFilter
中的方法
/**
* 過(guò)濾器類型 pre表示在請(qǐng)求之前進(jìn)行邏輯操作
*/
@Override
public String filterType() {
return "pre";
}
/**
* 過(guò)濾器執(zhí)行順序
* 當(dāng)一個(gè)請(qǐng)求在同一個(gè)階段存在多個(gè)過(guò)濾器的時(shí)候 過(guò)濾器的執(zhí)行順序
*/
@Override
public int filterOrder() {
return 0;
}
/**
* 是否開啟過(guò)濾
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 編寫過(guò)濾器攔截業(yè)務(wù)邏輯代碼
*/
@Override
public Object run() {
return null;
}
然后我們開始寫過(guò)濾的邏輯
/**
* 編寫過(guò)濾器攔截業(yè)務(wù)邏輯代碼
*/
@Override
public Object run() {
RequestContext currentContext = RequestContext.getCurrentContext();
HttpServletRequest request = currentContext.getRequest();
String token = request.getParameter("token");
if (token == null) {
currentContext.setSendZuulResponse(false);
currentContext.setResponseBody("token is null");
currentContext.setResponseStatusCode(401);
}
return null;
}
邏輯很簡(jiǎn)單 就是校驗(yàn)客戶端發(fā)來(lái)的請(qǐng)求token是否為空 如果為空就不能通過(guò) 返回 token is null
之后我們配置一下入口文件 這個(gè)地方千萬(wàn)不要忘記實(shí)例化出來(lái)filter
否則不生效
package com.objcat.servicezuul;
import com.objcat.filter.TokenFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ServiceZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceZuulApplication.class, args);
}
@Bean
TokenFilter tokenFilter() {
return new TokenFilter();
}
}
之后我們來(lái)運(yùn)行服務(wù)試試吧
我們可以清晰的看到 我訪問(wèn)a服務(wù) 只需要使用 網(wǎng)關(guān)的地址 + 網(wǎng)關(guān)的端口號(hào) + 服務(wù)的別名路徑(配置文件中配置) + api名稱
就可以訪問(wèn)了
http://localhost:8085/service-a/hello
當(dāng)沒(méi)有token的時(shí)候返回就是 token is null
當(dāng)token有值的時(shí)候就可以正常進(jìn)行訪問(wèn)了
然后我們來(lái)嘗試訪問(wèn)以下service-a的原地址
這次有些人可能會(huì)有疑問(wèn) 這個(gè)不用token就可以訪問(wèn)嗎??
沒(méi)錯(cuò) 聰明的你應(yīng)該已經(jīng)看出來(lái)了 這個(gè)請(qǐng)求并沒(méi)有經(jīng)過(guò)網(wǎng)關(guān)轉(zhuǎn)發(fā) 是直接訪問(wèn)到目標(biāo)服務(wù)器的 所以并沒(méi)有做token驗(yàn)證
這種網(wǎng)關(guān)轉(zhuǎn)發(fā)之后的請(qǐng)求 就叫做
反向代理
你可以隱藏你本地的服務(wù)器的真實(shí)地址 只暴露給外界網(wǎng)關(guān)的地址 然后由網(wǎng)關(guān)轉(zhuǎn)發(fā)給服務(wù)器 從而做到安全性更高
好了 到這里網(wǎng)關(guān)配置已經(jīng)完成了.