ウエブアプリケーション 第15回servlet•...
TRANSCRIPT
ウエブアプリケーション第15回 Servlet
2018/1/18海谷 治彦
1
http://www0.info.kanagawa-u.ac.jp/~kaiya/wa/dotcampus ショートコード 212834
目次
• JSP/Servletの対比 (ほぼ復習)• Servletの記述
• Servletのコンパイル
• Servletの配置
• redirect と forward• ウエブアプリに利用可能な通常Javaクラス
2
期末試験について
• やります.• シラバスにそうかいちゃったんで.
• 本,紙類は持ち込み可能とします.• PC, スマフォ,携帯電話,タブレット等はダメよ.
• 基本,知識を問う問題ではなく,理由を問う問題中心になると思います.
3
セットアップしてほしい構成
4
Lenovo : クライアント
Firefox等 : ウエブブラウザ
CentOS 6.5 : サーバー
apache 2.2 : ウエブサーバー
PHP 5.3 : モジュール
Tomcat6 : アプリケーションサーバー
MySQL 5.1 : データベース
HTTP
JVM : モジュール
復習++
JSP and Servlet• 共通点
• どちらもサーバーで実行される.
• すなわち,クライアントに届いた時にはただのHTML• コレがJavaScriptとの大きな違い
• JSP• HTMLにJavaっぽいものを埋め込む.
• 雰囲気はJavaScriptに似てるが,上記のようにサーバー内で実行される.
• phpはコレに考え方が似ている.
• オリジナルのクラス等を作成する場合は,Servletとの連携が必要.
• Servlet• Javaそのもの.
• mainメソッドは書かないのが普通.
• そもそも スーパークラスがフレームワーク的にできている.
• Javaのprint機能でHTMLの行を表示しないと,クライアント側で解釈不能になる.
• どちらかといえば,JSPのサブルーチン的に使われるのが普通.
5
復習
サンプル
6
<HTML><HEAD><TITLE>JSP loop</TITLE></HEAD>
<BODY><ul><%int i;for(i=0; i<10; i++){%><li> number <%= i*3 %><%}%></ul></BODY>
</HTML>
// Simple Servletimport java.io.*;import javax.servlet.*;import javax.servlet.http.*;
public class Another 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>");out.println("<title>Another!</title>");out.println("</head>");out.println("<body>");out.println("<h1>Another!</h1>");out.println("</body>");out.println("</html>");
}}
復習
Tomcat6の基本事項を復習 (JSP)• HTMLにJavaの断片を埋め込む感じ.
• 以下のフォルダの下の個々のフォルダがアプリケーションである,例えば,
/var/lib/tomcat6/webapps/アプリ/• JSPファイルはアプリのフォルダに直接置けばよい.
• JSPに関しては特にコンパイル等はいらない.
• DBにアクセスするためには,
/var/lib/tomcat6/webapps/アプリ/META-INF/context.html に設定を書かないといけない.
7
Tomcat6の基本事項 (Servlet)• Javaプログラムそのもの.
• 以下のフォルダの下の個々のフォルダがアプリケーションである.
/var/lib/tomcat6/webapps/• ServletはJavaそのものなので事前にコンパイルする必要がある.
• クラスファイルは
/var/lib/tomcat6/webapps/アプリ/WEB-INF/classes/の下におく.パッケージに分けているなら,フォルダ階層も必要.
• クラスファイルとページの対応表を以下のファイルにかかないといけない.
/var/lib/tomcat6/webapps/アプリ/WEB-INF/web.xml
• DBにアクセスするためには,
/var/lib/tomcat6/webapps/アプリ/META-INF/context.html に設定を書かないといけない.
8
Servletソースの構造
• アップしたサンプルを見ながら聞いてください.例えば,WhereApi.java 等.
• javax.servlet.http.HttServletクラスのサブクラスとして構成する.
• 大抵,doGet もしくは doPostメソッドをオーバーライドする.
• 独自にhtmlページを構成する場合,• respnseの型を設定
• printlnで一行一行htmlを書く
という面倒をしないといけない.
• JSPにあった暗黙変数の取り方は次頁へ.
9
JSPの暗黙オブジェクト• 以下のようなオブジェクト(インスタンス)が宣言なしで使える.
• 主にウエブとの情報共有に用いられる.
• 宣言部 (<%! %>)では使えないことを注意.
10
オブジェクト名 概要
application コンテナに関する情報等
config 設定ファイルへのアクセス
exception ページ内で発生した例外情報を管理
out クライアントにデータを出力する手段.out.printlnはよくつかう.
page JSPページそのもの.
pageContext ページ単位で利用可能な情報.
request httpリクエストへのアクセスを提供
response httpレスポンスを修正する場合に利用
session セッションの情報,次回以降.
復習
Servletでの対応
• JSPでの暗黙オブジェクトは以下のようにSevletでは取得できる.
11
JSP Servlet
application javax.servlet.ServletContext a=this.getServletContext();
config javax.servlet.ServletConfig c=this.getServletConfig();
exception 各メソッドによる APIを見ること
out java.io.PrintWriter out=response.getWriter();
page なし
pageContext なし
request doPost等の引数
response doPost等の引数
session javax.servlet.http.httpSession s=request.getSession();
主なメソッド
• 基本的にはHTTPのメソッドの種類に対応.よく使うものは,
• doGet ブラウザからGETメソッドでサーバーに接続する際に呼び出される.
• doPost こちらはPOSTメソッドの場合.
• 引数の構成はほぼ同じ
• 軽くAPIを見直してみてください.
12
Javaのコンパイル (一般論,復習)• Eclipse等を使っていると忘れ気味だが,javac というコマンドラインのコンパイラが存在する.
• servletでは非標準APIを使う必要があるので,自身でこの準備を行う必要がある.
• 具体的には,本授業の環境では,以下のように,-cp オプションを付ける必要がある.
• 面倒だと思う人は shell scriptなり,alias なりにしてみること.• サンプル中には,compile.sh というスクリプトが入っている.
• CLASSPATH という環境変数を設定してもよい.
13
javac -classpath /usr/share/tomcat6/lib/../servlet.jar なんとか.java
Javaのパッケージ (一般論)• Javaでは同じ名前のクラスが衝突しないように,パッケージという概念がある.
• これによって,例えば,• org.acm.kaiya.Jindai クラスと,• jp.ac.nii.kaiya.Jindai クラスは,クラス名は同じでも,別のクラスとして扱える.
• パッケージ名は,上記のように,.で区切った英数文字(-は使えない)の列で構成される.
• 上記のように,慣例として,ドメイン名を逆したした名前をパッケージ名とすることが多い.
• kaiya.acm.org ならば org.acm.kaiya• コンパイルは問題無いが,実行時点の配置には考慮が必要.(後述)
14
サンプル
15
// ごく普通のクラス// パッケージの定義,本来は,org.acm.kaiya 等,// ドメイン逆の名前にすべきだが,//面倒だから単に一語のパッケージ名としたpackage kaiya;
public class ImportTest2{public int val=314;// public ImportTest2(){}
public String say(){return "I was imported!";
}
public static String sayStatic(){return "I am static and packaged. 2nd.";
}}
Servletのコンパイル
• javax.servletクラスは標準的なAPIではない.
• よって,前述の-cpオプション等でライブラリが入っているフォルダもしくはjarファイルを指定しないといけない.
• 本演習の標準的な設定では,
/usr/share/tomcat6/lib/../servlet.jarにSerlet関連のクラスが入っている.
• よって,以下のようにコンパイル
16
javac -classpath /usr/share/tomcat6/lib/../servlet.jar なんとか.java
Tomcat6の基本事項 (Servlet)• Javaプログラムそのもの.
• 以下のフォルダの下の個々のフォルダがアプリケーションである.
/var/lib/tomcat6/webapps/• ServletはJavaそのものなので事前にコンパイルする必要がある.
• クラスファイルは
/var/lib/tomcat6/webapps/アプリ/WEB-INF/classes/の下におく.パッケージに分けているなら,フォルダ階層も必要.
• クラスファイルとページの対応表を以下のファイルにかかないといけない.
/var/lib/tomcat6/webapps/アプリ/WEB-INF/web.xml
• DBにアクセスするためには,
/var/lib/tomcat6/webapps/アプリ/META-INF/context.html に設定を書かないといけない.
17
再掲載
Servletの配置
• コンパイルしたプログラムや設定ファイルを実行のためにサーバーの特定のフォルダにおくことを,配置もしくはディプロイ(deploy)と呼ぶ.
• 単純なアプリと違い,ウエブアプリを含めた複雑なアプリは,この,配置だけでわりと一苦労である.
• Servletやウエブアプリで使うJavaのclassファイルは,
/var/lib/tomcat6/webapps/アプリ/WEB-INF/classes/• におけばよい.
• ただし,パッケージにした場合,パッケージに応じたフォルダ階層を構成しないといけない(次頁).
• アプリとclassファイルの対応表,web.xml については後述.
18
パッケージ対応の例
19
// サンプル acm.zip にはいってますpackage org.acm.kaiya;
import java.io.*;import javax.servlet.*;import javax.servlet.http.*;
public class Acm 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("</html>");
}}
左記のようなパッケージに,クラスAcmを定義した場合,
以下のように,わりと深いフォルダ階層を掘らないといけない.
・・・・・メンドい
web.xml• クラスファイルをブラウザからアクセスするための対応表である.
• 特に慣例は無い様だが,Strutsというフレームワークを使う場合は .do とするようだ.
• 以下,例,青字は解説
20
<servlet><servlet-name>id20141210</servlet-name> 名前は一意ならなんでもOK<servlet-class>org.acm.kaiya.Acm</servlet-class> パッケージを含めたクラス名
</servlet>
<servlet-mapping><servlet-name>id20141210</servlet-name> servletで定義した名前<url-pattern>/welcome</url-pattern> URLの最後にコレがつく
</servlet-mapping>
Servletの実行
• アプリのURLに web.xml で定義したurl-patternをくっつければ実行できる.
• 普通のHTMLやJSPが実際のフォルダ階層に合致しているのに対して,servletはそうでは無いので注意が必要.
21
Form等からの値処理
• From等から入力されたkey-valueをrequestから取り出す典型的なインタラクション処理もJSP同様に記述可能.
• 例: svltform/ を参照
22
import java.io.*;import javax.servlet.*;import javax.servlet.http.*;
public class Register extends HttpServlet {public void doGet(HttpServletRequest req, HttpServletResponse res)throws IOException, ServletException{
String email = req.getParameter("email");// 以下,略
}}
ServletからのDBアクセス
• JSPでのコードがほぼそのまま利用できる.
• サンプルソース Sql1.java• アプリ /tomcat/tomcat01/sql1
• 別途,本日のサンプル中に dbclass/ というのもある.
• これは,DB操作部分を独立したJavaクラスとしてある.(後述)
23
redirect と forward• ユーザーからの入力をトリガーとして,他のページに遷移することはformで実現できる.
• ユーザーからのトリガー無く他のページに処理を移すための技術としてredirectとforwardがある.
• 例えば,Servletで何か計算をして,その結果をJSPで表示したい場合等はとても便利.
• Servletで表示するのは面倒だし.• 無論,Servlet → Servlet, JSP → JSP もOK
• キーとなるポイントはページ間でどのようにデータを共有するかである.
• redirect セッション等を利用するしかない.• forward リクエストの情報がそのまま引き継がれる.の違いがある.
24
redirectのサンプル
• redict/ を参照
25
// 略 Redirect.javapublic class Redirect extends HttpServlet {
public void doPost(HttpServletRequest req, HttpServletResponse res)throws IOException, ServletException{
String email = req.getParameter("email");if(email==null) email="unknown";
HttpSession s=req.getSession();s.setAttribute("email", email);res.sendRedirect("/tomcat/redirect/show.jsp");
}}
<body> <%-- show.jsp --%><%String email=
(String)session.getAttribute("email");%>
<div><table border><tr> <th>email address</th><tr><tr> <td> <%=email%> </td></tr></table></div><a href="form.html">[again]</a></body>
forwardのサンプル
• forward/ を参照.
26
public void doPost(HttpServletRequest req, HttpServletResponse res)throws IOException, ServletException{// 折角なので,Servletで追加情報をつけたreq.setAttribute("add", "ServletObjectID="+this);// 最初のJSPで入力されたemailについては何も対処してない単に転送されるthis.getServletContext().getRequestDispatcher("/show.jsp").forward(req, res);
}
<%// 最初のJSPで入力された情報String email = request.getParameter("email");if(email==null) email="unknown";
// Servletで意図的に付け加えた情報String add = (String)request.getAttribute("add");%>
<div><table border><tr> <th>email address</th> <th>Object ID</th> <tr><tr> <td><%=email%></td> <td><%=add%></td> </tr></table></div>
Forward.java から抜粋
show.jsp から抜粋
自作のクラスについて
• JSP/Servlet双方で自作のクラスが当然使える.
• 配置等については「Servletの配置」や次頁を参照.
• JSP/Servletはブラウザ等との直接の窓口に過ぎないので,業務に特化した処理内容やデータは,別途,普通のクラスで構築したほうがよい.
• 後述のMVCの話.
• サンプル: インストール時に配布した,tomcat01/simple2.jsptomcat01/WEB-INF/classes/kaiya/ImportTest2.class
• 本日の dbclass/ もサンプルの一種.
27
Tomcat6の基本事項 (一般クラス)• 当たり前だがJavaプログラムそのもの.
• 以下のフォルダの下の個々のフォルダがアプリケーションであり,アプリ毎に使うクラスを準備する.
/var/lib/tomcat6/webapps/• 事前にコンパイルする必要がある.
• クラスファイルは
/var/lib/tomcat6/webapps/アプリ/WEB-INF/classes/の下におく.パッケージに分ける必要があるらしく,フォルダ階層が必要.
• web.xml は特に書かなくて良い.
• DBにアクセスするためには,
/var/lib/tomcat6/webapps/アプリ/META-INF/context.html に設定を書かないといけない.
28
MVCについて• Model-View-Controller の略.
• オブジェクト指向プログラミングで習ったかもしれない.
• アプリケーションを作る際に上記の三つに分けて設計すると良いという指針.
• Model• アプリで扱う業務や活動のみを扱う部分.
• ショッピングサイトの業務なら商品,注文,顧客等がコレに相当.
• 基本,システムとは関係ない業務依存の部分.
• 主に普通のクラスやJavaBeans等で実現される.
• View• システムとしてユーザーと相互作用する部分.入出力.
• ウエブアプリならウエブページに相当し,主にJSPが担当.
• Controller• ModelとViewを関連付け,業務の進行を制御する部分.
• 主にServletが担当.
29
MVCのメリット
• 特にModelと他を分離することで,実現方法を簡単に変更できる.
• 例えば,ウエブアプリをやめて,アンドロイドの専用アプリを作ろうという時にも,Modelはそっくりそのまま流用できる.(Javaの場合,特に)
• Modelで表現される業務は往々にして類似したものが多いので,再利用ができる.
• 我々が想像する以上に業務というのはワンパターン
• アマゾンも楽天もやってることはほぼ同じ.
• 吉野家,松屋,すき家もほぼ同じ.
• アプリケーションフレームワーク等.
30
JSP/Servletの挙動が変になったら
• 以下をrootで実行する.
• localhostのところは,127.0.0.1 かもしれない.
31
# cd /var/cache/tomcat6/work/Catalina/localhost/# rm -rf アプリ名# cd /etc/tomcat6/Catalina/localhost/# rm アプリ名.xmlプログラムを修正する.# /etc/rc.d/init.d/tomcat6 restart# /etc/rc.d/init.d/httpd restart
# /etc/rc.d/init.d/tomcat6 force-reloadでもよさそう.
エピローグ
32
本講義の目的・手段・顛末
• ウエブアプリケーションの仕組みを理解し,将来の技術革新に追従できる素養を身に着ける.
• 現時点でのウエブアプリケーションを構成する技術や言語を知り,試用してみる.
• 今後も急速に変化し続けるウエブアプリケーションの動向を理解し,必要な時に実践できるでしょう.
33
復習
クライアントサイドの具体的技術
• HTML5, CSS3• ブラウザ上で文字や図形を描画するための言語
• 音声や動画の再生も可能.
• クライアント側でのデータ保存に関する仕様もある.
• JavaScript• ブラウザ上で計算を行うための言語.
• 基本,C言語に似てる.
• 文字列やデータ等の変換も計算として行える.
• 事実上,唯一のクライアントサイドの処理言語
34
復習
クライアントサイドの主な役割• 入力,表示,データの送受信
35
入力
表示
送受信
復習
BOM自体の主な変数・関数• innerHeight
• 画面内側の高さ
• innerWidth• 画面内側の幅
• onclick• 画面がクリックされた際に呼び出される関数を保持する変数.• 一般に Callback 関数と呼ばれる.
• alert()• 画面に文字列を含む小さいウインドウを表示して警告を利用者に示すことができる.
• open()• 新規windowをあける,ブラウザによってはタブか.
• close()• windowを閉じる.ブラウザによってはタブか.• たいてい,設定で禁止されている場合が多い.
36
サンプルwindowOwnProps.html
復習
BOMの主な変数
• document• 現在表示している文書をあらわすオブジェクト
• document.write 等もこのオブジェクトのメソッド(関数)• たぶん,もっともよくお世話になるオブジェクト
• location• 現在表示しているURLを表すオブジェクト
• navigator• ブラウザの情報
• history• ブラウザの表示履歴
37
サンプル(document以外の動作テスト)
windowProps.html
復習
DOM: Document Object Model• 表示されているページのデータにアクセスするためのオブジェクト.
• 本来,window.document. と書くが,window. は略せるので,document. と書くのが普通.
• ある意味,もっともJSを特徴的に使う際に重要となるデータ構造.
• 構造は無論,個々のページに依存する.
38
復習
できること
• ページ中の要素を変更できます.• スタイルも含めて変更できます.
• 要素の中身(innerHTML)が変更できます.
• 要素の属性も変更できます.• <img src=“xxx” alt=“image”> の src alt 等が属性
• かなり後の formHiden.html 参照
• ページ中に要素の追加・削除ができます.
• ページ中の要素に対するCallbackを設定できます.• 例えば,<div></div>の要素を押したら,警告がでるとか.
39
復習
サーバーサイドの具体的技術
• JavaによるJSP/Servlet• 銀行系等の大規模で信頼性の必要なシステム向け.
• PHP• お手軽にサイトを作るサーバーサイド言語.
• Cに似ている.
• Ruby on Rails• 昨今,流行っている模様.わりと頑丈.
• 伝統的なCGI (Common Gateway Interface)• Perl, Ruby, C等でサーバー側処理をするもの.
• いまどきは見かけない.
40
復習
サーバーサイドの主な役割
• 検索,計算,データ保存,手順のナビゲート,画面データの生成等
41
データ
検索
計算
生成
送受信
保存
復習
HTMLにコードを埋め込む
• ブラウザまで埋め込まれたコードが届く.• JavaScript
• サーバーで実行されHTML等に展開される.• JSP• PHP
42
<!DOCTYPE html><html> <head><meta charset="utf-8"><title>テストの問題</title><script>onload=function(){
var lis=document.getElementsByTagName("li");var w=document.getElementById("want");var x="Init";if(lis==undefined || w==undefined){
x="None";}else{
for(i=0; i<lis.length; i++) if(lis[i]==w) {x=(i+1);lis[i].style.textDecoration="underline";
}}var cho=document.getElementById("choice");if(cho!=undefined) cho.innerHTML=x;
}</script></head>
<body>Which beer do you want? <span id="choice">X</span> <ol><li>Guinness (Ireland)<li>Beck (Deutschland)<li id="want">Heineken (Netherlands)<li>Grolsch (Netherlands)</ol></body> </html>
JavaScriptの例
JSPの例
44
<HTML><HEAD><TITLE>JSP loop</TITLE></HEAD>
<BODY><ul><%int i;for(i=0; i<10; i++){%><li> number <%= i*3 %><%}%></ul></BODY>
</HTML>
<HTML><HEAD><TITLE>JSP loop</TITLE></HEAD>
<BODY><ul><li> number 0<li> number 3<li> number 6<li> number 9<li> number 12<li> number 15<li> number 18<li> number 21<li> number 24<li> number 27</ul></BODY>
</HTML>
ステートレス (状態が無い)• httpはリクエストとレスポンスの対からなる.
• あるブラウザから連続してリクエスト/レスポンスを行っても,それらの間を関係付けるものは無い.
• このような特徴をステートレスと呼ぶ.
ブラウザ
JSプログラム
・・・・・
入力画面準備
選択肢を送る
結果が返ってくる
サーバー側のデータ
サーバープログラムweb
storage等
45
一連処理という意識は無い一連処理という意識は無い一連処理という意識は無い
復習
ステートレスの例
• 以下のような状態遷移図に従うHTMLページ群を作成することは可能である.
• サンプル中の vendor0/ 下のHTMLファイル参照.
• しかし,単なるばらばらのHTMLファイル群なので,状態遷移に沿わないでページにアクセスすることができる.
• 例えば,金を払わず Coke や Fanta を得られる.
46
start
moreCoin
50JPY
showMenu
50JPY coke
fanta
100JPY
dropCoke
dropFanta
復習
状態をウエブアプリで使うには?
• ブラウザが状態を示す値(状態変数)を記憶し,毎回,サーバーにその値を送信する.
• ウエブストレージやクッキー(Cookie)が利用可能.
• ブラウザが「一連の処理」を示す識別子を記憶し,毎回,サーバーにその値を送信する.
• この一連の処理をセッション(session)と呼ぶ.
• この識別子をセッションIDと呼ぶ.
• 具体的な状態を示す値は,サーバー側で,セッションIDと対応付けて記録する.
47
復習
Formの典型様式
48
<form action="http://www.example.com/form.php" method="post">Topic: <input type="text" name="topic" size="20">
<br><textarea rows="5" cols="22" name="feedback"></textarea>
<br><input type="submit" value="send"></form>
メッセージを受け取るページを指定.このページはリクエスト処理の能力がないといけない.
get もしくは post を指定.違いは後述.
ユーザーの入力値を最終的に受け取りページに送るための呪文.
ユーザー入力場所の指定.詳細は後述.ユーザー入力場所の指定.詳細は後述.
復習
GETとPOST• GET
• 本来はサーバーからのデータ取得リクエストに用いる.
• よって,クライアント側から原則データを送ることはできない.
• しかし,URL自体にデータを付記することで,データを無理やり送ることが可能となっている.
• 送ったデータはURLを見ただけで丸見え.
• POST• サーバーにデータを送る本来のリクエスト.
• リクエストの本体(ヘッダーより下)に送るデータが付記される.
• 一応,ぱっと見にはデータは見えないが,暗号化されていないHTTPは簡単に傍受できるので,実際にはデータは丸見え.
49
復習
Form入力値を取り出す
• 基本的に form の action で指定されたページでのみ取り出せる.
• Key-value の連想配列になっているので,keyをあらかじめ知っておいて,それで取り出す.
• 言語によって取り出し方はさまざま.• PHP: 連想配列が直に見えている.
• JSP/Servlet: request.getParameter() 等のメソッドで値を取り出せる.
• 取り出した値を継続的に使いたいなら,sessionのattributeにしたり,cookieにしまったり,DBに入れたりしないといけない.
50
ソフトウェアの種類• ウエブブラウザ
• IE, Firefox, Chrome 等のブラウザ.
• ウエブサーバー
• HTTPによりブラウザとの通信を行うソフトウェア
• Apache, IIS, Nginx等が具体例.
• アプリケーションサーバー
• 特定の業務や活動の手順をガイドするソフトウェア.
• 本授業ではtomcat(+spring等)がこの位置づけに近い.
• データベースマネージメントシステム (略してデータベース or DBMS)• データを永続化するためのソフトウェア.
• MySQL, MongoDB等
• モジュール
• 各ソフトウェアの機能拡張をするための部品
※実際はOSの仲介がハードとの間に必ず入るが,それは省略.
51
復習
構成例2: 比較的大規模
• 航空券予約等のシステム (現実とは異なります)
52
VAIO : クライアント
Chrome : ウエブブラウザ
ANAのサイト : サーバー
IIS : ウエブサーバー
子会社のサーバー : サーバー
予約システム : アプリケーションサーバー
オラクルの : データベース
VISA Card : サーバー
決済システム : アプリケーションサーバー
Master Card
決済システム : アプリケーションサーバー
AJP
HTTPS
復習
最終演習
• 提出は必須です.締切は1週間後くらいでお願いします.dotcampus のインラインテキストでお願いします.
1. 本授業において面白かった話題を200字以上で述べてください.
2. 本授業で難しかった話題を200字以上で述べてください.
3. 本授業で取り上げてほしかった話題があれば列挙してください.
• 以上,よろしくお願いします.
53
以上
54