Mapping servlet in root
guice, gwt, java, resteasy, servlets
Solution
So your problem is that you are mapping all root requests to go to the rest servlet because it doesnt work otherwise.
If there were a way to know some patterns for your rest servlet, you could configure all those specific patterns in your web.xml. But `url-pattern` uses an extremely simple syntax only `whatever/*` and `*.extension` are allowed, and it seems that your rest-servlet does not match this requirement.
Another option could be to use an advanced servlet dispatcher like the `GuiceServletContextListener` (provided by guice) and configure a `WebModule` witch rich regular expressions. Modify your `web.xml` to add a `WebModule` and configure that module to handle urls and dispatch with the appropriate servlet (remove these servlets from your web.xml)
<context-param>
<param-name>resteasy.guice.modules</param-name>
<param-value>org.jboss.errai.ui.demo.server.MyModule</param-value>
<param-value>org.jboss.errai.ui.demo.server.MyWebModule</param-value>
</context-param>
public class MyWebModule extends ServletModule {
@Override
protected void configureServlets() {
// Note: all servlets and filters must be singletons
bind(FactoryServlet.class).in(Singleton.class);
// Pass to the HttpServletDispatcher everything but urls ending with static extensions
serveRegex(".+(?<!\\.(html|css|png|jpg))")
.with(HttpServletDispatcher.class);
}
}
- The last option, is to write your own filter, where you detect whether the path matches a static file and dispatch it.
private FilterConfig config;
public void init(FilterConfig filterConfig) throws ServletException {
config = filterConfig;
}
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
File file = new File(config.getServletContext().getRealPath(req.getServletPath()));
if (file.canRead()) {
// NOTE: you have to set the most appropriate type per file
resp.setContentType("text/html");
// This depends on apache commons-io
IOUtils.copy(new FileInputStream(file), resp.getOutputStream());
} else {
filterChain.doFilter(req, resp);
}
}
Problem
What is the right configuration for both of this to "co-exist": ``` http://localhost:8888/index.html http://localhost:8888/{some_path_value} ``` The first item will be returning a html page and will also containt href that will access resource like `/public/images/bg.png` etc. Now the second item is a Restful api that is mapped in the same root context ad the one that serves pages (index.html, png, jpg, css, js etc) So the problem I am facing right now is that when I configure the Rest API servlet mapping like this: ``` <servlet> <servlet-name>Resteasy</servlet-name> <servlet-class> org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher </servlet-class> </servlet> <servlet-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> ``` The Rest API works but it effectively removes access to the static resources like index.html, css, js etc. to render a "home page". However if I changed the mapping to something like `/api/*` the GWT app can now be accessed but the PATH of the Rest API is not the root anymore. So what could be wrong in my app? I really need to make both co-exist on the same path. My initial idea is to do some kind of filter, but there may be easier and more appropriate solution. Update: My app's guice module: ``` public class MyModule implements Module { public void configure(final Binder binder) { binder.bind(MyResource.class); } } ``` web.xml ``` <context-param> <param-name>resteasy.guice.modules</param-name> <param-value>org.jboss.errai.ui.demo.server.MyModule</param-value> </context-param> <listener> <listener-class> org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener </listener-class> </listener> <context-param> <param-name>resteasy.servlet.mapping.prefix</param-name> <param-value>/api</param-value> </context-param> <servlet> <servlet-name>Resteasy</servlet-name> <servlet-class> org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher </servlet-class> </servlet> <servlet-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> ```