ウェブインコ

インコの技術メモ

Java

────────────────────────────────────────
Java を始める方法
────────────────────────────────────────
なんの知識もないところからスタートアップしたわけですが、面倒すぎる、という感想です。
同じような苦労をする人もいるかもしれないので一連の軌跡を記すとします。
2016.1 時点での作業メモです。
古くなったら他の人を当たってください。
私は LAMP開発ばかりしていたので、ときどき「LAMPで言うところのほにゃらら」みたいな言い回しをします。正確ではないこともありますが、だいたいで解釈してください。
あと、作業しながらメモしたものなので、絶対に間違っていない、なんてことありませんので、書いている通り行かなかったらそのときだけは自分で調べて問題解決してください。

※私限定ですが、進めていくとともに「あえてJavaを使うメリット」が、「囲い込みをしたい」「Eclipseでぜんぶ管理出来て気持ちイイ」以外のものが感じられなくなっているので、後ろ向きな文章になっているかもしれません。なので、心の中でプラス10%ぐらい Javaへの愛を増強させて読んでください。


────────────────────────────────────────
JDK
────────────────────────────────────────
開発環境である JDK を使います。

----------------------------------------
インストール
----------------------------------------
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
jdk-8u65-windows-x64.exe(← windows x64 の場合)

x86 が 32 ビット版、x64 が 64 ビット版
自分の PC が何かは「コンピュータ → 右クリック」で確認。

----------------------------------------
環境変数
----------------------------------------
コンピューター → 右クリック → プロパティ → システムの詳細設定 → 環境変数
以下を追加。
一応その場所に以下のパスがあるか確認してください。
JAVA_HOME は無いので追加になります。

PATH
C:\ProgramData\Oracle\Java\javapath
C:\Program Files\Java\jdk1.8.0_65\bin

JAVA_HOME
C:\Program Files\Java\jdk1.8.0_65

区切り文字はセミコロン ;

----------------------------------------
動作確認
----------------------------------------
コマンドプロンプトから以下の2つを確認。

java -version
javac -version

----------------------------------------
備考
----------------------------------------
まず最初に Java を始めようとすると、いろんな種類があって意味不明なので以下説明。

JDK(Java Development Kit)
    直訳するとJava開発キット(環境)。Javaでプログラムを作るとき必要です。
    JDKにはJREが含まれています。

JRE(Java Runtime Environment)
    Javaで作られたプログラムを実行するとき必要です。 
    JDKに含まれているJREを非公開JRE(PrivateJRE)、単体でインストールするものを公開JRE
    (PublicJRE)といいます。

JVM(Java Virtual Machine)
    Java言語で作られたプログラムを実行するためのソフトウェアです。JREに含まれています。

API(Application Programming Interface)
    JavaでいうAPIは関数群の事です。クラスやインターフェースの形で提供されてます。

JavaSE(Java Platform, Standard Edition)
    wikiにある通り標準的な機能がまとめられたAPIの集合体です。JDKやJREというのはJavaSE
    の事を指しているのとほぼ同義です。また、webでJavaの事を調べているとよく出てきて混
    乱する原因の一つがバージョンの表記です。J2SEやJ2EEという表記を見たことがあると思
    いますが、これはバージョン2から5までの表記がJ2SEで、6以降はJavaSEと表されます。紛
    らわしいですよね。

JavaEE(Java Platform, Enterprise Edition)
    JavaSEにサーバ関係のライブラリなどを追加したもので、ベースはJavaSEそのものです。
    JavaEE SDK(JDKじゃないよ)は、JavaSE+JavaEE用ライブラリ+標準JavaEEサーバ+各種ドキ
    ュメントからなります。


────────────────────────────────────────
Tomcat
────────────────────────────────────────
Apache みたいなものです。
バージョンは 8 を使用しよう。

----------------------------------------
インストール
----------------------------------------
http://tomcat.apache.org/download-80.cgi
32-bit/64-bit Windows Service Installer (pgp, md5, sha1) 


────────────────────────────────────────
Maven3
────────────────────────────────────────
Perl で言うところの CPAN です。

----------------------------------------
インストール
----------------------------------------
http://ftp.riken.jp/net/apache/maven/maven-3/3.3.9/binaries/
apache-maven-3.3.9-bin.zip

解凍して任意の場所に置きます。

----------------------------------------
環境変数
----------------------------------------
以下は C:\ 直下に置いた場合。

PATH
C:\apache-maven\bin
M2_HOME
C:\apache-maven\

────────────────────────────────────────
Eclipse
────────────────────────────────────────
Eclipse とは、ひとまずエディターとコンソールがセットになったものと思ってください。
あとで、サーバー、ブラウザ、ログ、DB管理、ER図作成、バージョン管理、等々、様々なプラグインを入れると何でも一手に引き受けてくれる開発環境になってくれます。
LAMP 開発で言うと例えば、エディター + XAMPP + Firefox をぜんぶ1つのソフトでやっているみたいな感じです。

----------------------------------------
インストール
----------------------------------------
Eclipse Luna を使うこととします。

(公式)
(http://www.eclipse.org/downloads/packages/eclipse-ide-java-developers/lunasr2)

日本化したものをインストールします。
http://mergedoc.osdn.jp/index.html#pleiades.html
→ 安定版 → pleiades_1.6.0.zip

解凍したら任意の場所、例えば C:\ の直下にでも置きます。
パスに日本語が入ってたり長すぎるとロクなことがないので。

----------------------------------------
動作確認
----------------------------------------
ウインドウ → ビューの表示 → プロジェクト・エクスプローラー

プロジェクト名:javatest
プロジェクト・エクスプローラーの空白を右クリック
 → 新規 → その他 → Javaプロジェクト → プロジェクト固有
 → JREを使用でさっき入れたもの jre1.8.0_65 を指定(別になんでもいいかも)。

クラス名:classTest
出来たプロジェクトを右クリック
 → 新規 → クラス

classTest.java へ以下のように書いて、画面上の緑色で右向き三角のアイコンをクリックして、画面下部のコンソールに出力されればおk。
コンパイル(javac classTest.java)と実行(java classTest)をいっぺんにしてくれます。

package javatest;
public class classTest {
    public static void main (String[] args) {
        System.out.println("Hello World !!");
    }
}

----------------------------------------
備考
----------------------------------------
人にもよると思いますが、ちょっとしたノリの話です。
PHP等の開発では、いっぺんにブラウザに表示するところまで作ってブラウザで動作確認という手順をとることが多いかもしれませんが、Javaではプログラムの部品を細切れに作って「意図する結果(文字列)が得られるか」というテストを小まめに行う、という感じで進めるようです。
「プログラムの部品を細切れに作る」という点についてはどちらも同じですが、(P)HTMLとくっつけて表示してからおかしかったら原因を探る、のと、(J)あらかじめ細かい部品のテストを行ってOKならば先に進む、のの違いがあります。
もちろん、LAMPでも JAVA と同じような開発手法はできる(している)ので、あくまで「例えばこういうこともある」という程度です。
PHP は HTML に(の代わりに)動的な機能を付けたものという感じで着手しはじめることがあるので、こういう違いが生まれやすく、お互いに話がかみ合わないことがあるのだと思います。


────────────────────────────────────────
ブラウザからアクセス(サーブレット)
────────────────────────────────────────
----------------------------------------
設定
----------------------------------------
ウィンドウ → ビューの表示 → サーバー
画面下部にサーバービューが出現。

----------------------------------------
ウェブプロジェクト
----------------------------------------
プロジェクト空白右クリック → 新規 → その他 → 動的 Web プロジェクト
プロジェクト名(任意):TomcatTest
ターゲット・ランタイム:Apache Tomcat v8.0
 このとき、「新規ローカル・サーバーの作成(c)」にチェックを入れる!
次 → 
Tomcat インストール・ディレクトリー(D):C:\Program Files\Apache Software Foundation\Tomcat 8.0
JRE(J):JRE jre1.8.0.65
次 → 次 →
web.xml デプロイメント記述子の生成 にチェック

----------------------------------------
サーブレット
----------------------------------------
出来たプロジェクトを右クリック → 新規 → その他 → Web → サーブレット
Java パッケージ(任意):example.test
クラス名(任意):HelloWorld

HelloWorld.java
29
既に書かれているdoGetメソッド内に1行だけ、以下を追加する。
response.getWriter().write("Hello, World!");
ex.)
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.getWriter().write("Hello, World!");
    }

----------------------------------------
Tomcat
----------------------------------------
画面下部.サーバービューにローカル・ホスト の Tomcat v8.0 サーバー」を右をクリック
実行ボタン(右斜め上の再生ボタン)をクリックして起動。
→ 追加および除去 → TomcatTest を追加。

----------------------------------------
ブラウザ
----------------------------------------
ブラウザから以下を入力して Hello, World! と出ればおk。

http://localhost:8080/TomcatTest/HelloWorld


────────────────────────────────────────
ブラウザからアクセス(JSP)
────────────────────────────────────────
サーブレット:HTMLも全てJavaで記述されたコードで構成。
JSP(JavaServer Page):HTMLページの中にJavaのコードを埋め込み。

----------------------------------------
設定
----------------------------------------
TomcatTest/WebContent を右クリック → 新規 → その他 → JSP ファイル
<body>タグの中に何か書いて、保存 → サーバー再起動

----------------------------------------
ブラウザ
----------------------------------------
ブラウザから以下を入力して上記のものが表示されればおk。
ファイル名が NewFile.jsp の場合。

http://localhost:8080/TomcatTest/NewFile.jsp


────────────────────────────────────────
サーブレットとJSP
────────────────────────────────────────
java をコンパイルして実行するだけならコマンドラインで結果を見れるのですが、
ブラウザから見るときには「サーブレット」と「JSP」という2種類の手法があります。

・サーブレットはコマンドで実行したものに近い形で、ASPのようなラウザーから受け取ったデーターを処理するのに適しています。

・JSP は PHP のように HTML形式の中に処理を埋め込む形で、ブラウザに画面を表示するのに適しています。


────────────────────────────────────────
トラブル
────────────────────────────────────────
ここらへんで一休み。

・Tomcat はインストール時に起動しているかもしれないので、サーブレット確認時にサーバー起動エラーになったら、Windowsメニューの「すべてのプログラム」から切っておく。
・よく分からなければPC再起動(基本w)。
・プロジェクト作成あたりからリセットしてやり直す時は、プロジェクト・エクスプローラーから全部削除 → Eclipse 終了 → Eclipse で使用していた workspace の中身をぜんぶゴミ箱へ → Eclipse 起動してゼロからやり直し。バカバカしいようだけどこれを繰り返すことで経験値が上がります。


────────────────────────────────────────
m2e
────────────────────────────────────────
Maven3 と Eclipse を繋ぐプラグイン。

----------------------------------------
インストール
----------------------------------------
eclipse → ヘルプ → インストール詳細 → プラグイン で確かめたら入っていた。


────────────────────────────────────────
MySQL
────────────────────────────────────────
----------------------------------------
インストール
----------------------------------------
以下からダウンロードしてインストール。
root のパスワードを聞かれるので適当に設定して控えておいてください。
http://dev.mysql.com/
上部タブメニューの「Downloads」をクリック。
その下のサブメニューにある「Windows」をクリック。
「MySQL Installer」をクリック。
画面内の「Windows (x86, 32-bit), MSI Installer」をダウンロード。
ウェブ経由でインストールするか、最初にローカルに落としてインストールするかの違いで上下とも同じものです。
次のページ下部で No thanks, just start my download.

うまくいかない時はいったんぜんぶアンインストールしてから再度行ってください。

----------------------------------------
動作確認
----------------------------------------
コマンドプロンプトより、
mysql -u root -pパスワード

「認識されていません」的なエラーが出るときにはパソコンが mysql の場所を見つけられないということ。
環境変数を設定して教えてやります。

コンピューター → 右クリック → システムの詳細設定 → 環境変数 → Path をえらんで編集 → 「C:\Program Files\MySQL\MySQL Server 5.7\bin」を追加してOK。
区切り文字は ;

コマンドプロンプトを上げ直して
mysql -u root -pパスワード

----------------------------------------
データベース作成
----------------------------------------
アクセスできたらついでにDBも1つ作っておきましょう。
create database javadb;

----------------------------------------
テーブル作成
----------------------------------------
ついでにテーブルも一つ。
DB選択。
use javadb;

以下をコピペしてエンター。
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
loginid VARCHAR(50),
password VARCHAR(50),
created DATETIME DEFAULT NULL,
updated DATETIME DEFAULT NULL
);

確認
show tables;
desc users;

----------------------------------------
レコード作成
----------------------------------------
1レコードぐらい入力しておこう。
INSERT INTO users (name,loginid,password,created,updated) VALUES ('テストマン', 'wwww', 'wwww', NOW(), NOW());

確認
SELECT * FROM users;


────────────────────────────────────────
DBドライバー
────────────────────────────────────────
Java で MySQL を使うためのもの。

----------------------------------------
インストール
----------------------------------------
http://dev.mysql.com/downloads/connector/j/5.1.html

Platform Independent (Architecture Independent), ZIP Archive Down load → No thanks, just start my download.

解凍したら任意の場所に置きます。
以下辺りでよろしいかと。
C:\Program Files\MySQL


────────────────────────────────────────
Eclipse.DBViewer
────────────────────────────────────────
Eclipse で DBを管理するツール。
phpMyAdmin のようなもの。

----------------------------------------
インストール
----------------------------------------
ヘルプ - マーケットプレイス を選択し、検索 タブの 検索欄に DBViewer と入力して実行 。
インストール → 確認 → 使用条件の条項に同意します → 完了。

マーケットプレイスが無い場合は先にそれをインストールしてください。
説明ページ
http://dotnsf.blog.jp/archives/1010597771.html

----------------------------------------
設定
----------------------------------------
ウインドウ → パースペクティブを開く → その他 → DBViewer
画面左上のDBツリー・ビューという文字の下にある円柱のアイコンをクリック
データベース定義画開くので、データベース定義名に適当な名前を入れて、「ファイルの追加」をクリック。
さっき保存したドライバーを指定。
C:\Program Files\MySQL\mysql-connector-java-5.1.38
mysql-connector-java-5.1.38-bin.jar
「次へ」
JDBC Driver は com.mysql.jdbc.Driver
接続文字列
jdbc:mysql://(MySQL サーバー名):3306/(データベース名)
今回は以下でよいでしょう。
jdbc:mysql://localhost:3306/javadb
接続ユーザ、接続パスワード、はとりあえず root とインストール時に設定したもの。
設定していなければ root だけでもよいかもしれません。
「テスト接続」をクリックして「接続に成功しました」出ればOK。
「完了」
DB ツリービューに出来ていればOK。
「データベース名」をダブルクリックすると先ほど作成した「javadb」も見えているかと。
右クリックで接続・切断できます。

画面右下の「SQL 実行・ビュー」のところでコマンドを入力実行できます。

SELECT * FROM users;

基の画面に戻るには、画面右上の「Java」をクリック。


────────────────────────────────────────
JAVA で DB を操作
────────────────────────────────────────
----------------------------------------
プロジェクト作成
----------------------------------------
プロジェクト名右クリック → 新規 → クラス
名前を sqlTest とします。
sqlTest.java というファイルが出来るので、それを右クリック → ビルド・パス → ビルド・パスの構成 → ライブラリー → 外部 Jar 追加
C:\Program Files\MySQL\mysql-connector-java-5.1.38
mysql-connector-java-5.1.38-bin.jar

sqlTest.java へ以下のように書きます。
プロジェクト名は TomcatTest とします。

package example.test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class sqlTest {

public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/javadb","root","パスワード");
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("select * from users");

while(rs.next()) {
String name = rs.getString(2);
System.out.println("名前:"+name);
}
rs.close();
st.close();
conn.close();
System.exit(0);

} catch (ClassNotFoundException e) {
System.out.println("ドライバを読み込めませんでした "+ e);
} catch (SQLException e) {
System.out.println("データベース接続エラー"+ e);
}
}

}

保存したら、実行ボタンをクリックします。
以下のように表示されたらとりあえずOKです。

名前:テストマン

ワーニング(SSL接続推奨みたいな)が出てもひとまず無視してください。


────────────────────────────────────────
Eclipse Java ウェブアプリから MySQL に接続
────────────────────────────────────────
----------------------------------------
プロジェクト作成
----------------------------------------

----------------------------------------
MyObj.java
----------------------------------------
新しく MySQL を読み込むクラスを作ります。
ほぼ、上で作ったのの System.out.println が return になっただけです。

package com.example.part1;

import java.sql.*;

public class MyObj {
    public MyObj(){
    }
    public String getMsgText(){

        Connection con = null;
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            // MySQLに接続
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/javadb", "root", "パスワード");
            System.out.println("MySQLに接続できました。。");

            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery("select * from users");
            while(rs.next()) {
                String name = rs.getString(2);
                return "名前:"+name;
            }

        } catch (InstantiationException e) {
            return "Error InstantiationException";
        } catch (IllegalAccessException e) {
            return "Error IllegalAccessException";
        } catch (ClassNotFoundException e) {
            return "Error ClassNotFoundException";
        } catch (SQLException e) {
            return "MySQLに接続できませんでした。";
        } finally {
            if (con != null) {
                try {
                    con.close();
                } catch (SQLException e) {
                    return "MySQLのクローズに失敗しました。";
                }
            }
        }
    }
}

----------------------------------------
HelloWorld.java
----------------------------------------
さっき作ったものに、上のクラスを呼び出す2行を追加します。
>MyObj myObj = new MyObj();
>response.getWriter().write( myObj.getMsgText() );

package com.example.part1;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class HelloWorld
 */
@WebServlet("/HelloWorld")
public class HelloWorld extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public HelloWorld() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.getWriter().write("Hello, World!");

        /* 値を取得して表示します。 */
        MyObj myObj = new MyObj();
        response.getWriter().write( myObj.getMsgText() );

    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
    }

}

----------------------------------------
mysql-connector-java-5.1.38-bin.jar
----------------------------------------
ドライバーを Eclipse にドラッグ&ドロップしてコピーします。

C:\Program Files\MySQL\mysql-connector-java-5.1.38\
mysql-connector-java-5.1.38-bin.jar ← これを eclipse にドラッグ&ドロップ。
TomcatTest/WebContent/WEB-INF/lib/

----------------------------------------
http://localhost:8080/TomcatTest/HelloWorld
----------------------------------------
サーバーを再起動して、先ほどと同じURLにアクセスすると「Hello, World!」の後ろに表示されます。
文字化けしているかもしれませんが、それは別問題なのでひとまず無視してください。


────────────────────────────────────────
セッション
────────────────────────────────────────
ウェブアプリを作るならセッションの問題は必須です。
以下のページが分かりやすかったので読み書き部分だけ抜粋させていただきました。
下記サイトは通して学ぶのにとても参考になりますので、より深く理解したい方はぜひどうぞ。

サーブレットの様々なサンプル - セッションの管理 -
http://www.whitemark.co.jp/tec/webapp/servletExamples3.html

----------------------------------------
CookieServlet.java
----------------------------------------
以下のクラスを作成します。

package com.example.part1;

import java.io.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
import javax.servlet.ServletException;

@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
      
    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String tex = "Hello!";
        
    /* セッションを作成します。 */            
    HttpSession session=request.getSession(true);
    
    /* tex をセッションへ格納します。 */
    session.setAttribute("sessionKey1",tex);
          
    /* ContentType を設定*/
    response.setContentType("text/html; charset=Shift_JIS");

    /* 出力用 PrintWriter を取得*/
    PrintWriter out = response.getWriter();
        
    /* HTML 出力 */
    out.println("<html>");
    out.println("<head>");
    out.println("<title>Session Sevlet GET</title>");
    out.println("</head>"); 
    out.println("<body>");   
    out.println("<h2>セッションに値を設定しました。</h2>"); 
    out.println("<h2>" + tex + "</h2>"); 
    out.println("<form method=\"POST\" action=\""
             + request.getContextPath() + "/CookieServlet\">");  
    out.println("<input type=\"submit\" value =\"POST送信\">" );  
    out.println("</form>");   
    out.println("</body>");
    out.println("</html>");    
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    /* ContentType を設定*/
    response.setContentType("text/html; charset=Shift_JIS");

    /* 出力用 PrintWriter を取得*/
    PrintWriter out = response.getWriter();
        
    /* HTML 出力 */
    out.println("<html>");
    out.println("<head>");
    out.println("<title>Session Sevlet POST</title>");
    out.println("</head>"); 
    out.println("<body>");   
    out.println("<h2>セッションから値を取り出しました。</h2>"); 
    
    /* getAttribute を使用してセッションより値を取得 */
    out.println("<h2>" 
      + request.getSession(true).getAttribute("sessionKey1") + "</h2>");

    out.println("<form method=\"POST\" action=\""
      + request.getContextPath() + "/CookieServlet\">");  

    out.println("<input type=\"submit\" value =\"POST送信\"> ");  
    out.println("</form>");  
    out.println("</body>");
    out.println("</html>");    
    }
 } 

----------------------------------------
http://localhost:8080/TomcatTest/CookieServlet
----------------------------------------
ブラウザから確認できます。
ここまででウェブアプリ製作の基礎がそろいました。


────────────────────────────────────────
文字化け
────────────────────────────────────────
トムキャットさまは meta タグを聞いてくれないそうです。

----------------------------------------
JSPの場合
----------------------------------------
1行目に以下を追加。

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<!DOCTYPE html>
<html lang="ja" ng-app>
?

contentType : 表示させたい文字コード、 ageEncoding : ファイルの文字コード

----------------------------------------
サーブレトの場合
----------------------------------------
サーブレットの場合、表示の前に setContentType を追加。

response.setContentType("text/html; charset=utf-8");
response.getWriter().write("Hello, World!");


────────────────────────────────────────
json → obj, obj → json
────────────────────────────────────────
連想配列が使いにくい、他の言語のように自由気ままではない。
当然、json との相互変換も何が正解かよく分からない。
とりあえず今のところの着地点。
予めオブジェクト用のクラス(変数を覚えさせて呼び出すだけのクラス Bean)を作っておかなくて良い方法で製作しました。

----------------------------------------
Jackson のダウンロード
----------------------------------------
http://wiki.fasterxml.com/JacksonDownload
Streaming, Databind, Annotations
これ等を lib にインストール(ドラッグ&ドロップでいいと思う)

----------------------------------------
相互変換のクラスを作成
----------------------------------------
今回は違うパッケージにして作ってみました。
同じパッケージ内で作るときとの差は、

・メリット:なんとなく種類が違うので隔離して整理整頓したら気持ちよい。
・デメリット:指定するときにパッケージ名から書くので字が長い。

package com.webinko.javatest.entity;

import java.io.IOException;
import java.util.HashMap;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonUtil {

// json → obj
public static HashMap<String,Object> parse(String json){
    ObjectMapper mapper = new ObjectMapper();
   TypeReference<HashMap<String,Object>> typeRef = new TypeReference<HashMap<String,Object>>() {};
        HashMap<String, Object> obj   = new HashMap<String,Object>();
try {
obj = mapper.readValue(json, typeRef);
} catch (IOException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}    
    return obj;
   }
// obj → json
    public static String convert(Object obj){
        ObjectMapper mapper = new ObjectMapper();
        String json = "";
try {
json = mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
    return json;
   }
}

----------------------------------------
使用例
----------------------------------------
// json
String data = "{\"key1\":\"value1\",\"key2\":\"value2\"";
// json → 連想配列
HashMap<String, Object> obj = com.webinko.javatest.entity.JacksonUtil.parse(json);
System.out.println(obj); 
System.out.println(obj.get("key1")); 
// 連想配列 → json
String json = com.webinko.javatest.entity.JacksonUtil.convert(obj);
System.out.println(json);


────────────────────────────────────────
Jersey
────────────────────────────────────────
RESTful な Webサービスを提供するための道具、だそうです。

----------------------------------------
RESTful とは
----------------------------------------
1) HTTPを使ったシンプルなWebサービス
2) リソースは、一意なURLで識別される(ex.http://example.com/api/hoge/1234)
3) 特定のHTTPメソッドを使用して操作する(GET,POST,PUT,DELETE)
4) JSON, XML, YAML がサポートされている

らしいですが、何が特別なのか分かりません。

----------------------------------------
インストール
----------------------------------------

以下からダウンロードします。
https://jersey.java.net/download.html

Jersey JAX-RS 2.0 RI bundle 今はこっちを使いますです。
Jersey 2.22.1 Examples bundle はサンプル集です。これもダウンロードして後で参考にして下さい。

◆lib
zip の中の jarファイルを /WEB-INF/lib にコピーします。
api, ext, lib ぜんぶ直下で良いです。

◆/WEB-INF/web.xml
/WEB-INF/web.xml の中を以下のように書き換えます。
 右クリック → 次で開く → テキスト・エディター
 com.webinko.test001 はパッケージ名ですので適当に書き換えて下さい。
 下の方にある /api/* は http://localhost:8080/TomcatTest/api/クラス名 になるような記述です。
  TomcatTest はプロジェクト名ですので適当に書き換えて下さい。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.webinko.test001</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>

◆WebContent
WebContent に zip の中の index.html を置きます。
WebContent/index.html

----------------------------------------
動作確認
----------------------------------------
サーバーを再起動して以下で見れます。
JSONを返すだけの GET リクエスト。
http://localhost:8080/TomcatTest/api/loadMessages

POSTのテスト
http://localhost:8080/TomcatTest/
index.html が呼び出され、何かしら入力して「put message」をクリックすると、
putMessage に送信されて、コンソールに入力内容が表示されます。

----------------------------------------
Jersey とは
----------------------------------------
普通にウェブアプリ作ると1つのURL(クラス)につき以下のようなファイルを1つ作るのですが、

◆普通の書き方
package example.test;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class HelloWorld
 */
@WebServlet("/HelloWorld")
public class HelloWorld extends HttpServlet {
private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public HelloWorld() {
        super();
        // TODO Auto-generated constructor stub
    }

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().write("Hello, World!");
}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}

}

Jersey だと以下のようにスッキリ1つのファイルにまとめることができます。
◆Jersey の書き方

package org.ukiuni.inspect.jaxrs;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.ukiuni.inspect.jaxrs.entity.MyData;

@Path("/")
public class IndexAction {
@GET
@Path("/loadMessages")
@Produces(MediaType.APPLICATION_JSON)
public List<MyData> loadList() {
List<MyData> datas = new ArrayList<MyData>();
datas.add(new MyData(1, "test1"));
datas.add(new MyData(2, "test2"));
datas.add(new MyData(3, "test3"));
return datas;
}

@POST
@Path("/putMessage")
@Produces(MediaType.APPLICATION_JSON)
public void put(@FormParam("message") String message) {
MyData myData = new MyData();
myData.setMessage(message);
System.out.println("message = " + message);
// put Message
}
}


あと、アノテーションを書くとそれを Jersey が解釈してよしなにしてくれます。
@POST と書くと POST送信されたとき自動的にここで受け取ってくれます。
 同じ@Pathでも @GET、@PUT が違えば別物として扱ってくれます。
@Path("/putMessage") はURL、
@Produces(MediaType.APPLICATION_JSON) は送信内容をどう解釈するか、この場合は自動的に JSON と解釈してくれます。
@Consumes(MediaType.APPLICATION_JSON) はアウトプットです。
他にも色々あるようです。

私も今のところ良く分からないのですが、こんな感じで「ブラウザとの窓口部分を担当する」ものです。
ここから呼び出す先のものは普通の Java です。
CakePHP等のフレームワークのように全部面倒を見てくれるものではなく、窓口係です。
私は勝手に勘違いしてしまって悩みました。


────────────────────────────────────────
アノテーション
────────────────────────────────────────
基本的にコメントのことです。

//ほにゃらら
/*
ほにゃらら
*/

と同じです。
ただし、アノテーションと言われる

@ほにゃらら

という書き方にすると、Javaの方でも意味を理解して動作に影響を与えてくれることがあります。
どんなご利益があるかは不確定です。
例えば、Jersey のライブラリを入れていると前述のように @GET と書けば自動的に振り分けてくれたりします。


────────────────────────────────────────
多種多様な型は早めにしっかり把握しておかないといつまでも引き摺ります
────────────────────────────────────────
1ヶ月ほど Java をやった感想で一番印象的なのは以下です。

(1) とにかく型
(2) 連想配列1つにつき、プログラム1つを用意する必要がある。

(1) は PHP でも JavaScript でもうすぼんやりと使っていたと思いますが、だいたい融通利いてくれるので甘えていました。
しかし、Java では痛恨の一撃になります。ちょっとでも間違うとアウトです。
どういうことかというと、例えば「Java 型」とかで検索すると以下のような記述が出てきます。

データ型
booleantrue or false
char16ビットUnicode文字 \u0000?\uFFFF
byte8ビット整数 -128?127
short16ビット整数 -32768?32767
int32ビット整数 -2147483648?2147483647
long64ビット整数 -9223372036854775808?9223372036854775807
float32ビット単精度浮動小数点数
double64ビット倍精度浮動小数点数

「Java にはこれだけの種類の型があるのか、ちょっと多いけど、まぁ今までも MySQL やなんかはこれぐらいあったし、へーきへーき」
と最初は思うんですが、
ぜんぜんそんなことはありません。

例えば、上に書いていない配列いっこ取っても。

宣言方法(数字の配列)
int hoge[];
hoge = new int[5];
或いは、
int hoge[] = new int[5];
或いは、
int[] hoge;
hoge = new int[5];
或いは、
int[] hoge = new int[5];

ぜんぶ一緒です。
最初から値をまとめて入れておくときは以下。
int hoge[] = {2, 4, 6, 9, 11};

配列は宣言時に何個いれるかまで書きます。
[5]と宣言したら要素を5個持つ配列ということです。
配列は一度サイズが決められると変更することはできません。

そして、例えば
String[] stringArray = new String[10];
と宣言した直後に、
System.out.println(stringArray[0].length());
とした場合、即座にコケます。
他の言語のように、あれば表示、なければ無視とか undefined と表示するとか、は無いです。
一撃で死にます。
また、配列とよく似た型 List、とか話し出すときりがないのでやめておきますが、とにかく、プログラム読んでいるうちになんか知らん型がわらわら出てくる&ルールが様々。
ぜんぜん話がちゃうがな。(´・ω・`)←こんな顔になります。
しばしば、さんざんググっても何も出てこない、と思ったら誰かが独自で作ったクラス名(←型に使えるんです)だったとか。
_ノ乙(、ン、)_←こんどはこんな感じになります。
これは (2) にも関連します。

(2) Java では未確定なものは基本許されない感じです。
上記の配列のような仲間で、List や Map がありますが、これも結局
import java.util.*;
することで使える用意されたクラスです。
これも頻繁に使うにはちょっと不便なときもあるので、よく使う連想配列、例えばデータベースのテーブルの受け皿になるようなものは予め自分で用意することになります。
言い切ってしまうと、
どんなアプリもテーブルの数だけその連想配列用のクラスを作るところからスタート。
です。
CakePHP で言うところの、Model のようで Model ではなく、ほんとにデータを保持出し入れするだけの、連想配列の機能をいちいち自分で用意するのです。
このセッター・ゲッターだけが書かれたデーターを保持するだけのプログラム、クラス、小さな部品、を、あまり良く分からないときに見たら「なにがしたいんや」と思ったのですが、その後、Java の特性としてハッシュが柔軟に使えないということから「必須やな」と心得ました。

この2点と、その宣言方法や使い方を早いことしっかり把握しておかないと、いつまでも引きずります。
つまんないエラーと自分のまぬけさに凹めます。

さらに(まだ言うか)ジェネリクス・型変数も早いとこしっかり把握しておかないといけない。いけないです。
<T> ←こんなやつです。
説明すると長くなるのと、他に分かりやすく説明されているサイトがたくさんあるので適当にググってください。

逆に言うと、このへんを押さえておけば LAMP な人もひとまず大丈夫な気がします。
ほんとに、1日目からしっかり意識してればよかった。今だから言えるのかもだけれど。
(というか、CakePHP におんぶだっこだった私などは他でもけっこう苦戦していますがw)


────────────────────────────────────────
INSERT された ID
────────────────────────────────────────
auto_increment の値は、すぐ後に SELECT LAST_INSERT_ID() で取って下さい。
MySQL新しめのバージョン向けので似て非なる関数がありますが無視してください。