スポンサーリンク

今から5分で,Tomcatの使い方を身に付けよう (Servlet・JSPアプリが動く仕組みを理解)

今から5分で,Tomcatを動かし,サーブレットやJSPも動かす。

その動作する仕組みも理解する。


サーバサイドJavaの入門の,一番最初の取っ掛かりとして利用できるページとして使ってほしい。

初学者に,独学を開始するための軌道に乗ってもらうことが目的。



環境:

  • Windows7 x64


前提:

  • JDKがインストール済みで,binにPATHが通っていること。


では,今から5分でTomcatを習得しよう。


(1)Tomcatのダウンロードと起動

インストール

コントロールパネル→システムとセキュリティ
→システム→システムの詳細設定→環境変数

から,環境変数を登録。

  • キー:JAVA_HOME
  • JDKのインストールフォルダ(binの上)

Tomcat 6 Downloads
http://tomcat.apache.org/download-60.cgi

↑のページから,64-bit Windows zip
をダウンロード。

展開。インストール完了。

起動と停止

bin\startup.bat
を実行。


http://localhost:8080/
にアクセス。


「If you're seeing this page via a web browser, it means you've setup Tomcat successfully. Congratulations!」
と表示される。


コマンドプロンプトを閉じればサーバも停止する。


インストールも起動・終了も,非常に簡単という事が分かった。

なお,サービスとしてインストールすれば,OS起動時に自動的に常駐などもできる。


セッション管理の様子を調べる

管理用のユーザを追加する。

conf\tomcat-users.xmlを開く。

tomcat-usersタグ内の最下部に,下記を追記。

  <role rolename="manager-gui"/>
  <user username="tomcat" password="tomcat" roles="manager-gui"/>


サーバをまた起動。


左側の

  • Administration→Tomcat Manager

を開く。

BASIC認証のユーザ名とパスワードは,tomcat/tomcat。


「Tomcat Webアプリケーションマネージャ」が開く。

現在のTomcatサーバにインストールされている「アプリの一覧」と,各アプリごとの「セッション有効期限」が表示される。

アプリの一覧とは,つまり Tomcatのインストールディレクトリのwebappsフォルダ内にあるフォルダの一覧である。



アプリケーション一覧の中の「/manager」の欄だけ,セッション数が 1 になっている。

つまり,「いま自分自身がTomcatの管理UIにアクセスしている」という事だ。

この 1 をクリック。


Session Idの欄に,有効なセッションのIDが表示される。

これは,Tomcatが管理しているCookieの一覧である。

現在表示されているのは,この画面を見ている自分自身ということになる。


ためしに,Firefoxでアクセスしているなら,FirebugのCookieのタブから「JSESSIONID」の中身を見てみる。

画面上に表示されているセッションIDと同じものが表示されるはずだ。



アプリケーション一覧に戻って,/examples にアクセスしてみる。

サンプルアプリがソースコード付で閲覧できる。

※あとで全部のページを読んでおくと良い。


ためしにどれか1つのサンプルにアクセスしてみると,

/examples というパス専用のJSESSIONIDが発行される。

※Cookieはドメインごとではなく,Pathごとに生成される。

※参考:クッキーのパス設定
http://surferonwww.info/BlogEngine/po...

これで,何もしなくてもTomcatが自動的にCookieでセッション管理してくれる,ということが分かった。


(2)アプリを作成して動かす

HTMLのみ

まず,シンプルな静的ファイルだけで,Webページを表示させてみる。



webappsフォルダ内に「hoge」フォルダを作成。

その中にa.htmlを作成。

中身は「This is a.」とだけ書く。



サーバを起動。

下記のパスにアクセス。

無事に表示される。


Tomcat管理画面から,アプリケーション一覧を開くと,hoge が存在する。

webapps内にフォルダを作るだけで,WebアプリないしWebコンテンツを発信できることが分かった。


URLを変える

webapps内に作成したフォルダ名とは違う名称で,URLを打ち込めるようにする。

conf\server.xml 内の,

  • Server
    • Service
      • Engine
        • Host

という要素の中に,下記を追記。

        <Context path="/fuga"
                 docBase="(Tomcatルート)\webapps\hoge"
                 debug="0" reloadable="true">
        </Context>

特定のフォルダを,特定のURLでアクセスできるように設定している。


サーバを起動。

下記のURLにアクセス。

これで,URLを変更できることが分かった。


参考:

コンテキストパスの設定−tomcatの設定
http://www.zealseeds.com/SysDevTech/a...

サーブレット

下記のファイルを作成。


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("<body>");
        out.println("<h1>Hello World!</h1>");
        out.println("</body>");
        out.println("</html>");
    }
}


Tomcatに付属するJARをくっつけて,コンパイル。

javac -classpath "(Tomcatインストールフォルダ)\lib\servlet-api.jar" HelloWorld.java 


出来上がったclassファイルは,webapps\hoge\WEB-INF\classes というフォルダを作って中に置く。


次に,今作ったWEB-INFフォルダ内に,下記のような web.xml を作成。

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">

  <servlet>
    <servlet-name>HelloWorldName</servlet-name>
    <servlet-class>HelloWorld</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>HelloWorldName</servlet-name>
    <url-pattern>/HelloWorldPage</url-pattern>
  </servlet-mapping>

</web-app>

タグの説明:

  • servlet-class:サーブレットのクラスファイルの名前を指定。
  • servlet-name:好きな名前をつける。各サーブレットを一意に識別するIDのようなもの。
  • url-pattern:そのサーブレットにアクセスする際のURLを指定。

ひもづけの説明:

  • servletタグ内では,サーブレットの実体を列挙。
  • servlet-mappingタグ内では,URLを列挙。
  • そして,両者をひも付けるのがservlet-name。

これで,サーバを起動。

下記のURLにアクセス。


Hello, World! と,サーブレットにより出力される。


このように,クラスファイルを配置して,XMLでマッピングすれば,所定のURLでアクセスできるということが分かった。



フォルダ構成の参考:

Tomcat−2.プログラム配置・実行
http://www.javaroad.jp/opensource/js_...

  • J2EE Webアプリのフォルダ仕様の図解が有
JSP

今度はJSPを動かしてみる。


webapps\hoge内に,fooというフォルダを作り,bar.jspを作成。

<HTML>
<BODY>
<%= "Hello, " + "World" %>
</BODY>
</HTML>

下記のURLにアクセス。

JSPによってHello, Worldと表示される。



ここで,下記のファイルが生成されているので,中身を見てみよう。

  • (Tomcatルート)\work\Catalina\localhost\fuga\org\apache\jsp\foo\bar_jsp.java

いつの間にこんなファイルが?と思うだろう。

中身がすごいことになっている。

package org.apache.jsp.foo;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class bar_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

  private static java.util.List _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.AnnotationProcessor _jsp_annotationprocessor;

  public Object getDependants() {
    return _jspx_dependants;
  }

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
  }

  public void _jspDestroy() {
  }

  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("<HTML>\r\n");
      out.write("<BODY>\r\n");
      out.print( "Hello, " + "World" );
      out.write("\r\n");
      out.write("</BODY>\r\n");
      out.write("</HTML> ");
    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else log(t.getMessage(), t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

これは,bar.jsp が自動的に Tomcat によって変換されて,サーブレット化した姿だ。

HTMLの1行ずつを out.write するようなプログラムになっている。


これで,JSPは「実行時にはサーブレットに変換されて,サーブレットとして動作している」ことが分かった。


静的コンパイル言語で,動的にWebページを表示する仕組みを見てみた。

PHPやRubyなどのスクリプト言語とはだいぶ異なるのを実感できたはず。


ここまでで,Tomcatを導入し,サーブレットとJSPを動かすことができた。


仕組みを補足

  • Tomcatwebコンテナ。下記を包含する。
    • Coyote=HTTPサーバ。HTTPリクエストを受理する。
    • Catalinaサーブレットコンテナ。必要に応じてJavaプログラムをサーバ上で動かす。

Tomcatがインストールされたディレクトリ(binとかの上のフォルダ)を,CATALINA_HOME と呼ぶ。

TomcatとかJavaの世界に片足を突っ込んでみて気になったところ
http://d.hatena.ne.jp/kanonji/2012040...

  • coyote単体でもWebサーバとして動作するが,Apacheのほうが広く使われているので,連携させることが多い
  • Tomcatのディレクトリ構成図あり。bin, conf, logs, webappsなど

注:Tomcatが起動できない時


もしサーバ起動時にエラーが発生したら,エラーログを閲覧する。

logs\catalina.2013-MM-DD.log

SEVERE: StandardServer.await: create[8005]: 
java.net.BindException: Address already in use: JVM_Bind
	at java.net.DualStackPlainSocketImpl.bind0(Native Method)
	at java.net.DualStackPlainSocketImpl.socketBind(Unknown Source)
	at java.net.AbstractPlainSocketImpl.bind(Unknown Source)
	at java.net.PlainSocketImpl.bind(Unknown Source)
	at java.net.ServerSocket.bind(Unknown Source)
	at java.net.ServerSocket.<init>(Unknown Source)
	at org.apache.catalina.core.StandardServer.await(StandardServer.java:406)
	at org.apache.catalina.startup.Catalina.await(Catalina.java:676)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:628)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)

ポートの競合が発生している。

createの後に書いてあるポート番号が原因。


conf\server.xmlで,ポート設定を変更して解決。

<Server port="8005" shutdown="SHUTDOWN"><Server port="18005" shutdown="SHUTDOWN">

Tomcat5.5
http://www.ne.jp/asahi/hishidama/home...

  • netstat -oan | findstr 8005
  • tasklist | findstr (pid)

この先

ここまで来れば,JavaでWebアプリを開発するための入門知識を得たことになる。

独学を開始するための軌道に乗れたはずだ。


あとは,下記のページなどを参考にしながら,プログラミングの作法やフレームワークなどの知識を増やしていくと良い。


現状で,スクラッチからJavaでWebアプリを作成する,などという事はありえない。

必ずStrutsなどのオープンソース・フレームワークを利用する。

なので,それらを学ぶ段階に入る前の前準備として,ざっと眺めて体験しておくのが良いだろう。

サーバサイドJavaの入門用リンク集 (Tomcat上でサーブレット&JSPを動かす)
http://language-and-engineering.hatenablog.jp/entry/20120903/ServerSideJavaSe...