1. ホーム
  2. css

[解決済み] JSPに転送するServletを呼び出すと、ブラウザがCSS、画像、リンクなどの相対的なリソースにアクセス/検索できない

2023-07-13 06:31:16

質問

サーブレットからJSPに転送する際、CSSや画像の読み込み、他のページへのリンクの作成に困っています。具体的には <welcome-file>index.jsp に変更すると、CSSが読み込まれ、画像も表示されるようになりました。しかし、もし私が <welcome-file>HomeServlet に転送し、制御を index.jsp に転送していますが、CSSが適用されず、画像が表示されません。

私のCSSファイルは web/styles/default.css .

私の画像は web/images/ .

こんな感じでCSSにリンクしてます。

<link href="styles/default.css" rel="stylesheet" type="text/css" />

私は以下のように画像を表示しています。

<img src="images/image1.png" alt="Image1" />

この問題はどのように発生し、どのように解決すればよいのでしょうか?


アップデート 1 : アプリケーションの構造など、参考になりそうな情報を追加しました。

header.jsp ファイルは、CSSのリンクタグを記述するファイルです。このファイルには HomeServlet が設定されているのは、私の welcome-fileweb.xml :

<welcome-file-list>
    <welcome-file>HomeServlet</welcome-file>
</welcome-file-list>

サーブレットの宣言とマッピングは、以下のように web.xml :

<servlet>
    <servlet-name>HomeServlet</servlet-name>
    <servlet-class>com.brianblog.frontend.HomeServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>HomeServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>


アップデート2 : サーブレットが正しくマッピングされていないことが原因でした。どうやら、サーブレットを <welcome-file> という URL パターンを持つことができないようです。 / という URL パターンを持つことができません。これは、サイトのルート ディレクトリを表しているのではないので、ちょっと変だと思います。

新しいマッピングは次のとおりです。

<servlet-mapping>
    <servlet-name>HomeServlet</servlet-name>
    <url-pattern>/HomeServlet</url-pattern>
</servlet-mapping>

どのように解決するのですか?

JSP ファイルによって生成される HTML ページ内のすべての相対 URL は、現在のリクエスト URL (ブラウザのアドレスバーに表示される URL) からの相対 URL であり、かつ ではなく でなく、サーバー側の JSP ファイルの位置に対する相対 URL です。つまり、リソースを個別に URL でダウンロードしなければならないのは Web ブラウザであり、ディスクから何らかの方法でインクルードしなければならないのは Web サーバーではありません。

JSP ファイルの場所ではなくサーブレットの URL に相対するように相対 URL を変更する以外に、この問題を解決するもうひとつの方法は、ドメイン ルートに相対するようにする (すなわち / ). この方法では、サーブレットの URL を変更したときに、相対パスをもう一度変更することを心配する必要がありません。

<head>
    <link rel="stylesheet" href="/context/css/default.css" />
    <script src="/context/js/default.js"></script>
</head>
<body>
    <img src="/context/img/logo.png" />
    <a href="/context/page.jsp">link</a>
    <form action="/context/servlet"><input type="submit" /></form>
</body>

しかし、おそらくあなたはコンテキストパスをハードコードしないことを望むでしょう。非常に合理的です。ELでコンテキストパスを取得するには、次のようにします。 ${pageContext.request.contextPath} .

<head>
    <link rel="stylesheet" href="${pageContext.request.contextPath}/css/default.css" />
    <script src="${pageContext.request.contextPath}/js/default.js"></script>
</head>
<body>
    <img src="${pageContext.request.contextPath}/img/logo.png" />
    <a href="${pageContext.request.contextPath}/page.jsp">link</a>
    <form action="${pageContext.request.contextPath}/servlet"><input type="submit" /></form>
</body>

(簡単に短縮できるのは <c:set var="root" value="${pageContext.request.contextPath}" /> として使用され ${root} として使用されます。)

あるいは、読めないXMLや壊れたXMLのシンタックスハイライトを恐れないのであれば、次のようにします。 JSTL <c:url> :

<head>
    <link rel="stylesheet" href="<c:url value="/css/default.css" />" />
    <script src="<c:url value="/js/default.js" />"></script>
</head>
<body>
    <img src="<c:url value="/img/logo.png" />" />
    <a href="<c:url value="/page.jsp" />">link</a>
    <form action="<c:url value="/servlet" />"><input type="submit" /></form>
</body>

いずれにせよ、相対URLを多用する場合、これは逆にかなり面倒です。そのような場合は <base> タグを使うことができます。すべての相対URLは、即座にこのタグに相対化されます。ただし、スキームで始まる必要があります ( http:// , https:// など)。ベースとなるコンテキストのパスをELできちんと取得する方法はありません。 JSTL の助けが必要です。

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="req" value="${pageContext.request}" />
<c:set var="uri" value="${req.requestURI}" />
<c:set var="url">${req.requestURL}</c:set>
...
<head>
    <base href="${fn:substring(url, 0, fn:length(url) - fn:length(uri))}${req.contextPath}/" />
    <link rel="stylesheet" href="css/default.css" />
    <script src="js/default.js"></script>
</head>
<body>
    <img src="img/logo.png" />
    <a href="page.jsp">link</a>
    <form action="servlet"><input type="submit" /></form>
</body>

これには(また)いくつかの注意点があります。アンカー( #identifier の URL)もベースパスからの相対パスになってしまいます! 代わりにリクエストURL(URI)に対して相対化させたいところです。そこで、次のように変更します。

<a href="#identifier">jump</a>

から

<a href="${uri}#identifier">jump</a>

それぞれの方法には、長所と短所があります。どちらを選ぶかはあなた次第です。少なくとも、この問題がどのように発生し、どのように解決するかは理解できたはずです :)

こちらもご覧ください。