<html:base>タグ
<html:base>タグは、Struts1で用意されていたタグライブラリである。
このタグは、HTMLの<base>タグを出力するためのタグです。
<base>タグは、<head>タグ内で記述し、<base href=”[絶対パス]”> という書式になります。このタグは、HTMLファイルに相対パスで記述されたURIの基準となるURIを指定します。基準となるURIは、[絶対パス] 部分で指定された絶対パスです。
Struts1
このタグは、リクエスト時にフィルターの機能を用い、URL書き換えをおこなう場合に便利です。URL書き換えをした場合に、見かけ上のURLの階層が変わってしまったりすると、相対パスで記述しているリンクや、画像ファイルが正しくリンクされないようになってしまうからです。
この時に<html:base/>タグを記述していると、相対パスの基準となるURIが固定される(出力されるファイルの階層に固定される)ため、URL書き換えで見た目のURLの階層がいくら変化しても、各リソースのリンクには全く問題がなくなります。
Struts2
Struts2のタグライブラリには残念ながら、<html:base>に代わるものが存在しません。これは、画像やリンクなどの各リソースのURLの指定をするために、<s:url value=”[リソース]”> タグを使うことで、<base> タグを指定する必要がなくなるためだからだろうと思いました。
しかしながら、各リソースのURLを動的に指定する必要がある場合、value属性に、<s:property> タグを入れ込んだりしての、URLの動的作成がうまくいきませんでした(もしかしたら、うまくやれば可能なのかもしれません…) さらに、フィルターによるURLの動的書き換えを組み合わせると、URLが2重になったりと先が見えなかったので、Struts1のように<base>タグを自前で出力させる方法を考えました。
<base>タグの出力
発想はいたって単純ですが、フィルターの処理中に、ベースとなるURLをrequestオブジェクトに保存しておき、viewの部分でそれを取り出し、<base>タグのhref属性に指定してあげるという方法です。
ポイントはベースとなるURLをどのように作成するところですが、以下のようにすることで簡単に求められそうです。
//ベースURLの設定
String url = req.getRequestURL().toString();
int len = url.length() – req.getRequestURI().length();
req.setAttribute(“htmlbase”, url.substring(0, len) + req.getContextPath() + “/”);
そして、viewでは以下のように呼び出すだけです。
<%@taglib prefix=”s” uri=”/struts-tags” %>
<head>
<base href=”<s:property value=”#request.htmlbase”/>”/>
</head>
以上で、Struts1の<html:base/>の処理と同様のことができるようになりました。
※他にもっと良い方法があるかもしれませんが、リソースのURLを動的に作成したり、フィルターにてリクエストのURLを書き換えてフォワードさせたりという処理を組み合わせると、思うような処理ができませんでした。
また、Struts2で、リクエストのURLを書き換え、フォワードしてアクションを実行させようとしてもできないトラブルの解決方法は以下を参照ください。
⇒Struts2 RequestDispatcher の動作について