亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

具有 Angular URL 重寫功能的嵌入式 Jetty

具有 Angular URL 重寫功能的嵌入式 Jetty

波斯汪 2023-08-23 17:08:56
我正在使用 Jetty 部署 WebSocket 和 Angular 應用程序。在開發中,一切正常,但在生產中,我遇到了一個問題,當刷新前端或輸入 url 時,我從服務器收到 404 消息,指出給定的資源不存在?,F在我正在嘗試創建重寫規則以將請求重定向到我的index.html。初始化我的服務器如下所示:server = new Server();ServerConnector connector = new ServerConnector(server);connector.setPort(config.getServer().getPort());server.addConnector(connector);RewriteHandler rewriteHandler = new RewriteHandler();rewriteHandler.setRewriteRequestURI(true);rewriteHandler.setRewritePathInfo(false);rewriteHandler.setOriginalPathAttribute("requestedPath");/* RedirectRegexRule rule1 = new RedirectRegexRule();rule1.setRegex("/(.+)");rule1.setLocation("/index.html");rewriteHandler.addRule(rule1);*/URL webRootLocation = this.getClass().getResource("/frontend/index.html");if (webRootLocation == null)    throw new IllegalStateException("Unable to determine webroot URL location");URI webRootUri = URI.create(webRootLocation.toURI().toASCIIString().replaceFirst("/index.html$","/"));logger.debug("Web Root URI: {}",webRootUri);ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);contextHandler.setContextPath("/");contextHandler.setBaseResource(Resource.newResource(webRootUri));contextHandler.setWelcomeFiles(new String[]{ "index.html" });rewriteHandler.setHandler(contextHandler);ServerContainer container = WebSocketServerContainerInitializer.initialize(contextHandler);List<Class<? extends Encoder>> encoders = new ArrayList<>();encoders.add(MessageEncoder.class);List<Class<? extends Decoder>> decoders = new ArrayList<>();decoders.add(MessageDecoder.class);我的 Angular 前端編譯在應用程序的資源文件夾中,該文件夾由服務器提供服務 - 例如:localhost:8080/。如果我的應用程序路由到localhost:8080/some/path一切都很好,但刷新頁面時我會收到some/path未知的 404。使用重寫規則(注釋掉)我ERR_TOO_MANY_REDIRECTIONS也得到了延遲加載的資源/模塊未找到。關于如何對 Angular 應用程序使用 Jetty 重寫的任何建議,因為我不知道如何繼續這里,或者 Jetty 不支持Angular 部署建議的 apache 重寫之類的東西
查看完整描述

2 回答

?
慕哥6287543

TA貢獻1831條經驗 獲得超10個贊

對于任何正在尋找解決方案的人,我讓它與 Jettys 一起工作RewriteHandler。我的服務器設置現在如下所示:


server = new Server(config.getServer().getPort());


RewriteHandler rewriteHandler = new RewriteHandler();

rewriteHandler.setRewriteRequestURI(true);

rewriteHandler.setRewritePathInfo(false);

rewriteHandler.setOriginalPathAttribute("requestedPath");


RewriteRegexRule rule1 = new RewriteRegexRule();

rule1.setRegex("^((?!"+wsPath+"|\\.js|\\.css|\\.jpe?g|\\.png).)*$");

rule1.setReplacement("/index.html");

rewriteHandler.addRule(rule1);


URL webRootLocation = this.getClass().getResource("/frontend/index.html");

if (webRootLocation == null)

    throw new IllegalStateException("Unable to determine Web-Root URL location");


URI webRootUri = URI.create(webRootLocation.toURI().toASCIIString().replaceFirst("/index.html$","/"));

logger.debug("Web-Root URI: {}",webRootUri);


ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);

contextHandler.setContextPath("/");

contextHandler.setBaseResource(Resource.newResource(webRootUri));

contextHandler.setWelcomeFiles(new String[]{ "index.html" });


rewriteHandler.setHandler(contextHandler);


// Initialize WebSocket

ServerContainer container = WebSocketServerContainerInitializer.initialize(contextHandler);


List<Class<? extends Encoder>> encoders = new ArrayList<>();

encoders.add(MessageEncoder.class);

List<Class<? extends Decoder>> decoders = new ArrayList<>();

decoders.add(MessageDecoder.class);


ServerEndpointConfig endpointConfig = ServerEndpointConfig.Builder

        .create(AppEndpoint.class, "/" + wsPath)

        .encoders(encoders)

        .decoders(decoders)

        .configurator(new AppEndpointConfig(config, factory))

        .build();

container.addEndpoint(endpointConfig);


server.setHandler(rewriteHandler);


contextHandler.addServlet(DefaultServlet.class, "/");


server.start();

server.join();

這并不理想,因為只有特定的文件結尾與正則表達式匹配,但它確實可以與 Jetty 內構建和部署的 Angular 應用程序配合使用。如果使用 RESTful API,則必須定義一些正則表達式來匹配 API 的路徑,如wsPath我的示例中的(一個簡單的字符串)。


查看完整回答
反對 回復 2023-08-23
?
滄海一幻覺

TA貢獻1824條經驗 獲得超5個贊

在 Servlet 世界中實現此目的的唯一方法是讓錯誤頁面處理 404 狀態代碼并自行發出重定向。

這只能在特定的 Web 應用程序中完成,而不能從通用重寫處理例程中完成。

為什么?

那么,“如果請求的資源不存在,則使用index.html”是關鍵。

會發生什么。

  1. 輸入了 web 應用程序,但沒有匹配的 url-pattern,因此使用默認的 url-pattern?(of )。"/"

  2. 默認 url 模式映射到所謂的“默認 Servlet”

  3. 默認 Servlet 負責在 Web 應用程序的基礎資源中查找匹配的資源,并將該內容作為靜態資源請求返回。

  4. 如果靜態資源不存在,并且請求是針對目錄(例如:/js/然后使用歡迎文件列表來查找歡迎文件。(此列表在 中配置WEB-INF/web.xml

<welcome-file-list>

? ? <welcome-file>index.html</welcome-file>

? ? <welcome-file>index.htm</welcome-file>

? ? <welcome-file>index.jsp</welcome-file>

</welcome-file-list>

如果靜態資源仍然不存在,則將其作為 404 響應進行處理。

同時,servlet 規范的錯誤頁面處理例程啟動。這將導致在您的WEB-INF/web.xml.


<servlet>

? <servletname>404Handler</servlet-name>

? <servlet-class>com.acme.My404Servlet</servlet-class>

</servlet>

<servlet-mapping>

? <servlet-name>404Handler</servlet-name>

? <url-pattern>/404status</url-pattern>

</servlet-mapping>

<!-- ... then later ... -->

<error-page>

? ? <error-code>404</error-code>

? ? <location>/404status</location>

</error-page>

該路徑可以是 servlet、靜態資源、jsp 等。幾乎可以是任何可以通過路徑引用的內容。

如果它是 servlet(或 jsp),您可以通過請求屬性詢問原始請求,以了解處理此錯誤的原因。


嵌入式碼頭中的一個例子是......

package jetty.errors;


import java.io.IOException;

import java.nio.file.Files;

import java.nio.file.Path;

import java.nio.file.Paths;

import javax.servlet.DispatcherType;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import org.eclipse.jetty.server.Server;

import org.eclipse.jetty.server.handler.DefaultHandler;

import org.eclipse.jetty.server.handler.HandlerList;

import org.eclipse.jetty.servlet.DefaultServlet;

import org.eclipse.jetty.servlet.ErrorPageErrorHandler;

import org.eclipse.jetty.servlet.ServletContextHandler;

import org.eclipse.jetty.servlet.ServletHolder;

import org.eclipse.jetty.util.resource.PathResource;


public class EmbeddedWelcomeErrorDemo

{

? ? public static void main(String[] args) throws Exception

? ? {

? ? ? ? Server server = new Server(8080);


? ? ? ? String baseDir = System.getProperty("user.home");

? ? ? ? if (args.length > 0)

? ? ? ? ? ? baseDir = args[0];


? ? ? ? Path basePath = Paths.get(baseDir);


? ? ? ? if (!Files.exists(basePath) || !Files.isDirectory(basePath))

? ? ? ? {

? ? ? ? ? ? throw new IOException("Not a valid directory: " + basePath);

? ? ? ? }


? ? ? ? ServletContextHandler context = new ServletContextHandler();

? ? ? ? context.setContextPath("/");

? ? ? ? context.setBaseResource(new PathResource(basePath));

? ? ? ? context.setWelcomeFiles(new String[]{

? ? ? ? ? ? "index.html"

? ? ? ? });


? ? ? ? // Add error page mapping for context

? ? ? ? context.addServlet(ErrorHandling.class, "/errorpage");

? ? ? ? ErrorPageErrorHandler errorMapper = new ErrorPageErrorHandler();

? ? ? ? errorMapper.addErrorPage(404, "/errorpage");

? ? ? ? context.setErrorHandler(errorMapper);


? ? ? ? // to handle static resources against base resource (always last)

? ? ? ? // always named "default" (per spec)

? ? ? ? ServletHolder defaultHolder = new ServletHolder("default", DefaultServlet.class);

? ? ? ? // assigned to default url-pattern of "/" (per spec)

? ? ? ? context.addServlet(defaultHolder, "/");


? ? ? ? HandlerList handlers = new HandlerList();

? ? ? ? handlers.addHandler(context);

? ? ? ? handlers.addHandler(new DefaultHandler()); // for non-context errors


? ? ? ? server.setHandler(handlers);

? ? ? ? server.start();

? ? ? ? server.join();

? ? }


? ? public static class ErrorHandling extends HttpServlet

? ? {

? ? ? ? @Override

? ? ? ? protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException

? ? ? ? {

? ? ? ? ? ? if (req.getDispatcherType() != DispatcherType.ERROR)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? // we didn't get here from a error dispatch.

? ? ? ? ? ? ? ? // somebody attempted to use this servlet directly.

? ? ? ? ? ? ? ? resp.setStatus(404);

? ? ? ? ? ? ? ? return;

? ? ? ? ? ? }


? ? ? ? ? ? String requestedResource = (String)req.getAttribute(RequestDispatcher.ERROR_REQUEST_URI);

? ? ? ? ? ? log("[ErrorHandling] Requested resource was " + requestedResource);

? ? ? ? ? ? int statusCode = (int)req.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);

? ? ? ? ? ? switch (statusCode)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? case 404:

? ? ? ? ? ? ? ? ? ? // let handle it by a redirect

? ? ? ? ? ? ? ? ? ? resp.sendRedirect("/");

? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? default:

? ? ? ? ? ? ? ? ? ? // pass the other errors through

? ? ? ? ? ? ? ? ? ? resp.setStatus(statusCode);

? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

發生的情況的一些例子。


$ mkdir $HOME/tmp-base

$ mdkir css

$ echo "this is the index.html" > index.html

$ echo "this is my other html" > myother.html

$ echo "this is my fancy css" > css/main.css

然后使用命令行運行服務器示例到該目錄


$ java ... jetty.errors.EmbeddedWelcomeErrorDemo $HOME/tmp-base

2019-09-24 14:17:55.540:INFO::main: Logging initialized @190ms to org.eclipse.jetty.util.log.StdErrLog

2019-09-24 14:17:55.621:INFO:oejs.Server:main: jetty-9.4.20.v20190813; built: 2019-08-13T21:28:18.144Z; git: 84700530e645e812b336747464d6fbbf370c9a20; jvm 1.8.0_202-b08

2019-09-24 14:17:55.661:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@7921b0a2{/,file:///home/joakim/tmp-base/,AVAILABLE}

2019-09-24 14:17:55.674:INFO:oejs.AbstractConnector:main: Started ServerConnector@7cef4e59{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}

2019-09-24 14:17:55.674:INFO:oejs.Server:main: Started @325ms

然后提出一些要求...


$ curl -L -vv http://localhost:8080/

*? ?Trying ::1...

* TCP_NODELAY set

* Connected to localhost (::1) port 8080 (#0)

> GET / HTTP/1.1

> Host: localhost:8080

> User-Agent: curl/7.58.0

> Accept: */*

>?

< HTTP/1.1 200 OK

< Date: Tue, 24 Sep 2019 19:26:28 GMT

< Last-Modified: Tue, 24 Sep 2019 19:12:21 GMT

< Content-Type: text/html

< Accept-Ranges: bytes

< Content-Length: 23

< Server: Jetty(9.4.20.v20190813)

<?

this is the index.html

* Connection #0 to host localhost left intact

這是受歡迎的文件處理


$ curl -L -vv http://localhost:8080/myother.html

*? ?Trying ::1...

* TCP_NODELAY set

* Connected to localhost (::1) port 8080 (#0)

> GET /myother.html HTTP/1.1

> Host: localhost:8080

> User-Agent: curl/7.58.0

> Accept: */*

>?

< HTTP/1.1 200 OK

< Date: Tue, 24 Sep 2019 19:21:10 GMT

< Last-Modified: Tue, 24 Sep 2019 19:13:46 GMT

< Content-Type: text/html

< Accept-Ranges: bytes

< Content-Length: 22

< Server: Jetty(9.4.20.v20190813)

<?

This is my other html

* Connection #0 to host localhost left intact

這是正常的靜態文件服務


$ curl -L -vv http://localhost:8080/css/main.css

*? ?Trying ::1...

* TCP_NODELAY set

* Connected to localhost (::1) port 8080 (#0)

> GET /css/main.css HTTP/1.1

> Host: localhost:8080

> User-Agent: curl/7.58.0

> Accept: */*

>?

< HTTP/1.1 200 OK

< Date: Tue, 24 Sep 2019 19:22:22 GMT

< Last-Modified: Tue, 24 Sep 2019 19:22:16 GMT

< Content-Type: text/css

< Accept-Ranges: bytes

< Content-Length: 21

< Server: Jetty(9.4.20.v20190813)

<?

this is my fancy css

* Connection #0 to host localhost left intact

這是正常的靜態文件服務


如果我向不存在的資源或目錄發出一些請求......


$ curl -L -vv http://localhost:8080/css/bogus.css

*? ?Trying ::1...

* TCP_NODELAY set

* Connected to localhost (::1) port 8080 (#0)

> GET /css/bogus.css HTTP/1.1

> Host: localhost:8080

> User-Agent: curl/7.58.0

> Accept: */*

>?

< HTTP/1.1 302 Found

< Date: Tue, 24 Sep 2019 19:22:46 GMT

< Location: http://localhost:8080/

< Content-Length: 0

< Server: Jetty(9.4.20.v20190813)

<?

* Connection #0 to host localhost left intact

* Issue another request to this URL: 'http://localhost:8080/'

* Found bundle for host localhost: 0x5647e1581a50 [can pipeline]

* Re-using existing connection! (#0) with host localhost

* Connected to localhost (::1) port 8080 (#0)

> GET / HTTP/1.1

> Host: localhost:8080

> User-Agent: curl/7.58.0

> Accept: */*

>?

< HTTP/1.1 200 OK

< Date: Tue, 24 Sep 2019 19:22:46 GMT

< Last-Modified: Tue, 24 Sep 2019 19:12:21 GMT

< Content-Type: text/html

< Accept-Ranges: bytes

< Content-Length: 23

< Server: Jetty(9.4.20.v20190813)

<?

this is the index.html

* Connection #0 to host localhost left intact

這是由ErrorHandlingservlet處理的


$ curl -L -vv http://localhost:8080/this/directory/does/not/exist

*? ?Trying ::1...

* TCP_NODELAY set

* Connected to localhost (::1) port 8080 (#0)

> GET /this/directory/does/not/exist HTTP/1.1

> Host: localhost:8080

> User-Agent: curl/7.58.0

> Accept: */*

>?

< HTTP/1.1 302 Found

< Date: Tue, 24 Sep 2019 19:23:02 GMT

< Location: http://localhost:8080/

< Content-Length: 0

< Server: Jetty(9.4.20.v20190813)

<?

* Connection #0 to host localhost left intact

* Issue another request to this URL: 'http://localhost:8080/'

* Found bundle for host localhost: 0x561eefa8b020 [can pipeline]

* Re-using existing connection! (#0) with host localhost

* Connected to localhost (::1) port 8080 (#0)

> GET / HTTP/1.1

> Host: localhost:8080

> User-Agent: curl/7.58.0

> Accept: */*

>?

< HTTP/1.1 200 OK

< Date: Tue, 24 Sep 2019 19:23:02 GMT

< Last-Modified: Tue, 24 Sep 2019 19:12:21 GMT

< Content-Type: text/html

< Accept-Ranges: bytes

< Content-Length: 23

< Server: Jetty(9.4.20.v20190813)

<?

this is the index.html

* Connection #0 to host localhost left intact

這是由ErrorHandlingservlet處理的


[joakim@hyperion tmp]$ curl -L -vv http://localhost:8080/non-existant.jpeg

*? ?Trying ::1...

* TCP_NODELAY set

* Connected to localhost (::1) port 8080 (#0)

> GET /non-existant.jpeg HTTP/1.1

> Host: localhost:8080

> User-Agent: curl/7.58.0

> Accept: */*

>?

< HTTP/1.1 302 Found

< Date: Tue, 24 Sep 2019 19:21:18 GMT

< Location: http://localhost:8080/

< Content-Length: 0

< Server: Jetty(9.4.20.v20190813)

<?

* Connection #0 to host localhost left intact

* Issue another request to this URL: 'http://localhost:8080/'

* Found bundle for host localhost: 0x563f476b6a50 [can pipeline]

* Re-using existing connection! (#0) with host localhost

* Connected to localhost (::1) port 8080 (#0)

> GET / HTTP/1.1

> Host: localhost:8080

> User-Agent: curl/7.58.0

> Accept: */*

>?

< HTTP/1.1 200 OK

< Date: Tue, 24 Sep 2019 19:21:18 GMT

< Last-Modified: Tue, 24 Sep 2019 19:12:21 GMT

< Content-Type: text/html

< Accept-Ranges: bytes

< Content-Length: 23

< Server: Jetty(9.4.20.v20190813)

<?

this is the index.html

* Connection #0 to host localhost left intact



查看完整回答
反對 回復 2023-08-23
  • 2 回答
  • 0 關注
  • 205 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號