I am using ZUUL APIGateway and there is a requirement to redirect user to other site and open the new url in browser. what is the best way ?
It's a custom filter with either response.sendRedirect() or a 30x response code with a Location header https://en.wikipedia.org/wiki/URL_redirection#HTTP_status_codes_3xx
I tried response.sendRedirect and it is appending the google.com in current URL. http://localhost:8080/www.google.com. am I doing something wrong ?
Use a full url, http:// included. If not use the 30x response code and Location header.
Very glad I found this, been struggling to do it all morning. I assumed a "route" filter would work, but it doesn't appear to be executed at all. I enabled logging DEBUG at the root (copious amounts of output), but nothing there. Even the shouldFilter() does not appear to be executed.
package mypackage;
/*
* simple filter to handle default route
*/
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Value;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.ZuulFilter;
@Component
public class DefaultRedirectFilter extends ZuulFilter {
private static final Log log = LogFactory.getLog(DefaultRedirectFilter.class);
@Value("${zuul.defaultRoute}")
private String defaultRoute;
@Override
public String filterType() {
return "route";
}
@Override
public int filterOrder() {
return 1;
}
// only run if we have a default route defined and we are on the default
@Override
public boolean shouldFilter() {
String requestURI = RequestContext.getCurrentContext().getRequest().getRequestURI();
if (log.isDebugEnabled()) {
log.debug("defaultRoute=" + defaultRoute);
log.debug("requestURI=" + requestURI);
}
return defaultRoute != null && requestURI.matches("/");
}
@Override
public Object run() {
if (log.isDebugEnabled()) {
log.debug("DefaultRedirectFilter: sending redirect " + defaultRoute);
}
try {
RequestContext.getCurrentContext().getResponse().sendRedirect(defaultRoute);
} catch (java.io.IOException e) {
// not sure what to do
if (log.isDebugEnabled()) {
log.debug("run: IOException on sendRedirect() " + e);
}
}
//if (HTTPRequestUtils.getInstance().getQueryParams() == null) {
// RequestContext.getCurrentContext().setRequestQueryParams(new HashMap<String, List<String>>());
//}
return null;
}
}
@deitch have a look at https://stackoverflow.com/a/44771361/936416
Thanks @tine2k
I enabled debug mode, looks like it doesn't find a match in the declared routes (correctly), or RequestMapping (correctly), but then does with the static. Well, not exactly. It does not find with static (we have no files in there), but that causes it to return a 404, which, in turn doesn't get to here.
So my question then becomes: do filters (pre, route, post, error) get executed if no route matches in the declared zuul.routes?
no they don't
We have a similar situation. When there is no route match, is there an option to do some custom processing. We are trying to avoid returning 404 for certain critical URLs (the routes for which may not be available all the time)
@madheshr please keep the comments to one issue. This question is about redirects and you've already opened an issue with your question.
@deitch You DefaultRedirectFilter works as a charm, however I have the following exception after such redirection:
com.netflix.zuul.exception.ZuulException: Filter threw Exception
... 74 common frames omitted
Caused by: java.io.IOException: UT010029: Stream is closed
at io.undertow.servlet.spec.ServletOutputStreamImpl.write(ServletOutputStreamImpl.java:136)
at org.springframework.cloud.sleuth.instrument.web.TraceServletOutputStream.write(TraceServletOutputStream.java:120)
at org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter.writeResponse(SendResponseFilter.java:219)
at org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter.writeResponse(SendResponseFilter.java:188)
at org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter.run(SendResponseFilter.java:117)
... 76 common frames omitted
Here is a little hack to avoid this (setting exception on RequestContext to disable SendResponseFilter):
@Override
public Object run() {
if (log.isDebugEnabled()) {
log.debug("DefaultRedirectFilter: sending redirect " + defaultRoute);
}
try {
RequestContext.getCurrentContext().getResponse().sendRedirect(defaultRoute);
RequestContext.getCurrentContext().setThrowable(new RuntimeException()); // fake, to prevent from trying to write to this response in SendResponseFilter
} catch (java.io.IOException e) {
// not sure what to do
if (log.isDebugEnabled()) {
log.debug("run: IOException on sendRedirect() " + e);
}
}
return null;
}
Thanks. I鈥檓 (thankfully) long past this one. Hoping not to have to touch it again. :-)
Hi is there any easy way to redirect my request to a new path within the same service without using custom filters?
zuul:
routes:
events:
path: /api/v1/test/**
serviceId: TESTSERVICE
If a request comes to this path "api/v1/test/" , I would like to forward it to "api/v1/latesttest/".
Thanks in Advance
Thanks deitch. You saved my day. The solution worked for me. Thanks a lot. Hare Krishna
I am glad it helped @sandeeptiet .
Closing due to age of the question. If you would like us to look at this issue, please comment and we will look at re-opening the issue.
Most helpful comment
Very glad I found this, been struggling to do it all morning. I assumed a
"route"filter would work, but it doesn't appear to be executed at all. I enabled loggingDEBUGat the root (copious amounts of output), but nothing there. Even theshouldFilter()does not appear to be executed.