Hi Satoshi,
You can do this. We serve static files and MVC controllers from the same root in production and never set up any of the per-extension mapping you're trying to avoid.
The thing to change is how you deploy JAX-RS: deploy it as a servlet filter, not a servlet. We're on RESTEasy/WildFly and the web.xml is just:
<filter> <filter-name>MVC</filter-name> <filter-class>org.jboss.resteasy.plugins.server.servlet.FilterDispatcher</filter-class> <init-param> <param-name>jakarta.ws.rs.Application</param-name> <param-value>com.example.MvcApplication</param-value> </init-param> </filter> <filter-mapping> <filter-name>MVC</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Static files just sit in the webapp root (src/main/webapp/…). Anything outside WEB-INF gets served by the default servlet once the filter passes the request through.
The Application is @ApplicationPath("/"), so it owns the whole root, which sounds like what you want.
A servlet on /* is terminal, so if the request lands there and isn't a resource method, you get a 404. A filter isn't. When RESTEasy can't match the path to a JAX-RS resource it delegates back to the servlet container, which serves the file off disk. RESTEasy's docs actually call this out as the reason to run as a filter: you can't keep static files in the same path as your services when you deploy as a servlet. So /images/logo.png comes back as a file and /courses/123 goes to a controller, with no mapping for either.
One gotcha: this only kicks in when nothing matches the path. If a controller matches the URL and then returns a 404 itself, that stays in JAX-RS and won't fall through to a file. Only matters if your asset paths overlap your controller paths.
That's RESTEasy's default. Jersey does the same thing in filter mode but it's off by default, so you'd set jersey.config.servlet.filter.forwardOn404=true (note that one forwards on any empty 404, not just unmatched paths). None of this fall-through is defined by the JAX-RS spec itself; it depends on how your implementation plugs into the servlet container, so it's worth confirming on your target server rather than assuming it ports across. On Jun 25, 2026, at 9:14 PM, Satoshi Seto via mvc-dev <mvc-dev@xxxxxxxxxxx> wrote:
Hello. I am currently trying out Jakarta MVC. I would like to use Jakarta MVC as a replacement for Servlets and handle all requests through it. However, I noticed that Jakarta MVC cannot directly handle static resources, such as image files. I am considering migrating from Spring Boot to a Jakarta EE server. To preserve the existing URLs built with Spring MVC without changing them, I need to be able to access static resources under the URLs mapped to JAX-RS. While it is possible to avoid this issue by configuring complex JAX-RS or Servlet mappings, I find that approach rather cumbersome. Are there any plans to include a specification in Jakarta MVC that allows it to handle static resources similarly to how Servlets do?
--
_______________________________________________ mvc-dev mailing list mvc-dev@xxxxxxxxxxx To change your delivery options, retrieve your password, or unsubscribe from this list, visit https://dev.eclipse.org/mailman/listinfo/mvc-dev
|