[???] /
[Java FAQ] / [S125]
S125: Servlet(プログラミング)
[S125-Q01]
Cookieを使ったセッション管理はできますか?
[S125-A01]
できます。しかし、java.servlet.http.HttpSession でそのものずばりの仕組みが
用意されています。
ただし、セッション管理はデフォルトでは数十分でタイムアウトになりますので、
長期にわたり情報を保存したい場合はCookieをそのまま使った方が良い場合もあります。
ちなみに、java.servlet.http.HttpSessionはCookieを使って実現されています。
詳しい説明は、http://java.sun.com/products/servlet/2.2/javadoc/javax/servlet/http/HttpSession.html から入手できます。
[S125-Q02]
CGIでヘッダに「Location: http://...」と記述するのと同様な URLのリダイレクトを
おこないたいのですが?
[S125-A02]
HttpServletResponse#sendRedirect(String)を使ってください。
[S125-Q03]
AppletやJavaアプリケーションで生成したオブジェクトをServletにわたす事はできますか?
[S125-A03]
できます。Object Serialization を使ってオブジェクトをServletに転送します。
以下はMessengerという型のオブジェクトをServletに渡す例です。
----------------------------------------------------------------------------
== 送りつける方 ==
URL url = new URL(http://ホスト名:ポート/サーブレットを指すパス);
URLConnection conn = url.openConnection();
conn.getDoOutput(true);
conn.setUseCaches(false);
ObjectOutputStream ObjOut = new ObjectOutputStream(conn.getOutputStream());
Messenger messenger = new Messenger();
....
ObjOut.writeObject(messenger);
ObjOut.close();
== 受け取るServlet ==
public void service(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException {
InputStream in = request.getInputStream();
ObjectInputStream ObjIn = new ObjectInputStream(in);
Messenger messenger = (Messenger)ObjIn.readObject()
......
}
----------------------------------------------------------------------------
このほかにもSorblet< http://jeeves.java-conf.gr.jp:8512/takagi/sorblet.html >という仕組みを使っても実現できます。
[S125-Q04]
Servletで日本語を表示するために特別な事をする必要はありますか?
[S125-A04]
なにもしなくても大丈夫なServletエンジンもあるようですが、基本としては
下記の設定のどちらかを行う必要があります。
1. javax.servlet.http.HttpServletResponse#setContentTypeにキャラクタセットを設定する
例
response.setContentType("text/html; charset=iso-2022-jp");
2. OutputStreamWriter() でエンコーディング名を指定する。
例
PrintWriter pw = new PrintWriter(
new OutputStreamWriter(
response.getOutputStream()
,response.getCharcterEncoding()
)
);
[S125-Q05]
ServletでRuntime#exec()からシェルがうまく実行されないのですが?
[S125-A005]
Servletを実行しているスレッドがRuntime.exec()を実行しているスレッドの終了
まで待つようにしてください。そうしないとシェルの結果を受け取れないのでうまく
実行されていないようにみえるようです。
下記 URL の「3.6 マルチスレッドと Servlet」に参考になるプログラムがあります。
http://www.netpotlet.com/books/shuwa/java-servlet/resource.html
[S125-Q06]
Servletでnativeメソッドは使えますか?
[S125-A06]
つかえます。Javaのクラスとネイティブなライブラリは下記の条件を満たすように配置
してください。
* JNIを実装しているJavaのクラスを、Servletエンジンが参照するCLASSPATHに登録して
あるディレクトリに置く。
* UNIXならライブラリ(*.so)をLD_LIBRARY_PATHに設定されているディレクトリに置く。
* WINならライブラリ(*.DLL)をOSが探せる適当なフォルダに置く。
[S125-Q07]
Servletから出力されるデータをブラウザで「ファイル名をつけて保存」するときの
ファイル名のServletで指定できるようにしたいのですが、可能でしょうか?
[S125-A07]
トリッキーですが、できなくはないです。
まず、ダウンロードさせたいファイルを、指定したいファイル名で保存します。
次に、httpServletResponse#sendRedirect(String)を使って先に保存したファイルに
リダイレクトさせます。
これでうまくいかない場合はブラウザやWebサーバの設定を見直して見てください。
[S125-Q08]
Servlet でクライアントの IP アドレスを取得したいのですが?
[S125-A08]
javax.servlet.ServletRequest#getRemoteAddr を使えば取得できますが、プロキシサーバ
を経由している場合はプロキシサーバのアドレスが返ってきてしまいます。
残念ながら確実にクライアントのIPアドレスを取得できる方法はなさそうです。
[S125-Q09]
Servletエンジンによって java.servlet.http.HttpServletRequest#getCharacterEncoding()
の返す値がまちまちなのですが?
[S125-A09]
JSDK 2.1 はブラウザが送りこんでくる Accept-Charset をそのまま返すようです。
IE は Accept-Charset を送りこまないので IE から起動すると null
になります。
Apache JServ 1.0 は Servlet Engine が起動されたときの環境から
拾うようで、英語環境で起動すると、ISO-8859-1 になります。
試しに、
response.setContenyType("text/plain; charset=iso-2022-jp");
をServletに追加すると Apache JServ 1.0 は Character Encoding が
iso-2022-jp となりますが、JSDK2.1 は相変わらず Accept-Charset を
返してきます。JSWDK 1.0 EA はブラウザが IE でも Netscape でも
content-type をセットしても null しか返ってきません。
このメソッドが返す値はエンジンの実装依存でしかも、信用できない場合もありそうです。
[S125-Q10]
Servlet でファイルのアップロードを行いたいのですが?
[S125-A110]
有益な参考文献が下記の URL で公開されています。
http://www.java-conf.gr.jp/wg_bof/servlet/docs/980403/FileUpload.doc.html
http://www.servlets.com/resources/com.oreilly.servlet/index.html
[S125-Q11]
Servlet で基本認証を実現したいのですが?
[S125-A11]
レスポンスに WWW-Authenticate ヘッダを追加し、javax.servlet.http.httpServletResponse.SC_UNAUTHORIZEDを返せば実現できます。
次のようなコーディングになります。
-----------------------------------------------------------------------------
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
...
String auth = req.getHeader("Authorization");
...
if( auth == null ) {
res.setHeader("WWW-Authenticate", "BASIC realm=\"Milkyway\""); //追加
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
}
-----------------------------------------------------------------------------
[S125-Q12]
JServで Toolkit.getDefaultToolkit().createImage を使用しているのですが
Can't connect to X11 window server using ':0.0'
as the value of the DISPLAY variable. というエラーが発生します。
[S125-A12]
xhost を実行して環境変数 DISPLAY を設定してJservを実行する必要があります。
1. xhost + を実行
2. DISPLAY変数を設定
3. jserv.properties 内で wrapper.env.copy=DISPLAY を追加
詳細は下記URLを参照してください。
http://dev.apache.org/jyve-faq/Turbine/screen/DisplayQuestionAnswer/action/SetAll/project_id/1/faq_id/1/topic_id/4/question_id/289
[S125-Q13]
サーブレットのsession trackingで、セション終了時に一時ファイルの削除を
行ないたいのですが?
[S125-A13]
セッションが invalidate() されるときに登録された全データについて removeValue()
が実行されるようなので,セッション生成時に後処理用のHttpSessionBindingListner
オブジェクトを生成し登録しておけば実現できます。
例えば、次のようなコーディングになります。
-----------------------------------------------------------------------------
:
HttpSession session = request.getSession(true);
session.putValue("this.invalidated.action", (Object) new Scavenger());
:
class Scavenger implements HttpSessionBindingListener {
public void valueBound(HttpSessionBindingEvent event) {
}
public void valueUnbound(HttpSessionBindingEvent event) {
// ファイル削除のためのロジック
}
}
-----------------------------------------------------------------------------
[S125-Q14]
Servlet でファイルのダウンロードをさせるので、Servletにセキュリティの設定を
行いたいのですが?
[S125-A14]
Signed Applet のような セキュリティの考え方はServlet は無いことはないのですが、
これはどこかの Web サーバ上に置いてある Servlet のクラスを違う Web サーバ
(Servlet Engine) に引っ張ってきて実行する場合に適用されます。
このような使い方をするのはまれで、普通は Servlet のクラスはローカルに置きますので Sandbox のようなセキュリティモデルはあまり意味がありません。
ファイルをダウンロードする Servlet にクラックの危険があるかないかを調べるのは
かなり難しいでしょう。
危険を回避するには Servlet Engine 起動時に policy を与えて Servlet Engine の
動作そのものを制限するしかないようです。
contributor: Takeshi Fujisawa, Nishino
コメントの送り先:Java FAQ BBS