ラベル Servlet の投稿を表示しています。 すべての投稿を表示
ラベル Servlet の投稿を表示しています。 すべての投稿を表示

2013年3月7日木曜日

サーブレットで非同期処理

サーブレットで非同期処理をするためのAsyncContextというクラスがServlet3.0から追加されている。

そもそもサーブレットでは時間のかかる処理を書いたり、スレッドを作りバックグラウンドで処理をしてはいけないという決まりがあるらしい。しかしTomcatなど特にチェックなどしておらずやろうと思えばできてしまうため結構使っている人も多いのではないでしょうか?(自分もそうです)

そういう場合にServlet3.0からはAsyncContextを別スレッドを使って実行することができるようです。

2013年1月5日土曜日

サーブレットでリクエストパラメータを書き換える

サーブレットにリクエストパラメータを書き換えて渡したいときの方法。たぶんFilterを使っても同じことができると思うが、今回はRequestDispatcherでforwardする方法を使ってみた。

以下のサンプルでは /myWrapperServlet.do で受けたリクエストのパラメータ名p2をp1に書き換えて /myServlet.doに渡す。パラメータの書き換えは直接できないので、少々わかりにくいが HttpServletRequestWrapperのサブクラスを作り元のリクエストをラップしてgetParameter()などで書き換えロジックを書いてやる必要がある。パラメータ名p2をp1に書き換えるにはgetParameter()でパラメータp1を要求されたときに元リクエストのパラメータp2の値を返すようにする。
package test;
// import文は省略

public class MyWrapperServlet extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {

    // パラメータの書き換えを行うHttpServletRequestを設定して
    // myServlet.doにforward
    RequestDispatcher dispatcher = req.getRequestDispatcher("/myServlet.do");
    MyServletRequestWrapper _req = new MyServletRequestWrapper(req);
    dispatcher.forward(_req, res);
  }

  public static class MyServletRequestWrapper extends HttpServletRequestWrapper {

    public MyServletRequestWrapper(HttpServletRequest request) {
      super(request);
    }

    @Override
    public String getParameter(String name) {
      if ("p1".equals(name)) { name = "p2"; }
      return getRequest().getParameter(name);
    }

    @Override
    public String[] getParameterValues(String name) {
      if ("p1".equals(name)) { name = "p2"; }
      return getRequest().getParameterValues(name);
    }
  }

}

以下はweb.xmlに記述するエントリの例。
<servlet>
  <servlet-name>myServlet</servlet-name>
  <servlet-class>test.MyServlet</servlet-class>
</servlet>
<servlet>
  <servlet-name>myWrapperServlet</servlet-name>
  <servlet-class>test.MyWrapperServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>myServlet</servlet-name>
  <url-pattern>/myServlet.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
  <servlet-name>myWrapperServlet</servlet-name>
  <url-pattern>/myWrapperServlet.do</url-pattern>
</servlet-mapping>

結果として上URLのリクエストが下URLのリクエストと同じになりサーブレットtest.MyServletクラスが呼び出される。
http://{server}:{port}/myapp/myWrapperServlet.do?p2=abcdefg
http://{server}:{port}/myapp/myServlet.do?p1=abcdefg

パラメータ名を書き換えるのでMyServletRequestWrapperクラスの他メソッドも(特にパラメータ名に関連するもの)もちゃんと実装したほうが良いと思うのだが、とりあえず動くので今回はここまで…