I am on a team developing a single page web application with an associated REST API.
I wonder if anyone can help me? I am trying to find a way for our application to return the contents of index.html with a 200 response if certain URLs are accessed. For example the client wants to embed information in the URL but expects the content on index.html to be returned.
For example our single page web application is available on a single context root e.g: http://host:9082/webapp
We have rest endpoints available on http://host:9082/webapp/api/... These endpoints must not return index html, they must only return valid rest responses with the appropriate status code (400, 404, 200, 201 etc)
Java script is served from http://host:9082/webapp/js/... and there are other locations we don't want to fall back to index.html
However, if the client requests http://host:9082/webapp/resource/7/show we want index.html to be returned with status code 200. The client will then extract meaning from the URL to drive other REST requests.
So I tried to write a filter like the following:
@Override
public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
{
final HttpServletRequest request = (HttpServletRequest)servletRequest;
final HttpServletResponse response = (HttpServletResponse)servletResponse;
final String requestUri = request.getRequestURI();
if (!excluded(requestUri))
{
request.getRequestDispatcher(INDEX_HTML).forward(request, response);
}
else
{
filterChain.doFilter(servletRequest, servletResponse);
}
}
private boolean excluded(String requestUri)
{
for (String part : mExcludedUriParts)
{
if (requestUri.contains(part))
{
return true;
}
}
return false;
}
and enabled the filter in web.xml as following:
<filter>
<filter-name>FallbackFilter</filter-name>
<filter-class>com....http.filter.internal.FallbackFilter</filter-class>
<init-param>
<param-name>excludedUriParts</param-name>
<param-value>/api/,.js/,.png,.html,/apidocs/,/users/imgs/</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FallbackFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
However this approach is quite fragile as the deployed needs to change the web.xml to match the available resources on the server which may of course change.
We also considered detecting 404's in the filterChain then modifying the response but Liberty did not allow this as the response has already been committed. We also considered using the request accept headers (i.e text/html) as the basis for whether or not to return index html, but we have other html files so this approach did not work either.
We basically want a way to allow some non existent locations on the server to return index.html with a 200 status code. Ideally we want to be informed of a 404 and control the response.
Is there a way to achieve this using filters or any other mechanism in Liberty?
Many thanks