api-gateway-netflix-zuul
DerekYRC 2 years ago
parent c8fc5e389c
commit e36e635db7

@ -2,6 +2,8 @@ package com.github.cloud.netflix.zuul;
import java.util.Map;
import com.github.cloud.netflix.zuul.filters.RouteLocator;
import com.github.cloud.netflix.zuul.filters.SimpleRouteLocator;
import com.github.cloud.netflix.zuul.filters.ZuulProperties;
import com.github.cloud.netflix.zuul.filters.post.SendResponseFilter;
import com.github.cloud.netflix.zuul.filters.pre.PreDecorationFilter;
@ -17,6 +19,7 @@ import com.netflix.zuul.monitoring.TracerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -39,20 +42,25 @@ public class ZuulServerAutoConfiguration {
return new ServletRegistrationBean<>(new ZuulServlet(), zuulProperties.getServletPath());
}
@Bean
public RouteLocator simpleRouteLocator() {
return new SimpleRouteLocator(zuulProperties);
}
/**
* preRouteLocator
*/
@Bean
public ZuulFilter preDecorationFilter() {
return new PreDecorationFilter();
public ZuulFilter preDecorationFilter(RouteLocator routeLocator) {
return new PreDecorationFilter(routeLocator);
}
/**
* route使ribbonhttp
*/
@Bean
ZuulFilter ribbonRoutingFilter() {
return new RibbonRoutingFilter();
ZuulFilter ribbonRoutingFilter(LoadBalancerClient loadBalancerClient) {
return new RibbonRoutingFilter(loadBalancerClient);
}
/**

@ -0,0 +1,35 @@
package com.github.cloud.netflix.zuul.filters;
/**
*
* @author derek()
* @date 2022/6/28
*/
public class Route {
private String path;
private String location;
public Route(String path, String location) {
this.path = path;
this.location = location;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}

@ -0,0 +1,16 @@
package com.github.cloud.netflix.zuul.filters;
/**
*
* @author derek()
* @date 2022/6/28
*/
public interface RouteLocator {
/**
*
* @param path
* @return
*/
Route getMatchingRoute(String path);
}

@ -0,0 +1,35 @@
package com.github.cloud.netflix.zuul.filters;
import java.util.Map;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
/**
*
* @author derek()
* @date 2022/6/28
*/
public class SimpleRouteLocator implements RouteLocator {
private ZuulProperties zuulProperties;
private PathMatcher pathMatcher = new AntPathMatcher();
public SimpleRouteLocator(ZuulProperties zuulProperties) {
this.zuulProperties = zuulProperties;
}
@Override
public Route getMatchingRoute(String path) {
for (Map.Entry<String, ZuulProperties.ZuulRoute> entry : zuulProperties.getRoutes().entrySet()) {
ZuulProperties.ZuulRoute zuulRoute = entry.getValue();
String pattern = zuulRoute.getPath();
if (pathMatcher.match(pattern, path)) {
return new Route(path, zuulRoute.getServiceId());
}
}
return null;
}
}

@ -1,6 +1,11 @@
package com.github.cloud.netflix.zuul.filters.post;
import java.io.OutputStream;
import javax.servlet.http.HttpServletResponse;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import static com.github.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;
@ -25,11 +30,21 @@ public class SendResponseFilter extends ZuulFilter {
@Override
public boolean shouldFilter() {
return true;
RequestContext requestContext = RequestContext.getCurrentContext();
return requestContext.getResponseDataStream() != null;
}
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletResponse servletResponse = requestContext.getResponse();
if (servletResponse.getCharacterEncoding() == null) {
servletResponse.setCharacterEncoding("UTF-8");
}
OutputStream outStream = servletResponse.getOutputStream();
return null;
}
}

@ -1,9 +1,16 @@
package com.github.cloud.netflix.zuul.filters.pre;
import com.github.cloud.netflix.zuul.filters.Route;
import com.github.cloud.netflix.zuul.filters.RouteLocator;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.github.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static com.github.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY;
import static com.github.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY;
/**
* preRouteLocator
@ -12,6 +19,13 @@ import static com.github.cloud.netflix.zuul.filters.support.FilterConstants.PRE_
* @date 2022/6/27
*/
public class PreDecorationFilter extends ZuulFilter {
private static Logger logger = LoggerFactory.getLogger(PreDecorationFilter.class);
private RouteLocator routeLocator;
public PreDecorationFilter(RouteLocator routeLocator) {
this.routeLocator = routeLocator;
}
@Override
public String filterType() {
@ -30,6 +44,18 @@ public class PreDecorationFilter extends ZuulFilter {
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
String requestURI = requestContext.getRequest().getRequestURI();
//获取匹配的路由
Route route = routeLocator.getMatchingRoute(requestURI);
if (route != null) {
requestContext.put(REQUEST_URI_KEY, route.getPath());
requestContext.set(SERVICE_ID_KEY, route.getLocation());
}
else {
logger.error("获取不到匹配的路由, requestURI: {}", requestContext);
}
return null;
}
}

@ -1,9 +1,25 @@
package com.github.cloud.netflix.zuul.filters.route;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import static com.github.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY;
import static com.github.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE;
import static com.github.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY;
/**
* route使ribbonhttp
@ -12,6 +28,13 @@ import static com.github.cloud.netflix.zuul.filters.support.FilterConstants.ROUT
* @date 2022/6/27
*/
public class RibbonRoutingFilter extends ZuulFilter {
private static Logger logger = LoggerFactory.getLogger(RibbonRoutingFilter.class);
private LoadBalancerClient loadBalancerClient;
public RibbonRoutingFilter(LoadBalancerClient loadBalancerClient) {
this.loadBalancerClient = loadBalancerClient;
}
@Override
public String filterType() {
@ -25,11 +48,39 @@ public class RibbonRoutingFilter extends ZuulFilter {
@Override
public boolean shouldFilter() {
return true;
RequestContext requestContext = RequestContext.getCurrentContext();
return requestContext.get(SERVICE_ID_KEY) != null;
}
@Override
public Object run() throws ZuulException {
return null;
RequestContext requestContext = RequestContext.getCurrentContext();
String serviceId = (String) requestContext.get(SERVICE_ID_KEY);
String requestURI = (String) requestContext.get(REQUEST_URI_KEY);
HttpServletRequest request = requestContext.getRequest();
String method = request.getMethod();
ServletInputStream inputStream = null;
try {
inputStream = request.getInputStream();
}
catch (IOException e) {
logger.error("获取输入流失败", e);
}
//TODO 构造请求
LoadBalancerRequest<ClientHttpResponse> loadBalancerRequest = null;
ClientHttpResponse response = loadBalancerClient.execute(serviceId, loadBalancerRequest);
int statusCode = response.getRawStatusCode();
InputStream responseBody = response.getBody();
requestContext.setResponseStatusCode(statusCode);
requestContext.setResponseDataStream(responseBody);
return response;
}
}

@ -8,6 +8,9 @@ package com.github.cloud.netflix.zuul.filters.support;
*/
public interface FilterConstants {
String REQUEST_URI_KEY = "requestURI";
String SERVICE_ID_KEY = "serviceId";
//过滤器类型常量-----------------------------------
String PRE_TYPE = "pre";

Loading…
Cancel
Save