システムプログラム(第9回): JavaによるCGIプログラムの作成(printarg)

                                       筑波大学 システム情報系 情報工学域
                                       新城 靖
                                       <yas@cs.tsukuba.ac.jp>

このページは、次の URL にあります。
http://www.coins.tsukuba.ac.jp/~syspro/2018/2018-06-13 /cgi-printarg-java.html
あるいは、次のページから手繰っていくこともできます。
http://www.coins.tsukuba.ac.jp/~syspro/2018/
http://www.coins.tsukuba.ac.jp/~yas/

JavaによるCGIプログラムの作成(printarg)

普通は、Java 言語で CGI プログラムを作成することはしない。そうではなく、 Java Servlet、Java JavaServer Pages、等の Java のプログラムをサーバ側で 実行するための専用の仕組みを使う。Java Servlet は、CGI のオーバーヘッド を避けるために、考案された仕組みである。CGI とは異なり、 fork + exec が行われないので実行が軽い。

CgiPrintargJava.java

CgiPrintargJava.java は、cgi-printarg.cを Java 言語で記述したものである。関数名や変数名としては、C 言語版と似たも のを使っている。プログラムの説明は、C 言語版を見なさい。

このプログラムは、手続き的に書かれており、オブジェクト指向のプログラム ではない。CGI の仕組みを理解することには適しているが、真似をすべきでは ない。

   1:	
   2:	/*
   3:	  CgiPrintargJava.java -- CGI プログラムに対する引数を表示するプログラム(Java版)
   4:	  ~yas/syspro/www/CgiPrintargJava.java
   5:	  Created on: 2018/07/29 14:15:58   6:	*/
   7:	
   8:	class CgiPrintargJava
   9:	{
  10:	        public static void main(String argv[]) throws java.io.IOException
  11:	        {
  12:	                print_header();
  13:	                print_content();
  14:	        }
  15:	        public static void print_header()
  16:	        {
  17:	                stdout.printf("Content-Type: text/html\n");
  18:	                stdout.printf("\n");
  19:	        }
  20:	        public static void print_content() throws java.io.IOException
  21:	        {
  22:	                stdout.printf("<HTML><HEAD></HEAD><BODY><PRE>\n");
  23:	
  24:	                safe_printenv("REQUEST_METHOD");
  25:	                safe_printenv("SCRIPT_NAME");
  26:	                safe_printenv("QUERY_STRING");
  27:	                safe_printenv("CONTENT_LENGTH");
  28:	
  29:	                String query_string = get_query_string();
  30:	                stdout.printf("query_string:\n");
  31:	                safe_print_string( query_string ); stdout.printf("\n");
  32:	
  33:	                String qv[] = null;
  34:	                if( query_string == null || (qv=query_string.split("&")) == null )
  35:	                {
  36:	                        stdout.printf("Error while parsing query string\n");
  37:	                        stdout.printf("</PRE></BODY></HTML>\n");
  38:	                        System.exit( -1 );
  39:	                }
  40:	                int qc = qv.length;
  41:	                for( int i=0 ; i<qc ; i++ )
  42:	                {
  43:	                        String decoded ;
  44:	                        stdout.printf("qv[%d]: ",i);
  45:	                        safe_print_string(qv[i]);
  46:	                        decoded = decode_url( qv[i] );
  47:	                        stdout.printf("("); safe_print_string( decoded ); stdout.printf(")\n");
  48:	                }
  49:	
  50:	                stdout.printf("</PRE></BODY></HTML>\n");
  51:	        }
  52:	
  53:	        public static String get_query_string() throws java.io.IOException
  54:	        {
  55:	                String request_method = System.getenv("REQUEST_METHOD");
  56:	                if( request_method == null )
  57:	                        return( null );
  58:	                else if( request_method.equals("GET") )
  59:	                {
  60:	                        String query_string = System.getenv("QUERY_STRING");
  61:	                        return( query_string );
  62:	                        /* no cloning is needed because 
  63:	                           a string is immutable in Java. */
  64:	                }
  65:	                else if( request_method.equals("POST") )
  66:	                {
  67:	                        return( read_query_string() );
  68:	                }
  69:	                else
  70:	                {
  71:	                        stdout.printf("Unknown method: ");
  72:	                        safe_print_string( request_method );
  73:	                        stdout.printf("\n");
  74:	                        return( null );
  75:	                }
  76:	        }
  77:	        public static String read_query_string() throws java.io.IOException
  78:	        {
  79:	                String content_length = System.getenv("CONTENT_LENGTH");
  80:	                if( content_length == null )
  81:	                {
  82:	                        return( null );
  83:	                }
  84:	                else
  85:	                {
  86:	                        int clen = java.lang.Integer.parseInt( content_length, 10 );
  87:	                        byte buf[] = new byte[ clen ];
  88:	                        if( buf == null )
  89:	                        {
  90:	                                stdout.printf("read_query_string(): no memory\n");
  91:	                                System.exit( -1 );
  92:	                        }
  93:	                        if( System.in.read(buf) != clen )
  94:	                        {
  95:	                                stdout.printf("read error.\n");
  96:	                                System.exit( -1 );
  97:	                        }
  98:	                        return( new String(buf) );
  99:	                }
 100:	        }
 101:	        public static void safe_printenv( String name )
 102:	        {
 103:	                stdout.printf("%s=",name );
 104:	                String val = System.getenv( name );
 105:	                safe_print_string( val );
 106:	                stdout.printf("\n");
 107:	        }
 108:	        public static void safe_print_string( String str )
 109:	        {
 110:	                if( str == null )
 111:	                {
 112:	                        stdout.printf("(null)");
 113:	                        return;
 114:	                }
 115:	                String safe_str = html_escape( str );
 116:	                if( safe_str == null )
 117:	                {
 118:	                        stdout.printf("(no memory)");
 119:	                }
 120:	                else
 121:	                {
 122:	                        stdout.printf("%s",safe_str );
 123:	                }
 124:	        }
 125:	        public static String html_escape( String str )
 126:	        {
 127:	                int len = str.length();
 128:	                StringBuffer tmp = new StringBuffer( len * 6 );
 129:	                if( tmp == null )
 130:	                        return( null );
 131:	                for( int i = 0; i< len; i++ )
 132:	                {
 133:	                        char c = str.charAt(i);
 134:	                        switch( c )
 135:	                        {
 136:	                        case '&': tmp.append("&amp;");  break;
 137:	                        case '<': tmp.append("&lt;");   break;
 138:	                        case '>': tmp.append("&gt;");   break;
 139:	                        case '"': tmp.append("&quot;"); break;
 140:	                        default:  tmp.append( c );      break;
 141:	                        }
 142:	                }
 143:	                String res = new String( tmp );
 144:	                return( res );
 145:	        }
 146:	        public static String decode_url( String str )
 147:	        {
 148:	                int len = str.length();
 149:	                StringBuffer tmp = new StringBuffer( len );
 150:	                if( tmp == null )
 151:	                        return( null );
 152:	                int i = 0;
 153:	                while( i<len )
 154:	                {
 155:	                        char c = str.charAt(i);
 156:	                        if( c == '%' )
 157:	                        {
 158:	                                String hexstr = str.substring( i+1, i+3 );
 159:	                                c = (char)Integer.parseInt( hexstr,16 );
 160:	                                tmp.append( c );
 161:	                                i += 3 ;
 162:	                        }
 163:	                        else if( c == '+' )
 164:	                        {
 165:	                                tmp.append( ' ' );
 166:	                                i ++ ;
 167:	                        }
 168:	                        else
 169:	                        {
 170:	                                tmp.append( c );
 171:	                                i ++ ;
 172:	                        }
 173:	                }
 174:	                String res = new String( tmp );
 175:	                return( res );
 176:	        }
 177:	
 178:	        public static String getparam( int qc, String qv[], String name )
 179:	        {
 180:	                for( int i=0; i<qc; i++ )
 181:	                {
 182:	                        String nv[] = qv[i].split("=");
 183:	                        if( nv.length == 2 && nv[0].equals(name) )
 184:	                        {
 185:	                                return( nv[1] );
 186:	                        }
 187:	                }
 188:	                return( null );
 189:	        }
 190:	        static java.io.PrintStream stdout = System.out;
 191:	        static java.io.PrintStream stderr = System.err; 
 192:	}

cgi-printarg-java.cgi

Java 言語のプログラムを CGI で動作させるために、簡単なシェルスクリプト を用いる。
   1:	#!/bin/sh
   2:	
   3:	exec java CgiPrintargJava

CGIを実行するためのフォーム

<H2><A ID="cgi-example-get">CGI の GET メソッドを使う例</A></H2>

<FORM ACTION="cgi-printarg-java.cgi" method="get">
    <P>
    姓: <INPUT type="text" name="lastname">
    名: <INPUT type="text" name="firstname"><BR>
    <INPUT type="radio" name="lang" value="C"> C言語 <BR>
    <INPUT type="radio" name="lang" value="Java"> Java言語 <BR>
    <INPUT type="radio" name="lang" value="others"> その他 <BR>
    電子メール: <INPUT type="text" name="email"><BR>
    <INPUT type="submit" value="send"> <INPUT type="reset">
    </P>
</FORM>

<H2><A ID="cgi-example-post">CGI の POST メソッドを使う例</A></H2>

<FORM ACTION="cgi-printarg-java.cgi" method="post">
    <P>
    姓: <INPUT type="text" name="lastname">
    名: <INPUT type="text" name="firstname"><BR>
    <INPUT type="radio" name="lang" value="C"> C言語 <BR>
    <INPUT type="radio" name="lang" value="Java"> Java言語 <BR>
    <INPUT type="radio" name="lang" value="others"> その他 <BR>
    電子メール: <INPUT type="text" name="email"><BR>
    <INPUT type="submit" value="send"> <INPUT type="reset">
    </P>
</FORM>

表示例

CGI の GET メソッドを使う例

姓: 名:
C言語
Java言語
その他
電子メール:

CGI の POST メソッドを使う例

姓: 名:
C言語
Java言語
その他
電子メール:


Last updated: 2018/06/12 22:22:09
Yasushi Shinjo / <yas@cs.tsukuba.ac.jp>