Hi,

I want to add an Angular 6 application to an existing embedded Jetty web
server (version 9.4.12.v20180830). I am having a problem getting
client-side page routing to work properly.

For example:
http://localhost:8080/mypage
Is a valid Angular route, but does not exist as a file.
I can navigate to it either via a link on the home page  (index.html) or by
typing: http://localhost:8080/#/mypage in my browser.

If I type http://localhost:8080/mypage,  I get a 404.

That is because for client-side routing feature to work properly, HTML 5
PushState must be supported. From my understanding, what this means is that
the server must rewrite URLs so that they reach the angular page on
/index.html. Using the above example, "/mypage" would have to be rewritten
to "/index.html" with an original path attribute set to the requested path.

Here is are links to Angular documentation:
https://angular.io/guide/router
https://angular.io/guide/deployment

I've been working at it for a few days and am stuck. I have found how to do
url rewriting with Jetty, using a RewriteHandler. The rewriting works, but
is affecting all URLs, including valid ones. This causes script files and
images to be replaced with contents of index.html.

I need URLs associated with other servlets (such as websocket servlets and
rest apis) to be left untouched, and I need URLs for real files (such as
images and other angular assets) to be left untouched.

I have been looking for something in the like of Ngnx:
try_files $uri $uri/ /index.html;

Which translates into "try the URI as-is, if that doesn`t work, treat the
URI as a folder, if that doesnt work then use index.html"

So I tried this with Jetty:

// Create the web app context
WebAppContext context = new WebAppContext();
context.setContextPath("/");
context.setWelcomeFiles(new String[] {"index.html"});
String resLocation = WebServer.class.getResource("/webapp").toString();
context.setResourceBase(resLocation);

// Enable URL Rewriting to support HTML 5 PushState
RewriteHandler rewrite = new RewriteHandler();
rewrite.setRewriteRequestURI(true);
rewrite.setRewritePathInfo(false);
rewrite.setOriginalPathAttribute("requestedPath");

RewriteRegexRule html5pushState = new RewriteRegexRule();
html5pushState.setRegex("/.*");
html5pushState.setReplacement("/index.html");
rewrite.addRule(html5pushState);

// Handler Structure
HandlerList handlers = new HandlerList();
rewrite.setHandler(context);
handlers.setHandlers(new Handler[] { context, rewrite});
server.setHandler(handlers);


I was hoping this would do the trick. My rationale was that using a
HandlerList would cause Jetty to call each handler in the list in the order
specified until a response is matched.  Calling context first would lookup
all the existing webapps for a file or servlet.  Then calling rewrite would
rewrite the URL and then because context is also a child of rewrite I was
hoping this would cause Jetty to try again using the rewritten URL, in
which case would be index.html.

Unfortunately, It doesn`t work because "context" returns a 404 to the
client directly. The rewrite handler is never called.


I've been looking for Conditional statements in Jetty and couldn`t find
any. In fact, I was able to do this kind of conditional rewrite with Tomcat
using a RewriteValve:
ctx.addValve(new RewriteValve());

and a text file (rewrite.config):

RewriteCond %{REQUEST_URI} -f
RewriteRule ^(.*)$ - [L]

RewriteRule ^(.*)$ /index.html


Notice how the rewrite rule is conditional.   The rewrite occurs only if
the URL cannot be matched to a file.



How can this kind of conditional rewriting be done under Jetty?

If a custom handler must be written, how would you guys query the server to
figure out if a given path matches a servlet or a file?

Your help would be very much appreciated.

*Nicolas Therrien*

Senior Software Developer

*[image:
https://www.motorolasolutions.com/content/dam/msi/images/logos/corporate/msiemailsignature.png]*

*o*: +1.819.931.2053
_______________________________________________
jetty-users mailing list
[email protected]
To change your delivery options, retrieve your password, or unsubscribe from 
this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users

Reply via email to