2017-08-09 10 views
0

私はシンプルなプロキシアプリケーションを作成していますが、マップされたURLはコントローラで処理されますが、別のURL(エラーを含む)を別の別のアドレスに転送できます。だから、HandlerInterceptorAdapterではなくFilterを使用します。特定の「resoureceパスハンドラ」がそれを扱うため、resoureceが見つからない場合は呼び出せません。HandlerMethodの取得方法は、フィルタのHttpServletRequestと一致します

期待

http://localhost:8090/upload.html>Filter>>http://localhost:8092/files/upload

ない

http://localhost:8090/upload.html>Filter>http://localhost:8092/upload.html

http://localhost:8090/files/upload>Controller >http://localhost:8090/files/upload>Controller>http://localhost:8092/files/upload

それとも

http://localhost:8090/upload.html>Interceptor私はWebMvcConfigurerAdapterの私のサブクラスでFilterを設定 http://localhost:8090/files/upload>Filter>http://localhost:8092/files/upload

デモ

が見つかりません。

@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 <mvc:default-servlet-handler/> <!-- This tag allows for mapping the DispatcherServlet to "/" --> 
    * 
    * @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 
      } 
     } 
    } 
} 

APIのURL /files/upload

@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<String> 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 < 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<String, Object> param = new LinkedMultiValueMap<>(); 
      param.add("file", new FileSystemResource(file)); 
      param.add("param1", fileName); 
      param.add("param2", "Leo"); 

      HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String,Object>>(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<Resource>(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"; 
    } 
} 

答えて

0

Spring mvc autowire RequestMappingHandlerMappingまたはGet destination controller from a HttpServletRequestを読んだのafer

次のコードは動作します:

@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 

    // https://stackoverflow.com/questions/129207/getting-spring-application-context 
    @Autowired 
    private org.springframework.context.ApplicationContext appContext; 

    private static final String MY_CONTROLLER_PACKAGE_NAME = "nxtcasb.casbproxy"; 

    @Bean 
    protected javax.servlet.Filter proxyFilter() { 
     return new OncePerRequestFilter() { 
      @Override 
      protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) 
        throws ServletException, IOException { 

       HandlerMethod handlerMethod = null; 
       try { 
        RequestMappingHandlerMapping req2HandlerMapping = (RequestMappingHandlerMapping) appContext.getBean("requestMappingHandlerMapping"); 
        // Map<RequestMappingInfo, HandlerMethod> handlerMethods = req2HandlerMapping.getHandlerMethods(); 
        HandlerExecutionChain handlerExeChain = req2HandlerMapping.getHandler(request); 
        if (Objects.nonNull(handlerExeChain)) { 
         handlerMethod = (HandlerMethod) handlerExeChain.getHandler(); 
         if (handlerMethod.getBeanType().getName().startsWith(MY_CONTROLLER_PACKAGE_NAME)) { 
          filterChain.doFilter(request, response); 
          return; 
         } 
        } 
       } catch (Exception e) { 
        logger.warn("Lookup the handler method", e); 
       } finally { 
        logger.debug("URI = " + request.getRequestURI() + ", handlerMethod = " + handlerMethod); 
       } 

       httpProxyForward(request, response); 
      } 
     }; 
    } 

// @Bean 
// private FilterRegistrationBean loggingFilterRegistration() { 
//  FilterRegistrationBean registration = new FilterRegistrationBean(proxyFilter()); 
//  registration.addUrlPatterns("/**"); 
//  return registration; 
// } 

    /** 
    * this is the same as <mvc:default-servlet-handler/> <!-- This tag allows for mapping the DispatcherServlet to "/" --> 
    * 
    * @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 
      } 
     } 
    } 
} 
関連する問題