Javaのまとめサイト
サーブレット、JSPのまとめ資料。

- Java -言語についてのまとめ
- Java -クラス設計についてのまとめ
- Java -サーブレット、JSPについてのまとめ
- Java -JDBC、データベースについてのまとめ
- シスコ CCNA対策はこちら
- ITILファンデーション対策はこちら




■eclipse
イクリプスの猫アイコン:トムキャットを起動する
http://localhost:8080 でアクセス
ctrl+spaceで入力補助あり

■WEB-INF
$APP_HOME/WEB-INFに置いたファイルはブラウザから直接アクセスすることが出来ません
■web.xml
Webアプリの核となる設定ファイルです。このファイルが存在しないWebアプリは通常ありません。$APP_HOME/WEB-INFに置く
■WEB-INF/classes
サーブレットなど、Webアプリで使う全てのJavaクラスファイルはこのディレクトリ以下に配置します。
■WEB-INF/lib
共通クラスやサードパーティ製のライブラリなど、Javaクラスファイルをまとめたjarファイルをここに置くことができます。サブディレクトリを作ることは出来ません。WEB-INF/lib 直下に各種jarファイルを配置する必要があります。

■URLデコード設定(日本語のURLエンコーディングを有効にする、要Tomcat再起動)
C:\java\tomcat5.5\conf\server.xml
HTTP/1.1 Connectorの設定に以下を追加
useBodyEncodingForURI="true"
ちなみにオラクルサーバも8080を使っている場合8081等に修正する
<Connector port="8080" maxHttpHeaderSize="8192"

■サーブレットのTomcatプロジェクトを作る
Java>Tomcatプロジェクト>プロジェクト名 entry これがコンテキスト名になる
プロジェクト名>新規>ファイル hello.txt http://localhost:8080/entry/hello.txt でアクセス
プロジェクト名>新規>その他>Web>HTMLページ hello.html http://localhost:8080/entry/hello.html でアクセス
プロジェクト名>新規>フォルダ sub http://localhost:8080/entry/sub/sub.html でアクセス
URLはケースセンシティブ
サーブレット/web.xml(Controller) --- JSP(View) --- クラス(Model)

■C:\java\tomcat5.5\conf\web.xml
<param-name>listings</param-name>
<param-value>true</param-value>でディレクトリ情報一覧が表示される、デフォはfalseの非表示

<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>がディレクトリのデフォ表示ファイル

■サーブレット
サーブレットはマルチスレッドで呼ばれる、つまりMTセーフな作りにしなければならない

javax.servlet.http.HttpServletを継承する
doGet, doPostメソッドをオーバーライドする

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HogeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{

WEB-INF/src>新規>クラス HogeServlet
WEB-INF>新規>ファイル web.xmlにクラス(servlet:完全クラス名で)とurl-patternのマッピング(contextルートから)を記述
<web-app>
<servlet>
<servlet-name>HogeServlet</servlet-name>
<servlet-class>hoge.HogeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HogeServlet</servlet-name>
<url-pattern>/hoge.HogeServlet</url-pattern>
</servlet-mapping>
</web-app>
http://localhost:8080/entry/HelloServlet でアクセスできる

■JSP
JSPエクスプレッション、スクリプトレット、ページディレクティブから成る
JSPコンテナがサーブレットに変換してくれる、MTセーフな作りにしなければならない
JSPはアクセス一回目にコンパイルされるが、その中間ファイルとして.javaや.classができる
workフォルダにJSPから生成された中間ファイルがある、調子が悪い場合削除するとよくなる場合がある
ScriptletはJavaの文法と同じ、思想的には使わずサーブレットで行いたい。<% int i = 1; i = i * 5; %>、変数はローカル変数でスレッドセーフ
JSPexpression(式)はJavaの文法とは異なり、区切り文字;は付かない。<%= i %> out.println()、out.print()と同意のもの
outはnewなしで使えるJSPの暗黙オブジェクト、<% out.println(i); %>でOK、requestやresponse,session等
<%--JSPコメント--%>
<%@ ディレクティブ、<%@page contentType="text/html; charset=Windows-31J" %>
ページディレクティブはページ全体に関する設定を行う
<%@page import="java.util.Date" %>すると<%= new java.util.Date() %>ではなく<%= new Date() %>で可
デフォルトパッケージのクラス/無名クラスはインポートできない(パッケージ名がないから)
<%@include file="common.jsp" %> ディレクティブのincludeは静的ファイルのみ
<a href="<%=request.getContextPath() %>">WEBアプリケーションのルート</a>
<% System.out.println("hoge"); %>のJSPにブラウザにアクセスすると、標準出力(eclipse)へhogeがでている
<jsp: アクションタグ <jsp:include page="header.jsp" /> 動的なJSPの結果を取り込む
<%! String declaration; %> 変数やメソッドの宣言、フィールド変数になりスレッドセーフでない
EL式(ExpressionLanguage) <html>${"hello"}</html> helloと表示される ${array[2]} ${1 + 2}
request.setAttribute("message","hello!");⇒${message}で取得(getAttribute)
HashMap map = new HashMap(); map.put("key","hoge"); request.setAttribute("map",map);⇒${map.key}で取得(ハッシュマップのget) ${map["key"]}でも可
request.setAttribute("message","hello!");⇒${message}で取得
<%=((UserBean)request.getAttribute("user")).getName() %>⇒${user.name}で取得(ゲッター)
<jsp:include page="<%=((PageController)request.getAttribute("ctrl")).getHeader()%>"/>⇒<jsp:include page="${ctrl.header}"/>
${header['user-agent']} EL式の暗黙オブジェクト一例

■カスタムタグとJSTL(標準的なカスタムタグのライブラリ)
JarファイルをWEB-INF/libに置く、JSPでtaglib宣言を行う
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> Coreタグでは慣習的にc(自由に決められる)、URIはTLDファイルの場所だが通常ドキュメント等にあるもの
<c:set var="name1" value="value1" scope="session"/>${name1} <c:remove var="name1"/> <c:if test="${age<20}">20未満</c:if>

■web.xmlの修正はTomcatの再起動が必要、サーブレットURLマッピングで再起動が必要
コンテキスト.xmlのコンテキストの部分は作成するコンテキスト名が入ります

■XML
ルート要素は単一、タグはケースセンシティブ、閉じタグ忘れが多い

■HTMLのフォーム送信をサーブレットのdoGet/doPostで受け取り URL?name=value&name2=value2
a.html/ <input type="text" name="message">

b.class/ public class receiveServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
perform(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
perform(request, response);
}
public void perform(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
//URLエンコードされた日本語データをデコード
request.setCharacterEncoding("Windows-31J");
//POST,GET両方受け取れる
String msg = request.getParameter("message");

//日本語表示の場合HTTPレスポンスのヘッダーとして、Shift_JIS, EUC=JP, UTF-8, ISO-8859-1,MS932
response.setContentType("text/plain; charset=Windows-31J");
PrintWriter out = response.getWriter();
out.println("message=" + msg);
}
}

■各種フォームのデータ取得
a.html/ <INPUT TYPE="text" NAME="text1" VALUE="テキストフィールド">

<TEXTAREA NAME="textarea1" COLS="30" ROWS="5">テキストエリア</TEXTAREA>

<INPUT TYPE="RADIO" NAME="radio1" VALUE="value1" CHECKED>左
<INPUT TYPE="RADIO" NAME="radio1" VALUE="value2">右

<INPUT TYPE="CHECKBOX" NAME="check1">ゴルフ
<INPUT TYPE="CHECKBOX" NAME="check2">テニス
<INPUT TYPE="CHECKBOX" NAME="check3" VALUE="FOOTBALL">サッカー

<SELECT NAME="lang" SIZE="3" MULTIPLE="true">
<OPTION VALUE="sel1">VB
<OPTION VALUE="sel2">C
<OPTION VALUE="sel3">Java
</SELECT>

イニュミレーション/列挙型はイテレーションみたいなもの、hasMoreElements()、nextElement()等メソッドを持つ
servlet.class/ Enumeration names = request.getParameterNames();//パラメータ名一覧取得
while(names.hasMoreElements()){//パラメータがあれば
String name = (String)names.nextElement();//パラメータ名取得
//パラメータ名のデータを取得、複数なのはセレクトが複数可能だから
String[] values = (String[])request.getParameterValues(name);
for(int i=0; i<values.length; i++){
out.println(name + "=" + values[i]);
}
}
nextElement()は順不同で以下のように取得する、チェックボックスはvalue省略でonが返る
textarea1=テキストエリア
check3=football
check2=tennis
check1=on
text1=テキストフィールド
lang=sel1
lang=sel2
lang=sel3
radio1=value1
---これでも可、getParameter()は、request.getParameterValues()の兄弟でString配列の先頭1個目を返す
out.println("TextBox=" + request.getParameter("text1"));
out.println("TextArea=" + request.getParameter("textarea1"));
out.println("Radio=" + request.getParameter("radio1"));
out.println("Check Golf=" + request.getParameter("check1"));
out.println("Check Tennis=" + request.getParameter("check2"));
out.println("Check Football=" + request.getParameter("check3"));

String[] values = request.getParameterValues("lang");
if(values!=null){
for(int i=0; i<values.length; i++){
out.println("Select lang=" + values[i]);
}
}

■エラー処理
try{
int year = Integer.parseInt(yearStr);
}catch(NumberFormatException e){
error = "年を入れてください";
}
if(error != null){ out.println(error); }else{ //正常時 }

■正規表現
String pattern = "[\\w\\.\\-]+@([\\w\\.\\-]+\\.)+[\\w\\.\\-]+";
if(text.matches(pattern)){ //マッチした時 }

■ディスパッチャー
import javax.servlet.RequestDispatcher;
//フォワード、URLは転送元のままで別ページへ転送、外部は無理のようだ
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
RequestDispatcher dispatcher = request.getRequestDispatcher("/ForwardServletB");
dispatcher.forward(request, response);
}
//インクルード、ファイルを埋め込む(サーブレットは基本的に表示をしないのでincludeはあまり使わない)
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
RequestDispatcher dispatcher = request.getRequestDispatcher("/IncludedServletB");
dispatcher.include(request, response);
}

■リダイレクト、外部でも内部でも転送可能
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
response.sendRedirect(request.getContextPath() + "/ForwardServletA");
//response.sendRedirect("http://www.google.co.jp");
}

■フィルタ
javax.servlet.Filterインターフェースをインプリする。
public class AccessFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
//初期時に1度呼ばれる、web.xmlの初期化パラメータを受け取れる
encode = filterConfig.getInitParameter("encode");
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
//doFilter()より前が前処理、後ろが後処理

//init()で取った初期化パラメータを使える
request.setCharacterEncoding(encode);

// リモートアドレス取得
String remoteAddr = req.getRemoteAddr();
// アドレスが192.168.1で始まる場合
if (remoteAddr.startsWith("192.168.1")) {
// 元々要求されていたリソースを呼び出します
chain.doFilter(req, res);
} else { // それ以外の場合
// エラーメッセージ用JSPに転送します
RequestDispatcher rd = req.getRequestDispatcher("/error.jsp");
rd.forward(req, res);
}
System.out.println(remoteAddr);
}
public void destroy() {
//終了時に呼ばれる
}
}
//web.xmlにフィルターを掛ける範囲を設定、init()内で受け取る初期化パラメータも記述できる
<filter>
<filter-name>AccessFilter</filter-name>
<filter-class>flt.AccessFilter</filter-class>
<init-param>
<param-name>encode</param-name>
<param-value>Windows-31J</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>helloFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>

■スコープ
リクエスト(1発)、セッション(同クライアント)、アプリケーションスコープ(異なるクライアントでも可)がある
サーブレット間のデータのやりとり等に使う。受け取り側ではキャストも必要
キーが同じものは上書きされる
//設定側 setServlet
request.setAttribute("mes","あいう");
SampleBean bean = new SampleBean();
bean.setMessage("ぼちぼち");
request.setAttribute("bean", bean);
RequestDispatcher dispatcher = request.getRequestDispatcher("/reqattr.Servlet2B");
dispatcher.forward(request, response);
//受取側 getServlet
String message = (String)request.getAttribute("mes");
SampleBean bean = (SampleBean)request.getAttribute("bean");
String message = bean.getMessage();
removeAttribute("mes");
//セッション
HttpSession session = request.getSession(); HttpSessionクラス型のセッションオブジェクトを取得
引数付きgetSession(true) セッションが無ければ作る、getSession(false) セッションが無ければnullを返す
session.getId() セッションID
session.setAttribute("count", 117);
Integer count = (Integer)session.getAttribute("count");
HogeBean obj = (HogeBean)session.getAttribute("hoge"); if(obj!=null){ キーがString型で値がHogeBeanクラス型
セッション変数を全て取得
Enumeration names = session.getAttributeNames();
while(names.hasMoreElements()){
String key = (String)names.nextElement();
Object value = session.getAttribute(key);
out.println(key + "=" + value + "<br>");
}
session.removeAttribute("count"); セッション変数の削除
session.invalidate(); セッション破棄
if(session.getAttribute(key)!=null){ セッションにkeyキーでobjがある場合
IEのタブを変えても同一セッション、ブラウザ全体を一度終了すると違うセッションになるブラウザが多い
デフォルトのタイムアウトは30分、web.xmlで設定
<session-config>
<session-timeout>5</session-timeout>
</session-config>
//アプリケーションスコープ(トムキャットが落ちるまで)
ServletContext application = getServletContext();
application.setAttribute("count",1);
Integer count = (Integer)application.getAttribute("count");

String linkUrl = request.getRequestURI(); このページのURL
<a href="<%= request.getContextPath() %>/index.jsp">戻る</a>
String path = context.getRealPath("/WEB-INF/test.initServlet"); OSの物理パスを取得c:\eclipse\WEB-INF\test.initServlet

ライフサイクルメソッドでフィルタと同じメソッド名だが動作タイミングが全然違う、init() 最初のサーブレット起動時呼び出される、destory() サーバ停止時に呼び出される、ファイルにデータを書き込むなど

■スレッドセーフ
シングルインスタンス・マルチスレッド、一つのインスタンスが使いまわされ複数のリクエスト間で共有される
同時にアクセスされても正常に動作させるにはスレッドセーフにする必要がある
メソッド内やブロック内で使われる「ローカル変数」「リクエスト属性」「ページ属性」はOK
クラスから生成された個々のインスタンス(オブジェクト)で使用される「インスタンス変数」は×
「スタティック変数」「セッション属性」「アプリケーション属性」も×
DI(Dependency Injection)コンテナを使う
public class MyServlet extends HttpServlet implements SingleThreadModel{
SingleThreadModelインターフェイスを実装するとdoGet()全体をsynchronizedで排他を掛けたようになる、セッションやアプリケーションスコープがスレッドセーフになるわけではない、デコミッションになる予定。

■初期化パラメータ アプリケーション全体でつかう<context-param>、サーブレットにマッピングした<init-param>を使用できる
<load-on-startup>に0以上を指定すると最初のリクエストでなくアプリ起動時にサーブレットも起動する、小さいものが先にロードされる
doGet(){
ServletConfig config = getServletConfig();
e2 = config.getInitParameter("key1");
}
//web.xml
<context-param>
<param-name>appkey1</param-name>
<param-value>appvalue1</param-name>
</context-param>
<servlet>
<servlet-name>CarSales</servlet-name>
<servlet-class>servlets.CarSales</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>key1</param-name>
<param-value>value1</param-name>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>CarSales</servlet-name>
<url-pattern>/CarSales</url-pattern>
</servlet-mapping>

■HTTPリクエスト・レスポンス
request.getContentType()
request.getContetnLength()
request.getRemoteAddr()
requet.getHeader("REFERER")
requst.getHeader("USER-AGENT")
//キャッシュオフ
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", 0);

■クッキー
doGet(){
//クッキー取得
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(int i=0; i<cookies.length; i++){
Cookie cookie = cookies[i];
if(cookie.getName().equals("count")){
String value = cookie.getValue();
count1 = Integer.valueOf(value);
break;
}
}
//クッキー設置
Cookie cookie = new Cookie("count", count2.toString());
cookie.setMaxAge(60*60*24*5);
response.addCookie(cookie);
}
クッキーに日本語を使用する
//設置
Key = URLEncoder.encode(key, "Windows-31J");
value = URLEncoder.encode(value, "Windows-31J");
Cookie cookie = new Cookie(key, value);
//取得
String key = cookie.getName();
String value = cookie.getValue();
key = URLDecoder.decode(key, "Windows-31J");
key = URLDecoder.decode(value, "Windows-31J");
//クッキーが使えないセッション管理
URLにjsessionidを追加する
linkUrl = response.encodeURL("http://hoge/hoge/hogeServlet");
out.println("<a href=" + linkUrl + ">")

■invokerサーブレット
web.xmlでのマッピングを一つづつでなく、invokerでまとめ記述し簡易アクセスさせる。開発時に便利だが非推奨

■WARファイルとデプロイ
もろもろのWebApplicationResoursesファイルを一つのファイルに纏める、JARやZIPと同じ圧縮形式
デプロイはAPサーバのデプロイツールを使う、簡易デプロイでなくこの方法が標準のリリース方法
//WARファイル作成
該当プロジェクト>右クリック>プロパティ>Tomcat>WARエクスポート設定tab
ソースのjavaファイルは不要、日本語の無いディレクトリに保存 例C:\src\TestApp.war ファイル名がアプリ名
該当プロジェクト>右クリック>Tomcatプロジェクト>WARファイル作成
//デプロイ
Tomcatユーザ登録 C:\java\tomcat5.5\conf\tomcat-users.xml <user username="hoge" password="hoge" roles="manager"/>を追加
Tomcat Webアプリケーションマネージャ id:hoge/pass:hoge http://localhost:8080/manager/html/
WARファイルの配備で作成したWARファイルをデプロイする

■MVC
Beansをモデル、JSPをビュー、Servletをコントローラ
//モデルには、アプリケーションデータと、そのデータ変更に適用されるビジネスルールを記述 SearchItemBeans.java
package searchitem;
public class SearchItemBeans{
private String item = null;
public String getItem(){
return item;
}
}
//コントローラは、ユーザの要求を解釈しモデルを操作しビューを選択する SearchItemServlet
アクションタグでオブジェクトを取得する
public void doGet(){
SearchItemBeans sItems = new SearchItemBeans();
request.setAttribute("setBeans", sItems);
RequestDispatcher rDispatcher = request.getRequestDispatcher("result.jsp");
rDispatcher.forward(request, response);
}
//ビューは、コントローラからのフォワードを表示する result.jsp
<jsp:useBean id="setBeans" scope="request" class="searchitem.SearchItemBeans" />
<jsp:setProperty name="searchItemBeans" property="item" value="<%=price * 1.05 %>" />
セッターメソッドを使用し、ビーンのitem変数を設定
<html>
idにはコントローラでsetAttributeで指定したキー、classにはpackage名.class名
<jsp:getProperty name="setBeans" property="item" />
<%= setBeans.getItem() %>
ゲッターメソッドを使用し、ビーンのitem変数を取得、2行どちらでも可
</html>

■JavaBeansとは?
ビジネスロジックとデータをカプセル化した再利用可能なコンポーネント
名前規則に従うゲッターとセッターを持つ
引数の無いコンストラクタを持つ
パッケージを付ける
クラスはpublic
ファイル保存時やリモート転送時にシリアライズ?? implements Serializable

java webアプリケーション プログラミング サーブレット JSP データベース DB ゲーム script ダウンロード sun 入門 講座 vm eclipse アプレット ジャバザハット コンチェ ブーシ クラス メソッド コンストラクタ 実装 スプリクト アプレット オブジェクト 呼び出し 初歩 例外 リシュモン コンパス 入門 プログラミング 言語 スウォッチ 変数 bufferedreader stringbuffer stringtokenizer extends inputstream hashmap javaworld synchronized applet class equals iterator tostring boolean resultset applets constructor javadoc specified implements arraylist interface hashtable arrays documentation jfilechooser 遅い exceptions vector tutorial import