title: How I get the HandlerMethod matchs a HttpServletRequest in a Filter
body: <p>I'm writing a simple proxy app, and want mapped url will be handled by my controller, but other url (includes error) can be forwarded to another different address. So I use <code>Filter</code> rather than <code>HandlerInterceptorAdapter</code> that cannot be invoked if the resourece is not found because certain "resourece path handler" deals it.</p>
  
  <p><strong>Expectation</strong></p>
  
  <p><code>http://localhost:8090/upload.html</code> > <code>Filter</code> > <code>http://localhost:8092/upload.html</code><br>
  <code>http://localhost:8090/files/upload</code> > <code>Controller</code> > <code>http://localhost:8092/files/upload</code></p>
  
  <p><strong>Not</strong></p>
  
  <p><code>http://localhost:8090/upload.html</code> > <code>Filter</code> > <code>http://localhost:8092/upload.html</code><br>
  <code>http://localhost:8090/files/upload</code> > <code>Controller</code> > <code>http://localhost:8092/files/upload</code></p>
  
  <p>Or</p>
  
  <p><code>http://localhost:8090/upload.html</code> > <code>Interceptor</code> > <code>http://localhost:8090/error</code> Not found 
  <code>http://localhost:8090/files/upload</code> > <code>Filter</code> > <code>http://localhost:8092/files/upload</code></p>
  
  <p><strong>Demo</strong></p>
  
  <p>I set up a <code>Filter</code> in my subclass of <code>WebMvcConfigurerAdapter</code>.</p>
  
  <pre><code>@Configuration
  @EnableWebMvc
  public class WebConfig extends WebMvcConfigurerAdapter {
  
      @Bean
      private javax.servlet.Filter proxyFilter() {
          return new OncePerRequestFilter() {
              @Override
              protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
                  System.out.println("[doFilterInternal]isCommitted=" + response.isCommitted() + ", URI = " + request.getRequestURI());
                  // if(!isRequestMappedInController(request, "my.pakcage"))
                  httpProxyForward(request, response);
              }
          };
      }
  
  //    @Bean
  //    private FilterRegistrationBean loggingFilterRegistration() {
  //        FilterRegistrationBean registration = new FilterRegistrationBean(proxyFilter());
  //        registration.addUrlPatterns("/**");
  //        return registration;
  //    }
  
      Override
      public void addInterceptors(InterceptorRegistry registry) {
          registry.addInterceptor(new HandlerInterceptorAdapter() {
              @Override
              public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                  // How I determine a controller has handled the request in my interceptor?
                  if (handler instanceof HandlerMethod) {
                      HandlerMethod handlerMethod = ((HandlerMethod) handler);
                      if (handlerMethod.getMethod().getDeclaringClass().getName().startsWith("nxtcasb.casbproxy")) {
                          System.out.println("[preHandle]dealt: request uri = " + request.getRequestURI() + ", HandlerMethod = " + ((HandlerMethod) handler).getMethod());
                          return true;
                      } else {
                          System.out.println("[preHandle]isCommitted=" + response.isCommitted() + ", HandlerMethod = " + ((HandlerMethod) handler).getMethod());
                      }
                  }
                  // act as an api-gateway
                  System.out.println("[preHandle]undealt: request uri = " + request.getRequestURI() + ", handler = " + handler);
  
                  //ModelAndView modelView = new ModelAndView("redirect: http://www.bing.com");
                  //throw new ModelAndViewDefiningException(modelView);
                  httpProxyForward(request, response);
                  return false;
              }
  
              @Override
              public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
                  if (handler instanceof HandlerMethod) {
                      System.out.println("[postHandle]dealt: uri = " + request.getRequestURI() + ", handler = " + ((HandlerMethod) handler).getMethod());
                  } else {
                      System.out.println("[postHandle]undealt uri = " + request.getRequestURI() + ", handler = " + handler);
                  }
              }
          }).addPathPatterns("/**", "/error");
      }
  
      /**
       * this is the same as  &lt;mvc:default-servlet-handler/&gt; &lt;!-- This tag allows for mapping the DispatcherServlet to "/" --&gt;
       *
       * @param configurer
       */
      @Override
      public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
          configurer.enable();
      }
  
      @Override
      public void addResourceHandlers(ResourceHandlerRegistry registry) {
          //registry.addResourceHandler("/**").addResourceLocations("classpath:/public");
      }
  
      protected void httpProxyForward(HttpServletRequest request, HttpServletResponse response) {
          HttpClient httpClient = CreateHttpClient();
          HttpUriRequest targetRequest = null;
          HttpResponse targetResponse = null;
          try {
              targetRequest = createHttpUriRequest(request);
              targetResponse = httpClient.execute(targetRequest);
          } catch (IOException e) {
              e.printStackTrace();
          } finally {
              // make sure the entire entity was consumed, so the connection is released
              if (targetResponse != null) {
                  EntityUtils.consumeQuietly(targetResponse.getEntity()); // @since 4.2
                  //Note: Don't need to close servlet outputStream:
                  // http://stackoverflow.com/questions/1159168/should-one-call-close-on-httpservletresponse-getoutputstream-getwriter
              }
          }
      }
  }
  </code></pre>
  
  <p>The api url <code>/files/upload</code>:</p>
  
  <pre><code>@RestController
  @RequestMapping(value = "/files")
  public class FileUploadProxyController {
  
      private static final Logger logger = LoggerFactory.getLogger(FileUploadProxyController.class);
  
      @RequestMapping(value = "/upload", method = RequestMethod.POST)
      public ResponseEntity upload(HttpServletResponse response, HttpServletRequest request) {
          try {
              MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
              Iterator&lt;String&gt; it = multipartRequest.getFileNames();
              MultipartFile multipart = multipartRequest.getFile(it.next());
              String fileName = multipart.getOriginalFilename();
  
              File dir = new File("files", "proxy-uploaded");
              dir.mkdirs();
  
              logger.debug("current dir = {}, uploaded dir = {}", System.getProperty("user.dir"), dir.getAbsolutePath());
  
              File file = new File(dir, fileName);
              Files.copy(multipart.getInputStream(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
              //FileCopyUtils.copy(multipart.getInputStream())
  
  //            byte[] bytes = multipart.getBytes();
  //            BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream("upload" + fileName));
  //            stream.write(bytes);
  //            stream.close();
  
              RestTemplate restTemplate = new RestTemplate();
              SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
              //// if Spring version &lt; 3.1, see https://jira.springsource.org/browse/SPR-7909
              // requestFactory.setBufferRequestBody(false);
              restTemplate.setRequestFactory(requestFactory);
  
              String url = "http://localhost:8092/files/upload";
  
              // [resttemplate multipart post](https://jira.spring.io/browse/SPR-13571)
              // [Spring RestTemplate - how to enable full debugging/logging of requests/responses?](https://stackoverflow.com/questions/7952154/spring-resttemplate-how-to-enable-full-debugging-logging-of-requests-responses?rq=1)
  
              MultiValueMap&lt;String, Object&gt; param = new LinkedMultiValueMap&lt;&gt;();
              param.add("file", new FileSystemResource(file));
              param.add("param1", fileName);
              param.add("param2", "Leo");
  
              HttpEntity&lt;MultiValueMap&lt;String, Object&gt;&gt; httpEntity = new HttpEntity&lt;MultiValueMap&lt;String,Object&gt;&gt;(param);
              ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
  
              //String string = restTemplate.postForObject(url, param, String.class);
  
              //ResponseEntity e = restTemplate.exchange(url, HttpMethod.POST,
               //       new HttpEntity&lt;Resource&gt;(new FileSystemResource(file)), String.class);
  
              return responseEntity;
          } catch (Exception e) {
              e.printStackTrace();
              return new ResponseEntity("Upload failed", HttpStatus.BAD_REQUEST);
          }
      }
  
      @RequestMapping("/hello")
      public String hello() {
          return "hello word";
      }
  }
  </code></pre>