英文:
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 2或Spring 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论