« 09.30 止めの一日 | ココ | 10.07 ついにやってきたか »

2009年10月 1日

WebDAVServletのルートディレクトリを変える  このエントリーを含むはてなブックマーク 

OpenLaszloで何かをしようとして、途中でWebDAVの機能が使えればと思ったのでちょっと寄り道。

WebDAVの機能を実装させようとすると、Java(Tomcat)やとorg.apache.catalina.servlets.WebdavServletというサーブレットを使うと便利なんやけど、これは、どうもURLパターンをどう指定しようとも、Webappのルートディレクトリがルートとして固定されて表示されるらしく。

つまり、"http://server:port/context/servlet-urlpattern/subdir/file"で、fileの場所は"$Webapp/subdir/file"になってしまう。これだと、常に$Webapp/の中身は見えてしまうことに(もちろんWEB-INFは見えないんやけど)。これじゃー$Webapp/lpsディレクトリを見えなくした意味が全くねーじゃん!! ということに。少なくとも、"$Webapp/somewhere/subdir/file" が表示されるようになってもらわないと、ということで格闘すること1週間あまり。えー納期間近の影響もあり全然できんかったわけで(おまけに寝不足になるし、目がしゅばしゅばするし)。

最終的にはできたんやけどね(デスクトップがGnomeからKDEに変わりました…メモリ使いすぎるんやもん、Gnomeが)。

  • サーブレットのフィルターを作る
  • HttpServletRequestWrapperを作る

やったのは2つ。まーURL書き換えるのとかってフィルターなんやろうな、と思ってたし、WebdavServletを派生させるとかいう解もなくはないけど…ライブラリを別に読み込む必要があるのでそれは出来れば避けたい。ということで。

で、フィルターを作って、フィルターから読ませたいディレクトリのURLからディスパッチャー作ってForwardさせればいいのかと思ったら、そうすると501エラーが起こる…実装されてないってどういうこと?? sendRedirectでリダイレクトをさせるとしっかり強制的に読み込ませるディレクトリを摺りかえられるんやけど、これではクライアントに移動先のURLが通知されてしまうので "http://server:port/servlet-urlpattern/somewhere/subdir" とかになっちゃうんよね…不恰好。
Forwardしてエラーになるのは、どうやらfilterConfig.getServletContext().getRequestDispatcher("newpath").forward(request, response) でやると、WebdavServletクラスのdoPropFind()は実装されていないことになって、doGet/doPostしか呼び出せないっぽい…なんといらんことを。

なので、リクエストオブジェクトのメソッドをオーバーライドをしてサーバーを騙せないかを試すことに(大元のRequestURIは変えない)。フィルターを通るときにやってくるrequestは、ServletRequestの型で書いてあるけど今回の場合実際はHttpServletRequestなので、HttpServletRequestWrapperを作って getPathInfo() とgetServletPath() をオーバーライドする。

  • getPathInfo() の戻り値の先頭に"/somewhere"を入れる
  • getServletPath() の戻り値は""にする

これが必要。1つ目は、WebdavServletのソースコードを見てどうやらgetRelativePath()が使うのはPATH_INFOだと分かったからで、これは案外うまくいった。しかし、これだけだと表示されるファイル一覧に「自分」が出てくる…これがどうしてか分かるのに数日悩み、ようやくgetServletPath()でサーブレットのURLPatternがあるとダブって表示されるということに行き着いた。

上の図はhttp://server:port/context/files を表示してるけど、$Webapp/files 以下が表示されてて、http://server:port/context を表示しようとしても表示されない。なぜならWebdavServletの対象となるurl-patternに"/files/*" と指定してあるので。これで、ユーザー名ごとにディレクトリを変えたりするなんてことができるようになったぞと。

これが標準のWebdavServletでなんで出来ないんやろうかと不思議に思う…よくある要求やと思うのに。そして、今回の方法はディレクトリがWebappの中にあることが条件となるので、ファイルシステム上の任意の場所にするときにはやっぱりWebdavServletを派生させる必要がある…。

By ただ at 23:38 カテゴリー ; プログラミングとか

« 09.30 止めの一日 | 10月の記事 | 10.07 ついにやってきたか »




トラックバック

このエントリーのトラックバックURL:
http://pinmarch.sakura.ne.jp/mt/mt-tb.cgi/1479