Reputation: 25
I'm trying to deploy an Angular 4 app with a Java backend on Google App Engine (standard). Everything works fine except when I try to reload the page. What happens is that a request to e.g. myapp.com/some/page should be redirected to myapp.com/index.html for the Angular app to respond.
As far as I can see, this would be possible if using the app.yaml configuration file which is used for all supported languages except Java (which uses appengine-web.xml and web.xml).
Can this be done with appengine-web.xml? In any other way?
Upvotes: 2
Views: 494
Reputation: 1703
As a follow up to Gwendal Le Cren's answer, I did this and needed a few more things with the filter, so I'll put them below.
// Filter all paths.
@WebFilter("/*")
public class SinglePageAppFilter implements Filter {
@Override
public void doFilter(
ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
// Get the end part of the path e.g. /api for API requests, /devices for the devices page etc.
String path = ((HttpServletRequest) servletRequest).getServletPath();
// Continue with the intended action if an API request.
if (path.startsWith("/api")) {
filterChain.doFilter(servletRequest, servletResponse);
}
// Otherwise, send the result as if requesting the '/' path.
else {
RequestDispatcher dispatcher = servletRequest.getRequestDispatcher("/");
dispatcher.forward(servletRequest, servletResponse);
}
}
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void destroy() {}
}
Upvotes: 0
Reputation: 510
If you want to keep the PathLocationStrategy which is the default "HTML5 pushState" style, you need to implement a redirect on the backend side. Basically you need to add a filter or servlet with "/*" as the URL pattern with the following behavior:
public class SinglePageAppFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
RequestDispatcher dispatcher = servletRequest.getRequestDispatcher("/");
dispatcher.forward(servletRequest, servletResponse);
}
}
Upvotes: 2
Reputation: 793
Yes you have to use the HashLocationStrategy instead of the default PathLocationStrategy.
Angular's documentation: https://angular.io/guide/router#appendix-locationstrategy-and-browser-url-styles
Basically, you just have to tell the RouterModule to use HashLocationStrategy in your AppRoutingModule:
@NgModule({
imports: [RouterModule.forRoot(routes, {useHash: true})],
exports: [RouterModule]
})
export class AppRoutingModule {
}
I hope it helps
Upvotes: 1