我想隐藏弹簧MVC控制器入口点后面的apache骆驼servlet,因为我有一些专有组件,我必须使用这些组件。
我有以下Apache骆驼路线,该路由正常工作
<route id="Route">
<from uri="servlet:messages?httpMethodRestrict=POST"/>
<process ref="..."></process>
<to uri="{{storage.service.endpoint}}?bridgeEndpoint=true"/>
</route>
我已经注册了没有任何URL映射的骆驼servlet,因为我不想直接访问。弹簧豆:
@Bean
ServletRegistrationBean servletRegistrationBean() {
CamelHttpTransportServlet camelServlet = new CamelHttpTransportServlet();
ServletRegistrationBean servletBean = new ServletRegistrationBean(camelServlet, false, new String[]{});
servletBean.setName("CamelServlet");
return servletBean;
}
在弹簧控制器的入口点我只需要转发到骆驼servlet:
@RequestMapping(method=RequestMethod.POST, value="/api/v1/*")
public void wrapper(HttpServletRequest request, HttpServletResponse response) throws Exception{
context.getNamedDispatcher("CamelServlet").forward(request, response);
}
问题是骆驼servlet依赖于使用request.getPathInfo()
的ServletResolveconsumersstrategy,它在Spring Controller入口点中始终是null
。我在@RequestMapping
中尝试了不同的路径,但是总是request.getServletPath()
具有完整的路径,而pathInfo
为null
P.S。该应用程序在Tomcat8。
使用路径变量修改弹簧控制器入口点,并在自定义HttpServletRequestWrapper
中设置路径变量A pathInfo()
的值:
@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;
}
}
}
一种解决方案是创建仅依赖request.getServletPath()
的自定义ServletResolveConsumerStrategy
来找到适当的路由。不幸的是,仅使用org.apache.camel.http.common.CamelServlet.setServletResolveConsumerStrategy(ServletResolveConsumerStrategy)
设定策略不起作用,因为它在org.apache.camel.camel.component.servlet.camelhttptransportservlet.init方法中被覆盖。因此,您还需要覆盖骆驼sers脚的初始化:
CamelHttpTransportServlet camelServlet = new CamelHttpTransportServlet(){
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
ServletResolveConsumerStrategy servletResolveConsumerStrategy = new CamelSpringResolveConsumerStrategy();
setServletResolveConsumerStrategy(servletResolveConsumerStrategy );
}
};