Servlet/JSP

 JavaをつかってのWebアプリケーション開発は、いまでは特に難しいものではなく、情報も多くありますが、いざ個人で使用するとなると少し敷居が高いようです。ひとつはJavaをサポートしているレンタルサーバーが数少ないこと、もうひとつはPHPやPerlに比べて設定が多いことがあると思います。

 最近は、IDE、EclipseやNetBeansなどで、簡単にJavaのWEBアプリケーションの開発が簡単にできると思います。IDEを使うと、ServletやServletコンテナの知識がなくても、とっても簡単にアプリケーションが開発できてしまい、いざ実際のサーバーにデプロイする際につまずいているのを、Webなどの質問で見かけます。

 ここでは、Servletの基本的なところを説明していきたいと思います。ブラウザーからのリクエストの流れは、以下のようになります。
 

Web Browser -> HTTP Server -> Web Container -> Servlet

 Web Containerは、Servlet Containerともよばれ、簡単に言うとServletを実行させる環境です。Tomcatが有名ですが、ここでは、Jettyを使用します。Web ServerとWeb Containerがひとつになっているものも多く、Tomcat、Jettyもそうです。TomcatのHTTP Serverは貧弱なので、HTTP ServerとしてApacheを使用して、Apache JServ Protocol(AJP)でTomcatと連携しているサーバーが多いと思いま、JettyのHTTPは実運用に耐えうるそうですが、ここでは、HTTP ServerとしてLighttpd1.5を使います。

 まずは、HTTP Server、Lighttpd1.5からWeb Containerに受け渡す為の設定に以下を追加します。http://XXX/helloworld/とリクエストが来た際に、AJPでWeb Containerに受け渡す設定です。XXXはサイト名になります。ローカルで試す場合は。http://localhost/helloworld/になります。

server.modules += ( "mod_proxy_backend_ajp13" )
$HTTP["url"] =~ "^/helloworld/" {
   proxy-core.balancer = "round-robin"
   proxy-core.protocol = "ajp13"
   proxy-core.backends = ( "localhost:8009" )
   proxy-core.max-pool-size = 16
}

 Web Container、Jettyの方は、etc/jetty-ajp.xmlを読み込めば、初期設定で以下のように書かれていて8009のポートで受け取ります。

<Call name="addConnector">
   <Arg>
      <New>
         <Set name="port">8009</Set>
      </New>
   </Arg>
</Call>

 この設定で、Web Containerのところまでは、リクエストを導いて来ることができます。
 次は、Web ContainerからServletにリクエストを投げる設定です。それは、デプロイメント・ディスクリプタ、日本語だと配備記述子とよばれるweb.xmlに記述されます。Javaらしからぬファイル名からは推測しずらい呼び名です。Jettyでは、etc/webdefault.xmlに初期設定のweb.xmlがかありますので、これを利用してもいいですが、理解のために簡略したものを使います。

<?xml version="1.0" encoding="UTF-8"?>
<web-app
   xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   metadata-complete="true"
   version="2.5"
>
      <display-name>Hello World</display-name>
      <servlet>
         <servlet-name>helloworld</servlet-name>
         <servlet-class>HelloWorld</servlet-class>
      </servlet>
      <servlet-mapping>
         <servlet-name>helloworld</servlet-name>
         <url-pattern>/</url-pattern>
      </servlet-mapping>
</web-app>

 Jetty 7では、Servlet 2.5に対応しているので、Ver2.5のSchemaを指定しています。Servlet 2.4からweb.xmlがDTDベースからXMLSchema変更されています。Servlet 2.3のweb.xmlですとDOCTYPEで定義がなされています。設定の意味を簡単に説明しますと、<servlet>でServletの定義をしています。<servlet-name>でServletの呼び名を定義し、そのクラスを<servlet-class>に定義します。次に、<servlet-mapping>で、ServletとURLの対応づけを行います。<servlet-name>は<servlet>内で決めた名前を使い、<url-pattern>は、URLのパターンを書きます。ここでは、乱暴に/にしていますので、http://XXX/helloworld/で来たものはすべて、HelloWorld.classが呼び出されます。web.xmlには、もっと多くのことを記述できますが、今回はこれで十分です。

 ここでやっと呼び出されるServletの作ることにします。ファイル名は、HelloWorld.javaで内容は以下のようになります。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorld extends HttpServlet{
   public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException{
      response.setContentType("text/html");
      PrintWriter out = response.getWriter();
      out.println("<html>");
      out.println("<head><title>Hello World!</title></head>");
      out.println("<body>");
      out.println("<h1>Hello World!</h1>");
      out.println("</body>");
      out.println("</html>");
      out.close();
   }
}

 Servletをつくる手初めとしてjavax.servlet.http.HttpServletを継承してHelloWorldというクラスを作ります。そのクラスにGETのリクエストに対応する、doGetというメソッドをオーバーライドします(POSTを処理する際は、doPostをオーバーライドします)。今回は、HttpServletRequest requestは、使用せずにリクエストされたら、HttpServletResponse responseにレスポンスを入れた返すだけのクラスにしてあります。htmlを返しますので、setContentTypeで、”text/html”を指定しています。次に、getWriter()で取得した、文字出力ストリームにどんどん出力していくだけです。出力内容がおわったら、close()で出力を閉じます。

ちなみに、HttpServletにはHTTPのリクエストに対応したメソッドが準備されています。

GET :
 protected void doGet(HttpServletRequest request, HttpServletResponse response)

POST:
 protected void doPost(HttpServletRequest request, HttpServletResponse response)

PUT:
 protected void doPut(HttpServletRequest request, HttpServletResponse response)

DELETE:
 protected void doDelete(HttpServletRequest request, HttpServletResponse response)

HEAD:
 protected void doHead(HttpServletRequest request, HttpServletResponse response)

TRACE:
 protected void doTrace(HttpServletRequest request, HttpServletResponse response)

OPTIONS:
 protected void doOptions(HttpServletRequest request, HttpServletResponse response)

 次にこれをコンパイルします。Servlet周りのライブラリーは、JDKに入っていませんので、Jettyのlibの中にあるservlet-api-2.5.jarをCLASS PATHに指定します。Jettyが、/usr/local/にあるのであれば、以下のようにコンパイルします。

$ javac -classpath /usr/local/jetty/lib/servlet-api-2.5.jar HelloWorld.java

 これででき上がった、HelloWorld.classと先に作ったweb.xmlをWeb Containerから呼び出せるところに置かなければなりません。通常は、webappsの下に置きます。Jettyが、/usr/local/にあるのであれば/usr/local/jetty/webappsです。具体的には、以下のように配備します。

webapps--+--helloworld--+--WEB-INF--+-- web.xml
                                    +--classes--+-- HelloWorld.class

 ファイルを再配置して、/usr/local/jetty/bin/jetty.sh startで、Jettyを起動し、http://XXX/helloworld/とリクエストすれば、”Hello World!”と表示されるはずです。Javaって結構、PHPなどに比べて設定が大変ですよね。PHPとくらべるとJavaは5倍速いというベンチマークを見たことがありますので、古いマシンを使っているものとして、そちらに期待したいですね。

コメントを残す