如何结合RedirectView与ClientHttpRequestInterceptor拦截重定向
Hey there! Let's break down your problem clearly first: ClientHttpRequestInterceptor only works for HTTP requests your application sends as a client (like calls via RestTemplate or WebClient). But RedirectView generates a server-side redirect response (think 302/301 status codes sent to the browser), which is entirely outside the scope of client-side request interception. That's why it's not catching those redirects.
Here are the practical solutions you're looking for:
1. Use Spring's HandlerInterceptor (Server-Side Interception)
This is the perfect tool for intercepting server-side redirects—including those created by RedirectView. It hooks into your app's request processing lifecycle, letting you catch and handle redirects before they're sent to the client.
Step 1: Implement the Interceptor
Create a class that implements HandlerInterceptor (skip the deprecated HandlerInterceptorAdapter):
@Component public class RedirectTrackingInterceptor implements HandlerInterceptor { @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // Check for redirect status codes if (isRedirectStatus(response.getStatus())) { String redirectTarget = response.getHeader("Location"); // Add your custom logic here: log, validate, modify the URL, etc. System.out.println("Intercepted server-side redirect to: " + redirectTarget); } // Directly detect RedirectView instances if (modelAndView != null && modelAndView.getView() instanceof RedirectView) { RedirectView redirectView = (RedirectView) modelAndView.getView(); String redirectUrl = redirectView.getUrl(); // Handle RedirectView-specific redirects here System.out.println("Intercepted RedirectView redirect to: " + redirectUrl); } } private boolean isRedirectStatus(int statusCode) { return statusCode == HttpServletResponse.SC_FOUND // 302 || statusCode == HttpServletResponse.SC_MOVED_PERMANENTLY // 301 || statusCode == HttpServletResponse.SC_TEMPORARY_REDIRECT; // 307 } }
Step 2: Register the Interceptor
Add it to your Spring MVC config to apply it to all requests:
@Configuration public class WebMvcConfig implements WebMvcConfigurer { private final RedirectTrackingInterceptor redirectInterceptor; // Constructor injection (cleaner than @Autowired) public WebMvcConfig(RedirectTrackingInterceptor redirectInterceptor) { this.redirectInterceptor = redirectInterceptor; } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(redirectInterceptor) .addPathPatterns("/**"); // Apply to all request paths } }
2. When Would ClientHttpRequestInterceptor Catch Redirects?
If your goal was to intercept redirects that your app follows as a client (e.g., RestTemplate calls an external API that returns a 302, and RestTemplate automatically makes the follow-up request), then ClientHttpRequestInterceptor does work—it will intercept every request in the redirect chain. Just ensure your RestTemplate is set to follow redirects (this is the default behavior).
But since you're using RedirectView, this scenario doesn't apply to your current use case.
3. Alternative Redirect Approach (If You Need Client-Side Interception)
If you absolutely need to use ClientHttpRequestInterceptor for redirects, you'd have to shift from server-side redirects to having your app act as a client:
- Instead of returning a
RedirectView, useRestTemplateto call the target URL directly, then return the response to the client. This way, theRestTemplaterequest (and any redirects it follows) will be intercepted byClientHttpRequestInterceptor. - Note: This adds an extra server hop, so it's not ideal for user-facing redirects, but it's an option if your use case requires it.
内容的提问来源于stack exchange,提问作者smithzo622

