JSPに転送するサーブレットを呼び出すと、ブラウザはCSS、画像、リンクなどの相対リソースにアクセス/検索できません。


83

サーブレットを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パターンを設定できなくなります。これ/はサイトのルートディレクトリを表していないので、ちょっと奇妙だと思います。

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

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

アップデート2をありがとう、私のcssがロードされなかった理由を理解しようとして、数時間壁に頭をぶつけていました。(注釈として/を持っていた)。
kiwicomb123 2017年

回答:


101

JSPファイルによって生成されたHTMLページ内のすべての相対URLは、現在の要求URL(ブラウザーのアドレスバーに表示されるURL)に相対的であり、サーバー側のJSPファイルの場所に相対的ではありません。つまり、これらのリソースをURLで個別にダウンロードする必要があるのはウェブブラウザであり、何らかの方法でディスクからリソースを含める必要があるウェブサーバーではありません。

相対URLを変更して、JSPファイルの場所ではなくサーブレットの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は即座に相対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>

これには(再び)いくつかの注意点があります。アンカー(#identifierURL)もベースパスを基準になります!代わりに、リクエストURL(URI)を基準にして作成します。だから、次のように変更します

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

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

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

参照:


私はこれが理にかなっているように機能することを本当に望んでいましたが、それでもブラウザはファイルを見つけることができません。質問にいくつかの情報(アプリの構造やその他の一般的な情報)を追加しました。助けてくれてありがとう!
Brian DiCasa 2010

3
サーブレットを/(におい、におい;))にマッピングしました。そのため、CSSファイル(実際にはすべてのHTTPリクエスト)もインターセプトします。それらを正しく処理していますか?つまり、localhost:8080 / context / styles / default.cssによってwebbrowserでCSSファイルに直接アクセスできますか?
BalusC 2010

「/」にマップされたときではありません。ただし、「/ HomeServlet」としてマップされている場合は可能です。
Brian DiCasa 2010

最初にマップした理由はわかりません/*が、ある種のフロントコントローラーを作成しようとしている場合は、この回答と、おそらくこの回答を確認することをお勧めします
BalusC 2010

@ BalusC-最初の段落で、「これらのリソースをURLで個別にダウンロードする必要があるのはウェブブラウザであり、何らかの方法でディスクからリソースを含める必要があるウェブサーバーではありません」と述べました。Webサーバーではなく、リソースをフェッチするのはブラウザの責任であることを実際に確認できますか?素晴らしい例やチュートリアルを教えていただければ幸いです。
AbhishekAggarwal19年


2

ヒントとして、実際のHTML出力を分析する必要があります。

このようなパスを与えることは「現在の場所から」を意味しますが、一方、で始める場合/は「コンテキストから」を意味します。


どういう意味かわかりません。cssリンクをこれに変更した場合:
Brian DiCasa 2010

つまり、ブラウザからHTMLソースを表示して、パスが正しいかどうかを確認できます。そうでない場合は、それを正しくするために何をする必要がありますか。
Adeel Ansari 2010

私はソースを表示してきましたが、リンクタグに表示されるのは、質問に投稿したものです。jspに直接リンクすると、ファイルが見つかるのに、転送するとファイルが見つからないのはなぜかわからないと思います。Webアプリのどこからでも見つけられるように、画像をどこに保存できますか?
Brian DiCasa 2010

さて、それはあなたindex.jspがあなたstylesimagesディレクトリと同じ場所/レベルにいるからです。したがって、index.jspウェルカムファイルとして直接使用すると、すべてが魅力のように見えます。一方、サーブレットを介して同じリソースを転送すると、問題は同じではなくなります。[続く...]
Adeel Ansari 2010

@Brian D。:...パスを考慮しない特定のサーブレットにリクエストを送信するには、サーブレットマッピングを使用します。ここで理解する必要がありcontext pathます。/パスで使用されたときに特定の意味を持つドキュメントで見たように、リクエストを転送するか、リクエストをリダイレクトします。スラッシュがないと、コンテキストパスからではなく、現在の場所から取得されます。あなたが今私を捕まえていることを願っています。
Adeel Ansari 2010

0

ウェルカムページはそのサーブレットとして設定されています。したがって、すべてのcss、imagesパスは、そのサーブレットDIRを基準にして指定する必要があります。これは悪い考えです!なぜサーブレットをホームページとして必要なのですか?.jspをインデックスページとして設定し、そこから任意のページにリダイレクトしますか?

dbからフィールドにデータを入力しようとしているのは、サーブレットを使用している理由です。


4
サーブレットを(MVC)フロントコントローラーとして使用することは確かに悪い考えではありません
BalusC 2010

0

Spring MVCを使用している場合は、静的コンテンツのデフォルトのアクションサーブレットを宣言する必要があります。spring-action-servlet.xmlに次のエントリを追加します。それは私のために働いた。

注:すべての静的コンテンツはWEB-INFの外部に保管してください。

<!-- Enable annotation-based controllers using @Controller annotations -->
<bean id="annotationUrlMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="order" value="0" />
</bean>

<bean id="controllerClassNameHandlerMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
    <property name="order" value="1" />
</bean>

<bean id="annotationMethodHandlerAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

0

あなたのアップデートに関しては、私は背後にある理由で混乱しました。もう少し深く掘り下げて、この宝石を見つけました:

  • yoursite.comはyoursite.com/になります
  • yoursite.com/はディレクトリであるため、welcome-file-listがスキャンされます
  • yoursite.com/CMSは最初のウェルカムファイル(welcome-file-listの「CMS」)であり、/ CMSからMyCMSサーブレットへのマッピングがあるため、サーブレットにアクセスできます。

ソース:http//wiki.metawerx.net/wiki/HowToUseAServletAsYourMainWebPage

したがって、マッピングは意味があります。

そして、相対リンクのsrc / hrefとして$ {pageContext.request.contextPath} / path /を自由に使用できるようになりました!




0

こちらもお試しいただけます。これは私にとってはうまくいき、簡単だからです。

<style>
    <%@ include file="/css/style.css" %>
</style>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.