[解決済み] JSPに転送するServletを呼び出すと、ブラウザがCSS、画像、リンクなどの相対的なリソースにアクセス/検索できない
質問
サーブレットから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-file
で
web.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>
それぞれの方法には、長所と短所があります。どちらを選ぶかはあなた次第です。少なくとも、この問題がどのように発生し、どのように解決するかは理解できたはずです :)
こちらもご覧ください。
関連
-
[CSSチュートリアル】CSS たった1行のコードでアバターと国旗の一体化を実現
-
[CSSチュートリアル】overflow:hiddenの役割を解説(overflow hidden、clear float、外周マージンの崩れを解決する)。
-
[CSSチュートリアル】CSSのクラスとidの共通命名規則
-
[CSSチュートリアル】CSSの新機能には、ページの再描画や並び替えの問題をコントロールする機能が含まれています。
-
[CSSチュートリアル】CSSカウンターを使った数字の並びの美化方法
-
[CSSレイアウト例】CSSで中央揃えを実現する方法N種
-
[CSSチュートリアル】ピュアCSSで作るスクロールシャドウ効果
-
[CSSチュートリアル】SVGを使ったCSSアニメーションでエネルギーフローを表現する
-
[解決済み] 背景画像データをCSSにBase64で埋め込むのは良い方法ですか、悪い方法ですか?
-
[解決済み】CSSでテキストを挿入する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[CSSチュートリアル】Pure CSSカスタム複数行抜け問題(原理から実装まで)
-
[CSSチュートリアル】CSS+HTMLで実現するトップナビゲーションバー機能
-
[CSSチュートリアル】CSSを解析して、画像のテーマカラー機能を抽出する(コツ)
-
[CSSチュートリアル】CSSでemを開く正しい方法 詳細へ
-
[CSSチュートリアル】ネイティブCSSでテキストの無制限回転を実現する汎用的な方法
-
[CSSチュートリアル】ボックス内の複数要素を両端揃えの効果で実現するCSS
-
[Div+CSSチュートリアル】divの背景を透明にする設定例
-
[CSSチュートリアル】擬似要素で実現する中空三角矢印とXアイコンの例
-
[css3]赤いパケットのジッター効果を実現するCSS3
-
[CSSチュートリアル】インタビュー必見!聖杯レイアウトとダブルウィングレイアウトの違いとは?