Spring Cloud Zuul路由网关服务过滤实现代码

网友投稿 278 2022-12-09


Spring Cloud Zuul路由网关服务过滤实现代码

Zuul 简介

Zuul 的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如 /api/admin 转发到到 Admin 服务,/api/member 转发到到 Member 服务。Zuul 默认和 Ribbon 结合实现了负载均衡的功能。

引入依赖

在 pom.xml 中主要添加 spring-cloud-starter-netflix-eureka-server 和 spring-cloud-starter-netflix-zuul 依赖

org.springframework.cloud

spring-cloud-starter-netflix-eureka-server

org.springframework.cloud

spring-cloud-starter-netflix-zuul

相关配置

在 application.yml 中主要添加 Zuul 路由配置

zuul:

routes:

api-a:

path: /api/ribbon/**

serviceId: hello-spring-cloud-web-admin-ribbon

api-b:

path: /api/feign/**

serviceId: hello-spring-cloud-web-admin-feign

路由说明:

以 /api/ribbon 开头的请求都转发给 spring-cloud-web-admin-ribbon 服务

以 /api/feign 开头的请求都转发给 spring-cloud-web-admin-feign 服务

在 Application 入口类中添加 @EnableZuulProxy 注解开启 zuul 功能

@SpringBootApplication

@EnableEurekaClient

@EnableZuulProxy

public class ZuulApplication {

public static void main(String[] args) {

SpringApplication.run(ZuulApplication.class, args);

}

}

配置网关路由失败时的回调

创建 WebAdminFeignFallbackProvider 回调类

/**

* 路由 hello-spring-cloud-web-admin-feign 失败时的回调

*/

@Component

public class WebAdminFeignFallbackProvider implements FallbackProvider {

@Override

public String getRoute() {

// ServiceId,如果需要所有调用都支持回退,则 return "*" 或 return null

return "hello-spring-cloud-web-admin-feign";

}

/**

* 如果请求服务失败,则返回指定的信息给调用者

* @param route

* @param cause

* @return

*/

@Override

public ClientHttpResponse fallbackResponse(String route, Throwable cause) {

return new ClientHttpResponse() {

/**

* 网关向 api 服务请求失败了,但是消费者客户端向网关发起的请求是成功的,

* 不应该把 api 的 404,500 等问题抛给客户端

* 网关和 api 服务集群对于客户端来说是黑盒

* @return

* @throws IOException

*/

@Override

public HttpStatus getStatusCode() throws IOException {

return HttpStatus.OK;

}

@Override

public int getRawStatusCode() throws IOException {

return HttpStatus.OK.value();

}

@Override

public String getStatusText() throws IOException {

return HttpStatus.OK.getReasonPhrase();

}

@Override

public void close() {

}

@Override

public InputStream getBody() throws IOException {

ObjectMapper objectMapper = new ObjectMapper();

Map map = new HashMap<>();

map.put("status", 200);

map.put("message", "无法连接");

return new ByteArrayInputStream(objectMapper.writeValueAsString(map).getBytes("UTF-8"));

}

@Override

public HttpHeaders getHeaders() {

HttpHeaders headers = new HttpHeaders();

// 和 getBody 中的内容编码一致

headers.setContentType(MediaType.APPLICATION_jsON_UTF8);

return headers;

}

};

}

}

测试路由访问

依次运行 EurekaApplication > ServiceAdminApplication > WebAdminRibbonApplication > WebAdminFeignApplication > ZuulApplication 各服务

访问:http://localhost:8769/api/ribbon/hi?message=zuul

浏览器显示

port : 8763,message : zuul

访问:http://localhost:8769/api/feign/hi?message=zuul

浏览器显示

port : 8763,message : zuul

至此说明 Zuul 的路由功能配置成功。

使用 Zuul 的服务过滤功能

Zuul 不仅仅只是路由,还有很多强大的功能。比如用在安全验证方面。

创建服务过滤器

/**

* Zuul 的服务过滤演示

*/

@Component

public class LoginFilter extends ZuulFilter {

private static final Logger logger = LoggerFactory.getLogger(LoginFilter.class);

/**

* 配置过滤类型,有四种不同生命周期的过滤器类型

* 1. pre:路由之前

* 2. routing:路由之时

* 3. post:路由之后

* 4. error:发送错误调用

* @return

*/

@Override

public String filterType() {

return "pre";

}

/**

* 配置过滤的顺序

* @return

*/

@Override

public int filterOrder() {

return 0;

}

/**

* 配置是否需要过滤:true/需要,false/不需要

* @return

*/

@Override

public boolean shouldFilter() {

return true;

}

/**

* 过滤器的具体业务代码

* @return

* @throws ZuulException

*/

@Override

public Object run() throws ZuulException {

RequestContext context = RequestContext.getCurrentContext();

HttpServletRequest request = context.getRequest();

String token = request.getParameter("token");

if (token == null) {

logger.warn("Token is empty");

context.setSendZuulResponse(false);

context.setResponseStatusCode(401);

try {

context.getResponse().getWriter().write("Token is empty");

} catch (IOException e) {

}

} else {

logger.info("OK");

}

return null;

}

}

测试过滤器

访问:http://localhost:8769/api/feign/hi?message=zuul

网页显示

Token is empty

访问:http://localhost:8769/api/feign/hi?message=zuul&token=1

网页显示

port : 8763,message : zuul


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java 14 发布了,你还会使用Lombok?
下一篇:关于@ResponseBody 默认输出的误区的解答
相关文章

 发表评论

暂时没有评论,来抢沙发吧~