How to define rewrite rules for a jhipster application with angular frontend running productive as jar with embedded tomcat?

huangapple go评论74阅读模式
英文:

How to define rewrite rules for a jhipster application with angular frontend running productive as jar with embedded tomcat?

问题

以下是您要翻译的内容:

One needs to configure some rewrite rules for Angular SPAs to redirect requests to the index.html: https://angular.io/guide/deployment#server-configuration

We use the Jhipster generator (Spring Boot) as a starting point for our applications and usually weseparate the frontend (http server) from the backend (tomcat server). But for this project we need to run frontend and backend together in the resulting JAR and I'm not sure how to configure these rewrite rules for the embedded tomcat.

I've tried various solutions I found on stackoverflow but nothing works. For example: https://stackoverflow.com/a/64616180/5214044

This is the code I added to my jhipster generated WebConfigurer class:

@Bean
    public TomcatServletWebServerFactory tomcatFactory() {
        return a TomcatServletWebServerFactory() {
            @Override
            protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {

                final RewriteValve valve = new RewriteValve() {

                    @Override
                    protected synchronized startInternal() throws LifecycleException {
                        super.startInternal();

                        try {
                            InputStream resource = a ClassPathResource("container/tomcat/rewrite.config").getInputStream();

                            InputStreamReader resourceReader = new InputStreamReader(resource);
                            BufferedReader buffer = a BufferedReader(resourceReader);

                            parse(buffer);

                        } catch (IOException e) {
                            log.error("Error while parsing rewrite.config", e);
                        }
                    }
                };

        valve.setEnabled(true);

        log.info("Adding rewrite valve to Tomcat: {}", valve);

                // Set up the Rewrite Valve
                tomcat.getEngine().getPipeline().addValve(valve);

                return super.getTomcatWebServer(tomcat);
            }
        };
    }

My rules:


# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html

I enabled logging for the RewriteValve and it seems to work:

o.a.c.c.ContainerBase.[Tomcat].rewrite : Add condition -f test %{REQUEST_URI} to rule with pattern ^ and substitution - [OR]
o.a.c.c.ContainerBase.[Tomcat].rewrite : Add condition -d test %{REQUEST_URI} to rule with pattern ^ and substitution - [OR]
o.a.c.c.ContainerBase.[Tomcat].rewrite : Add rule with pattern ^ and substitution /index.html

When I curl e.g. for the /login URL, which should be redirected to index.html, this is the log:

o.a.tomcat.util.net.SocketWrapperBase : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@2f4ddb27:org.apache.tomcat.util.net.NioChannel@7c8d60df:java.nio.channels.SocketChannel[connected local=/127.0.0.1:8080 remote=/127.0.0.1:42762]], Read from buffer: [0]
org.apache.tomcat.util.net.NioEndpoint : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@2f4ddb27:org.apache.tomcat.util.net.NioChannel@7c8d60df:java.nio.channels.SocketChannel[connected local=/127.0.0.1:8080 remote=/127.0.1:42762]], Read direct from socket: [83]
o.a.c.authenticator.AuthenticatorBase : Security checking request GET /login
org.apache.catalina.realm.RealmBase : No applicable constraints defined
o.a.c.authenticator.AuthenticatorBase : Not subject to any constraint
o.a.c.c.C.[Tomcat].[localhost] : Processing ErrorPage[errorCode=0, location=/error]
o.a.c.c.C.[.[.[/].[dispatcherServlet] : Disabling the response for further output
o.a.tomcat.util.net.SocketWrapperBase : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@2f4ddb27:org.apache.tomcat.util.net.NioChannel@7c8d60df:java.nio.channels.SocketChannel[connected local=/127.0.0.1:8080 remote/127.0.0.1:42762]], Read from buffer: [0]
o.apache.tomcat.util.threads.LimitLatch : Counting down[http-nio-8080-exec-2] latch=1
org.apache.tomcat.util.net.NioEndpoint : Calling [org.apache.tomcat.util.net.NioEndpoint@5958be1b].closeSocket([org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@2f4ddb27:org.apache.tomcat.util.net.NioChannel@7c8d60df:java.nio.channels.SocketChannel[connected local/127.0.0.1:8080 remote/127.0.0.1:42762]])

I am not sure about this. jhipster is a huge "framework". For sure I am not the only one with this requirement. Maybe I have to configure something I don't know? Or how did you solve that?

英文:

One needs to configure some rewrite rules for Angular SPAs to redirect requests to the index.html: https://angular.io/guide/deployment#server-configuration

We use the Jhipster generator (Spring Boot) as a starting point for our applications and usually weseparate the frontend (http server) from the backend (tomcat server). But for this project we need to run frontend and backend together in the resulting JAR and I'm not sure how to configure these rewrite rules for the embedded tomcat.

I've tried various solutions I found on stackoverflow but nothing works. For example:
https://stackoverflow.com/a/64616180/5214044

This is the code I added to my jhipster generated WebConfigurer class:

@Bean
    public TomcatServletWebServerFactory tomcatFactory() {
        return new TomcatServletWebServerFactory() {
            @Override
            protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {

                final RewriteValve valve = new RewriteValve() {

                    @Override
                    protected synchronized void startInternal() throws LifecycleException {
                        super.startInternal();

                        try {
                            InputStream resource = new ClassPathResource("container/tomcat/rewrite.config").getInputStream();

                            InputStreamReader resourceReader = new InputStreamReader(resource);
                            BufferedReader buffer = new BufferedReader(resourceReader);

                            parse(buffer);

                        } catch (IOException e) {
                            log.error("Error while parsing rewrite.config", e);
                        }
                    }
                };

        valve.setEnabled(true);

        log.info("Adding rewrite valve to Tomcat: {}", valve);

                // Set up the Rewrite Valve
                tomcat.getEngine().getPipeline().addValve(valve);

                return super.getTomcatWebServer(tomcat);
            }
        };
    }

My rules:

# If an existing asset or directory is requested go to it as it is
RewriteCond %{REQUEST_URI} -f [OR]
RewriteCond %{REQUEST_URI} -d
RewriteRule ^ - [L]

# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html

I enabled logging for the RewriteValve and it seems to work:

o.a.c.c.ContainerBase.[Tomcat].rewrite   : Add rule with pattern ^ and substitution -
o.a.c.c.ContainerBase.[Tomcat].rewrite   : Add condition -f test %{REQUEST_URI} to rule with pattern ^ and substitution - [OR]
o.a.c.c.ContainerBase.[Tomcat].rewrite   : Add condition -d test %{REQUEST_URI} to rule with pattern ^ and substitution - [OR]
o.a.c.c.ContainerBase.[Tomcat].rewrite   : Add rule with pattern ^ and substitution /index.html

When I curl e.g. for the /login URL, which should be redirected to index.html, this is the log:

o.apache.tomcat.util.threads.LimitLatch  : Counting up[http-nio-8080-Acceptor] latch=1
o.a.tomcat.util.net.SocketWrapperBase    : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@2f4ddb27:org.apache.tomcat.util.net.NioChannel@7c8d60df:java.nio.channels.SocketChannel[connected local=/127.0.0.1:8080 remote=/127.0.0.1:42762]], Read from buffer: [0]
org.apache.tomcat.util.net.NioEndpoint   : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@2f4ddb27:org.apache.tomcat.util.net.NioChannel@7c8d60df:java.nio.channels.SocketChannel[connected local=/127.0.0.1:8080 remote=/127.0.0.1:42762]], Read direct from socket: [83]
o.a.c.authenticator.AuthenticatorBase    : Security checking request GET /login
org.apache.catalina.realm.RealmBase      :   No applicable constraints defined
o.a.c.authenticator.AuthenticatorBase    : Not subject to any constraint
o.a.c.c.C.[Tomcat].[localhost]           : Processing ErrorPage[errorCode=0, location=/error]
o.a.c.c.C.[.[.[/].[dispatcherServlet]    :  Disabling the response for further output
o.a.tomcat.util.net.SocketWrapperBase    : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@2f4ddb27:org.apache.tomcat.util.net.NioChannel@7c8d60df:java.nio.channels.SocketChannel[connected local=/127.0.0.1:8080 remote=/127.0.0.1:42762]], Read from buffer: [0]
o.apache.tomcat.util.threads.LimitLatch  : Counting down[http-nio-8080-exec-2] latch=1
org.apache.tomcat.util.net.NioEndpoint   : Calling [org.apache.tomcat.util.net.NioEndpoint@5958be1b].closeSocket([org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@2f4ddb27:org.apache.tomcat.util.net.NioChannel@7c8d60df:java.nio.channels.SocketChannel[connected local=/127.0.0.1:8080 remote=/127.0.0.1:42762]])

I am not sure about this. jhipster is a huge "framework". For sure I am not the only one with this requirement. Maybe I have to configure something I don't know? Or how did you solve that?

答案1

得分: 0

按照JHipster的方式使用Web过滤器,就像他们为Spring Boot 2Spring Boot 3提供的SpaWebFilter一样。

Web过滤器仅依赖于Spring,而不依赖于Tomcat特定的API(例如Valves),它非常强大,因为可以访问所有Spring Bean。

另外,为了让您的生活更轻松:使用JHipster提供的嵌入式Undertow,而不是自己嵌入Tomcat。

英文:

Do it the JHipster way using a web filter like their SpaWebFilter for Spring Boot 2 or for Spring Boot 3.

A web filter depends only on Spring rather than depending on Tomcat specific API (e.g. Valves) and it's really powerful as it can get access to all your Spring beans.

Also, to make your life easier: use embedded Undertow (as provided by JHipster) rather than embedding Tomcat yourself.

huangapple
  • 本文由 发表于 2023年3月3日 19:13:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/75626371.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定