Java:サーブレットに与えられたURLの解析
サーブレットを作成してTomcatに配備し、これとApacheを連携させてサービスを構成するというやり方は良くあると思うのだが、その場合にサーブレット側に与えられたURLを解析したい場合がある。
実際の問題
こんなサーブレットを作成する。
import javax.servlet.*;
import javax.servlet.http.*;
public class SomeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
String uri = req.getRequestURI();
System.out.println(uri);
}
}
すると、uriの値は、サーブレットがどのように配備されているか(tomcat上のどんなコンテキストパスになっているか)によって変わってきてしまうのである。例えば、ROOT.warとして配備した場合とfoobar.warとして配備した場合とで異なってくる。
例えば、「/sample/index.html」が呼び出された場合、ROOTではこのままだが、foobarの場合のURIは「/foobar/sample/index.html」になっている。
そこで、tomcat上に配備されたコンテキストパスによって、調整しなければならない。
解決方法
tomcat上のコンテキストパスは以下のように取得する。
String contextPath = req.getContextPath();
ここにはROOTの場合なら空文字列、foobarの場合なら「/foobar」が入ってくる。したがって、元々の「/sample/index.html」を取得する方法としては以下だ。
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
String contextPath = req.getContextPath();
String uri = req.getRequestURI();
String realUri = uri.substring(contextPath.length());
}
これでtomcat上の配備コンテキストパスがどうであろうが常に所望のURIを取得することができる。
その他apacheの後ろ側にtomcatが配備されている場合のいろいろ
ウェブ検索してみると、元のURLを取得する方法として以下があると言うのだが、単純には使えないようだ。未だにどうやって使用するのかわからない。
HttpServletRequest reqがあるとして。。。
String[]attr = new String[] {
"javax.servlet.forward.request_uri",
"javax.servlet.forward.context_path",
"javax.servlet.forward.servlet_path",
"javax.servlet.forward.path_info",
"javax.servlet.forward.query_string"
};
Arrays.stream(attr).forEach(s-> {
System.out.println(s+ ":" + req.getAttribute(s));
});
試してみると、すべてnull値になっている。
また、以下の属性もある。
String[]heads = new String[] {
"X-Forwarded-For",
"X-Forwarded-Proto",
"X-Forwarded-Port",
"X-Forwarded-Host"
};
Arrays.stream(heads).forEach(s-> {
System.out.println(s+ ":" + req.getHeader(s));
});
が、値がとれるのは、X-Forwarded-For、X-Forwarded-Hostのみであった。