Недавно возникла небольшая проблема: как добавить свой спринговый сервлет в Tapestry приложение. Если просто прописать его в web.xml, например так:
<servlet>
<servlet-name>PaymentService</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PaymentService</servlet-name>
<url-pattern>/PaymentService</url-pattern>
</servlet-mapping>
то Tapestry filter перехватывает запрос к этому сервлету, из-за вот такой настройки:
<filter>
<filter-name>app</filter-name>
<filter-class>org.apache.tapestry5.TapestryFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>app</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Как исключить что-то в url-pattern, я так и не понял, но, к счастью, тапестри позволяет настроить обработку HttpRequest и вручную определить, какие фильтры к нему применять. Нужно всего лишь добавить следующий код в AppModule
@Contribute(HttpServletRequestHandler.class)
public void сontributeFilter(OrderedConfiguration<HttpServletRequestFilter> config){
config.add("httpInvoker", new HttpServletRequestFilter() {
@Override
public boolean service(HttpServletRequest request, HttpServletResponse response, HttpServletRequestHandler handler) throws IOException {
if(request.getServletPath().equals("/PaymentService")){ // имя нашего сервлета
try{
AppContext.getHttpInvoker(StringUtils.removeStart(request.getServletPath(), "/")).handleRequest(request, response);
}catch (ServletException ex){
throw new IOException(ex);
}
return true; // мы обработали запрос сами, не нужно его обрабатывать другими фильтрами.
}
return handler.service(request, response); // передаем запрос тапестри
}
});
}
AppContext.getHttpInvoker - это хелпер, который возвращает spring bean по его имени, приведя его к нужному типу.
public static HttpInvokerServiceExporter getHttpInvoker(String name){
if(context == null){
throw new ApplicationNotInitializedException();
}
return (HttpInvokerServiceExporter) context.getBean(name);
}
И, для полноты картины, кусочек конфига спринга:
<bean name="PaymentService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="PaymentServiceImpl"/>
<property name="serviceInterface" value="com.example.httpInvoker.PaymentService"/>
</bean>