将Apache Camel servlet隐藏在Spring MVC Controller入口点后面

时间:2017-02-27 12:45:40

标签: java spring-mvc servlets apache-camel

我想隐藏Spring Apache Camel Servlet背后的Spring MVC Controller入口点,因为我有一些必须依赖Sping Boot和Spring MVC Controller的专有组件。

我有以下Apache Camel Route,工作正常

<route id="Route">
            <from uri="servlet:messages?httpMethodRestrict=POST"/>
            <process ref="..."></process>
            <to uri="{{storage.service.endpoint}}?bridgeEndpoint=true"/>
</route>

我已经注册了Camel Servlet without any URL mappings,因为我不想直接访问。春豆:

@Bean
ServletRegistrationBean servletRegistrationBean() {
      CamelHttpTransportServlet camelServlet = new CamelHttpTransportServlet();
      ServletRegistrationBean servletBean = new ServletRegistrationBean(camelServlet, false, new String[]{});
      servletBean.setName("CamelServlet");
      return servletBean;
}

在Spring Controller入口点我只需转发到Camel Servlet:

@RequestMapping(method=RequestMethod.POST, value="/api/v1/*")
public void wrapper(HttpServletRequest request, HttpServletResponse response) throws Exception{
      context.getNamedDispatcher("CamelServlet").forward(request, response);
}

问题是Camel Servlet使用request.getPathInfo()依赖ServletResolveConsumerStrategy,它在Spring Controller入口点始终为null。我在@RequestMapping尝试了不同的路径,但始终request.getServletPath()有完整路径且pathInfo为空

P.S。该应用程序在Tomcat 8上运行。

2 个答案:

答案 0 :(得分:0)

一种解决方案是创建自定义ServletResolveConsumerStrategy,它仅依赖request.getServletPath()来查找适当的路由。不幸的是,仅使用org.apache.camel.http.common.CamelServlet.setServletResolveConsumerStrategy(ServletResolveConsumerStrategy)设置策略不起作用,因为它在org.apache.camel.component.servlet.CamelHttpTransportServlet.init方法中被覆盖。所以你需要覆盖Camel Servlet中的init:

CamelHttpTransportServlet camelServlet = new CamelHttpTransportServlet(){
          @Override
          public void init(ServletConfig config) throws ServletException {
              super.init(config);
              ServletResolveConsumerStrategy servletResolveConsumerStrategy = new CamelSpringResolveConsumerStrategy();
              setServletResolveConsumerStrategy(servletResolveConsumerStrategy );
          }
      };

答案 1 :(得分:0)

使用路径变量修改Spring Controller入口点,并在自定义pathInfo()中将路径变量的值设置为HttpServletRequestWrapper

  @RequestMapping(path="/api/v1/{messages}" , method=RequestMethod.POST)
  public void wrapper2(HttpServletRequest request, HttpServletResponse response, @PathVariable String messages) throws Exception{
      request = new PathInfoRequestWrapper(request, messages);
      context.getNamedDispatcher("CamelServlet").forward(request, response);

  }

  class PathInfoRequestWrapper extends HttpServletRequestWrapper{
    private String pathInfo;

    public PathInfoRequestWrapper(HttpServletRequest request, String pathInfo) {
       super(request);
       this.pathInfo = pathInfo;
    }

    @Override
    public String getPathInfo(){
        String origPathInfo = super.getPathInfo();
        if(origPathInfo == null || origPathInfo.equals("")){
            return this.pathInfo;
        }else{
            return origPathInfo;
        }
    }
  }