- PR -

ファイルの相対パス指定について

1
投稿者投稿内容
(株)ぽち
ぬし
会議室デビュー日: 2002/09/10
投稿数: 376
投稿日時: 2002-10-03 12:03
こんにちわ。

かなり初歩的なことなのかもしれませんが、以前から
結構悩んでいたので質問したいと思います。

この話しで出てくるファイルは3つです。
sample.jsp
Sample.class
sample.gif

ディレクトリ構成はこんな感じ
tomcat_home/webapps/hoge/sample.jsp
tomcat_home/webapps/hoge/sample.gif
tomcat_home/webapps/hoge/WEB-INF/classes/Sample.class

各ファイル内容はこんな感じ

---sample.jsp---
<%@ page contentType="text/html; charset=Shift_JIS" %>
<html>
<head>
<title>sample</title>
</head>
<body>
<img src="./sample.gif">
</body>
</html>

---Sample.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Sample extends HttpServlet {
 public void doGet( HttpServletRequest req, HttpServletResponse res )
 throws ServletException, IOException {
  req.getRequestDispatcher( "/sample.jsp" ).forward( req, res );
 }
}



いたって簡単です。


Servletを実行するとJSPに処理を流すだけです。JSPはgifを表示しているだけです。




この場合、Servletを経由しないでjspを表示させた場合、gifは表示されます。
しかしServletを実行してJSPに処理を流した場合、gifは表示されません。

理由はなんとなくはわかっているのです。。
しかし完璧ではなくて。

JSP内でgifを相対パス指定で記述しているため、JSPに直接アクセスした際は
./sample.gifはtomcat_home/webapps/hoge/配下にありますよね。

しかしrequestDispatcherで処理を遷移させた場合、カレントがServletと同じ
場所になるからgifが表示されない。こんな感じなのかなと。

でもなんでそうなるの?という感じで・・。
requestDispatcherというものをよくわかっていないからかもしれません。


また、JSPに直接アクセスする場合、Servlet経由の場合、双方可能性のある
JSP内でgifを相対パスで指定する場合、どちらのパターンからでも表示される
ようにするにはどのようにしたらいいのでしょうか?

絶対パスにしなければならないのでしょうか?
gsg
常連さん
会議室デビュー日: 2002/08/09
投稿数: 20
お住まい・勤務地: 東京都
投稿日時: 2002-10-03 12:55
この件は、「誰が<img src="./sample.gif">を解釈しているのか」
に注目する必要があります。

このタグ(そしてパス)を解釈しているのは、Javaではありません。
クライアントサイドのブラウザです。ブラウザは、今現在表示している
URLを基準にして、相対パスを探しにいっています。おそらく、
Servletは"http://hostname/servlet/Sample"というURLでアクセスされていて
(まあ、予想ですが)、JSPは"http://hostname/sample.jsp"となっているでしょう。

さて、それぞれのURLから、相対パスでたどった先のURLはどこでしょう。
(株)ぽち
ぬし
会議室デビュー日: 2002/09/10
投稿数: 376
投稿日時: 2002-10-03 13:23
>gsg様

引用:

Servletは"http://hostname/servlet/Sample"というURLでアクセスされていて
(まあ、予想ですが)、JSPは"http://hostname/sample.jsp"となっているでしょう。

さて、それぞれのURLから、相対パスでたどった先のURLはどこでしょう。



うーむ、上記ヒントからすると
Servlet経由の場合、ブラウザは
http://hostname/servlet/sample.gifを探す
→表示されない。(ファイルが存在しないから)

Servletを経由しない場合、ブラウザは
http://hostname/sample.gfiを探す
→表示される。(ファイルが存在するから)

ということだと思いました。


この場合、両パターンでgifを認識させる方法としては
・requestDispatcherではなくsendRedirectを使う。

などが考えられますが、sendRedirectだとJSPファイル名が
ブラウザのアドレス欄にのっかるのであまり好ましくありません。


他に何か方法はありますか?


gsg
常連さん
会議室デビュー日: 2002/08/09
投稿数: 20
お住まい・勤務地: 東京都
投稿日時: 2002-10-03 18:45
引用:

(株)ぽちさんの書き込み (2002-10-03 13:23) より:

うーむ、上記ヒントからすると
Servlet経由の場合、ブラウザは
http://hostname/servlet/sample.gifを探す
→表示されない。(ファイルが存在しないから)

Servletを経由しない場合、ブラウザは
http://hostname/sample.gfiを探す
→表示される。(ファイルが存在するから)

ということだと思いました。



はい、そういうことです。相対パスで書く際は、ブラウザが解釈するのだと
いうことを前提にしなくてはなりません。

たとえば、Servletのパスをweb.xmlで<servlet-mapping>をつかって
Mappingしてあげれば、ServletとJSPを同じ深さのディレクトリにおけるので、
何とかできるとは思うのですが、そういった方法ではまずいですか?
ad hoc
会議室デビュー日: 2002/08/03
投稿数: 5
投稿日時: 2002-10-04 09:33
ディレクトリ構成が前述の通りだとすれば
tomcat_home/webapps/hoge/sample.jsp
→http://hostname/sample.jsp
tomcat_home/webapps/hoge/sample.gif
→http://hostname/sample.gif
tomcat_home/webapps/hoge/WEB-INF/classes/Sample.class
→http://hostname/servlet/sample

ブラウザに表示するJSPと実際のservletのURLを同じ場所にしてあげれば定義ファイルを変更しなくても大丈夫ですよね。
tomcat_home/webapps/hoge/servlet/sample.jsp
→http://hostname/servlet/sample.jsp
req.getRequestDispatcher( "/servlet/sample.jsp" ).forward( req, res );

但し、これはスマートな方法ではないのでファイル位置の関係を理解できるようになったらMappingの変更などで対処するようにしてください。
1

スキルアップ/キャリアアップ(JOB@IT)