Closed ashleyconnor closed 7 years ago
It should be a "pre" filter and it should run before PreDecorationFilter
. I think setting the requestURI
field in RequestContext
will help. Otherwise spring cloud appends the original path.
The request still makes it to the original destination.
New code:
@Override
public int filterOrder() {
return 4;
}
@Override
public String filterType() {
return "pre";
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
try {
String url = UriComponentsBuilder.fromHttpUrl("http://localhost:8082").path("/outage").build()
.toUriString();
ctx.setRouteHost(new URL(url));
ctx.set("requestURI", url);
} catch(MalformedURLException mue) {
log.error("Cannot forward to outage period endpoint");
}
return null;
}
Breakpoint confirming it's run before PreDecorationFilter
.
What happens in ProxyRequestHelper.buildZuulRequestURI()
?
My guess is that predecorationfilter is still running later. Maybe it needs to happen after predecoration.
Changing the filter to run after PreDecorationFilter
and setting ctx.set("requestURI", url)
worked.
I removed ctx.setRouteHost(new URL(url));
as it doesn't appear to be required.
Final code:
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String url = UriComponentsBuilder.fromHttpUrl("http://localhost:8082").path("/outage").build()
.toUriString();
ctx.set("requestURI", url);
return null;
}
Strange because I had the same need and I succeeded thanks to this post but with ctx.setRouteHost
This solution is not working for me, please help me: My pre filter class code:
@Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest();
System.out.println(
"Request Method : " + request.getMethod() + " Request URL : " + request.getRequestURL().toString());
String body = readRequestBody(request);
String url1 = UriComponentsBuilder.fromHttpUrl("http://localhost:8082").path("/wf-service").path("/_create")
.build().toUriString();
try {
ctx.setRouteHost(new URL(url1));
ctx.set("requestURI", url1);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
requestParser.setReqAsMap(body);
if (requestParser.hasRequestInfo()) {
System.out.println("has req info");
}
return null;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public int filterOrder() {
return 1;
}
@Override
public String filterType() {
return "pre";
}
application.properties
zuul.routes.wf.path=/wf-service/** zuul.routes.wf.stripPrefix=false zuul.routes.wf.url=http://localhost:8082/
The previous answers seems to indicate that the filter needs to be triggered after the PreDecoration.
Have you try to change the filterOrder to:
@Override
public int filterOrder() {
return 6;
}
i change this also now it appending complete url twise { "timestamp": 1510720356916, "status": 404, "error": "Not Found", "message": "No message available", "path": "/wf-service/_createhttp:/localhost:8082/wf-service/_create" }
Worked for me too by changing the FilterOrder to 6. I was trying to prevent routing from happening.And so removed "routeHost" from the RequestContext in the Pre Filter. Thanks @spencergibb
Hi all, trying to achieve the same thing, but the ctx.setRouteHost() actually sends a 302 (Redirect) to my browser, and therefore it is not proxied by Zuul. Any suggestion would be highly appreciated.
This solution is not working for me, please help me: My pre filter class code:
@override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest();
System.out.println( "Request Method : " + request.getMethod() + " Request URL : " + request.getRequestURL().toString()); String body = readRequestBody(request); String url1 = UriComponentsBuilder.fromHttpUrl("http://localhost:8082").path("/wf-service").path("/_create") .build().toUriString(); try { ctx.setRouteHost(new URL(url1)); ctx.set("requestURI", url1); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } requestParser.setReqAsMap(body); if (requestParser.hasRequestInfo()) { System.out.println("has req info"); } return null; } @Override public boolean shouldFilter() { return true; } @Override public int filterOrder() { return 1; } @Override public String filterType() { return "pre"; }
application.properties
zuul.routes.wf.path=/wf-service/** zuul.routes.wf.stripPrefix=false zuul.routes.wf.url=http://localhost:8082/
GhanshyamRawat -> is resolved now? I am also getting same issue.
Changing the filter to run after
PreDecorationFilter
and settingctx.set("requestURI", url)
worked.I removed
ctx.setRouteHost(new URL(url));
as it doesn't appear to be required.Final code:
@Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); String url = UriComponentsBuilder.fromHttpUrl("http://localhost:8082").path("/outage").build() .toUriString(); ctx.set("requestURI", url); return null; }
I did the same but it did not work
Here is my code :
bootstrao.yml:
zuul.routes.cp.path: /navxcp/**
zuul.routes.cp.service-id: navxcp
zuul.routes.web.path: /navx/**
zuul.routes.web.service-id: navxweb
Prefilter:
requestUri = requestUri.replace("navx", "navxcp");
ctx.set(FilterConstants.REQUEST_URI_KEY,requestUri );
log.info("--- request-uri has been modified -> {}",requestUri);
actually I am hitting http://host:port/gateway/navx/getData
Here getData
endpoint is available on navxcp
microservice
So I am trying to change the requestURI
in pre-filter so that it should be routed to navxcp
I found one way to do this.
here is my zuul config:
zuul:
routes:
sevice-demo-b:
path: /b/**
url: http://localhost:5010
sevice-demo-a: /a/**
The filter should be pre
and before PRE_DECORATION_FILTER
the requestUri
attribute can change you uri after preDecorationFilter choose the route, but if you want to change the route, you need use this code request.setAttribute(WebUtils.INCLUDE_REQUEST_URI_ATTRIBUTE, url);
here is the code
public class ChangeUriFilter extends ZuulFilter {
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
}
@Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
final String uri = request.getRequestURI();
return uri.contains("/helloA");
}
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
final HttpServletRequest request = ctx.getRequest();
String uri = "/b/helloB"
// change uri
request.setAttribute(WebUtils.INCLUDE_REQUEST_URI_ATTRIBUTE, url);
return null;
}
}
when you request 'http://host:port/a/helloA', it will forward to http://host:port/b/helloB
😆
I'm trying to forward all requests to my API to a single endpoint based upon some condition.
The
Gateway
app runs on port8080
I've created the following filter:
However after making a request to
http://localhost:8080/alerts/public
my API logs show:For some reason it appends the original PATH to the redirect PATH resulting in a request to
/outage/alerts/public
which doesn't exist. I want to make a request to just/outage
.Putting a breakpoint in my filter just as the
ctx.setRouteHost()
is called shows that correct URL (http://10.50.36.43:8082/outage/
).My
application.properties
: