7

I have deployed an angular 4 application (with angular routing) on tomcat server with "frontend-maven-plugin" (V1.6) but url comportement is very strange.

In fact, when i click on refresh button on all pages, there is a HTTP 404 error. When i try to acess on root page, there is no redirection to index.html.

Theses error are only present with tomcat deployment (it work fine with nodejs).

How can i configure tomcat in order to correct this problems ?

Thanks for your responses.

Jérémy
  • 391
  • 2
  • 7
  • 20
  • https://stackoverflow.com/questions/39018765/deploy-angular-2-app-with-webpack-to-tomcat-404-errors/44727035#44727035 – Vikas Jun 26 '18 at 13:33
  • https://stackoverflow.com/questions/40852931/how-can-i-deploy-an-angular-2-application-on-tomcat-server-windows-server-2012 – Vikas Jun 26 '18 at 13:33
  • Thanks Vikas but this correct only index.html redirection, not refresh action on route url. – Jérémy Jun 27 '18 at 06:17
  • https://angular.io/guide/deployment#routed-apps-must-fallback-to-indexhtml – Vikas Jun 27 '18 at 09:22
  • Upon refresh your entire application is re-loaded either you go for above config or use [hash Location strategy](https://codecraft.tv/courses/angular/routing/routing-strategies/) – Vikas Jun 27 '18 at 09:24

3 Answers3

20

I think you are getting 404 because your are requesting http://localhost/route which doesn't exist on tomcat server. As Angular 2 uses html 5 routing by default rather than using hashes at the end of the URL, refreshing the page looks like a request for a different resource.

When using angular routing on tomcat you need to make sure that your server will map all routes in your app to your main index.html while refreshing the page. There are multiple way to resolve this issue. Whichever one suits you you can go for that.

1) Put below code in web.xml of your deployment folder :

<error-page>
     <error-code>404</error-code>
     <location>/index.html</location>
</error-page>

2) You can also try using HashLocationStrategy with # in the URL for routes

Try using:

RouterModule.forRoot(routes, { useHash: true })

Instead of:

RouterModule.forRoot(routes)

With HashLocationStrategy your urls gonna be like:

http://localhost/#/route

3) Tomcat URL Rewrite Valve : Re-write the url's using a server level configuration to redirect to index.html if the resource is not found.

3.1) Inside META-INF folder create a file context.xml and copy the below context inside it.

<?xml version="1.0" encoding="utf-8"?>
<Context>
  <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
</Context>

3.2) Inside WEB-INF, create file rewrite.config(this file contain the rule for URL Rewriting and used by tomcat for URL rewriting). Inside rewrite.config, copy the below content:

RewriteCond %{SERVLET_PATH} !-f
RewriteRule ^/(.*)$ /index.html [L]
Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
Karan Khanna
  • 272
  • 2
  • 12
2

The application deep links will not work without the redirect rule on the server. All the deep links have to redirect to the application index.html by the server.

To setup the tomcat to redirect any deep links -

  1. Configure the RewriteValve in server.xml
  2. Write the rewrite rule in rewrite.config

1. Configure the RewriteValve in server.xml

Edit the ~/conf/server.xml to add the below Valve inside the Host section as below –

...
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />

...
      </Host>
...

2. Write the rewrite rule in rewrite.config

Create directory structure – ~/conf/Catalina/localhost/ and create the rewrite.config file inside it with the below content. Note - here I am considering /hello as the context path of the application.

RewriteCond %{REQUEST_PATH} !-f
RewriteRule ^/hello/(.*) /hello/index.html

After setting this up restart the tomcat server and you can hit the deep links of the application which will route to the correct components inside the angular application.

You can refer to this post for more details.

Nithin Kumar Biliya
  • 2,763
  • 3
  • 34
  • 54
  • Downvoted above answer as people respond by copy pasting from another website and never understand the crux of problem. Rewriting on apache tomcat works fine for Deep Linking but then other features are broken, which is only fixed by adding an entry in web.xml, which tells server that for any 404 encountered, it should redirect to base url, from where the angular then takes control – Sategroup Nov 29 '19 at 10:02
  • what will you change in rewrite.config if you have multiple angular projects deployed in tomcat server? – Shekhar Sahu Jan 14 '20 at 06:11
  • 1
    you can have it as below - `RewriteCond %{REQUEST_PATH} !-f RewriteRule ^/app1/(.*) /app1/index.html RewriteCond %{REQUEST_PATH} !-f RewriteRule ^/app2/(.*) /app2/index.html` – Nithin Kumar Biliya Jan 15 '20 at 14:27
  • @NithinKumarBiliya Could you please explain the RewriteRule? – gourabix Jun 22 '21 at 21:02
  • any request coming into nginx for URL `/hello/` will be sent back the hello angular app's index.html file – Nithin Kumar Biliya Jun 24 '21 at 05:03
0

The above Valve configurations works fine when your application is deployed in ROOT. If you are deploying to a different application context, here is the config:

<Context path="/my-context-path" docBase="C:/apache-tomcat-10.0.0-M4/webapps/my-context-path">
    <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
</Context>