OracleクライアントをインストールせずにSQL*Plusを使う方法

同僚がLinuxからSQL*Plus使えるようにしてって言うから、「えぇー面倒くさー」と思いつつOracleクライアントを探してきてインストールしようとしたら・・・。なんと、いまはOracleクライアントをインストールしなくても(システムを汚さなくても)SQL*Plusを使ったり出来るらしい!知らんかった!これ↓
http://www.oracle.com/technology/global/jp/tech/oci/instantclient/instantclient.html

流れとしては、以下のファイルをダウンロードしてきて

  • basic.zip
  • sqlplus.zip

適当な場所に解凍して、環境変数を設定してsqlplusコマンドを実行するだけ!超簡単。そして、システム汚れない。
ちなみに詳しい設定方法は以下のPDF参照。
http://otndnld.oracle.co.jp/software/tech/oci/instantclient/pdf/Instant_Client_SetUp.pdf

1. ファイルをダウンロードしてきて解凍

/home/testに「basic.zip」「sqlplus.zip」を置いてunzip。すると「instantclient_11_1」っていうフォルダに必要なものが全部入る。

$ unzip basic.zip
Archive:  basic.zip
  inflating: instantclient_11_1/BASIC_README
  inflating: instantclient_11_1/adrci
  inflating: instantclient_11_1/genezi
  inflating: instantclient_11_1/libclntsh.so.11.1
  inflating: instantclient_11_1/libnnz11.so
  inflating: instantclient_11_1/libocci.so.11.1
  inflating: instantclient_11_1/libociei.so
  inflating: instantclient_11_1/libocijdbc11.so
  inflating: instantclient_11_1/ojdbc5.jar
  inflating: instantclient_11_1/ojdbc6.jar
  
$ unzip sqlplus.zip
Archive:  sqlplus.zip
  inflating: instantclient_11_1/SQLPLUS_README
  inflating: instantclient_11_1/glogin.sql
  inflating: instantclient_11_1/libsqlplus.so
  inflating: instantclient_11_1/libsqlplusic.so
  inflating: instantclient_11_1/sqlplus

2. sqlplusを簡単に実行するためのスクリプトを書く

/home/testにsqlplus.shを作成
普通に.bashrcとかに環境変数書いておいてもいいけど、こうしとくとさらにシステムが汚れないので。

#!/bin/bash
LD_LIBRARY_PATH=/home/test/instantclient_11_1
PATH=$LD_LIBRARY_PATH:$PATH
NLS_LANG=JAPANESE_JAPAN.AL32UTF8
export LD_LIBRARY_PATH PATH NLS_LANG

# sqlplus ユーザ名/パスワード@ホスト名:1521/orcl
sqlplus scott/tiger@192.168.0.20:1521/orcl

Linuxの場合はLD_LIBRARY_PATHとPATHにinstantclient_11_1(今回は/home/test/instantclient_11_1)の場所を指定しておく必要があるみたい。
NLS_LANGはOracleをインストールした環境に合わせるといいらしく、今回のOracleLinuxにインストールされていたので、「JAPANESE_JAPAN.AL32UTF8」となっていた。Windowsの場合はきっと「JAPANESE_JAPAN.JA16SJIS」なんだろう。

3. sqlplus.shコマンドを実行

実行権限をつけて・・

$ chmod +x sqlplus.sh

実行!

$ ./sqlplus.sh

SQL*Plus: Release 11.1.0.6.0 - Production on 火 7月 14 13:03:20 2009

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
に接続されました。
SQL>

接続されたらしい!

Windows版は試してないけど似たようなもんだと思われる。
今のところちょっとSQL*Plus使いたいんだけどって時に使うような場合しか思い浮かばないんだけど、使えると便利。
Windowsに入れてObjectBrowserとか使えたりするんだろうか。それは、無理かな・・。

Slim3、GAE/JでGoogleアカウントの認証 その2

前のエントリーで色々ご指摘いただいたので試してみました。
Googleアカウントを使ってGAE/Jアプリのログイン処理の実装 - ありの日記

独自の認証フィルターを作って認証をかける

debit-credit-monkeyさんからの提案。独自のサーブレットフィルターを作って認証させたくないやつ(index.jspとか)は認証させないようにして、それ以外は認証させるという方法。
まず、javax.servlet.Filterを実装したAuthFilterクラスを作成し、web.xmlに登録。init-paramで認証を除外したいURLを渡せるようにする。
まず、AuthFilterを作る。

package slim3.it;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

public class AuthFilter implements Filter {

    private String[] excludes;
    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        UserService userService = UserServiceFactory.getUserService();
        String thisURL = ((HttpServletRequest) request).getRequestURI();
        if (((HttpServletRequest) request).getUserPrincipal() == null) {
            if (!isExcludePath(thisURL)) {
                // × 除外したURLのアクセスの場合、ログイン画面にリダイレクトする[このコメントは間違い]
                // ○ 除外したURL以外へのアクセスの場合、ログイン画面にリダイレクトする
                ((HttpServletResponse) response).sendRedirect(userService
                  .createLoginURL(thisURL));
                return;
            }
        }
        chain.doFilter(request, response);
    }
    /**
     * リクエストされたURLが除外対象か判断する。
     * 除外対象の場合trueを返す
     * @param thisURL
     * @return
     */
    private boolean isExcludePath(String thisURL) {
        String[] excludes = this.excludes;
        for (String path : excludes) {
            // 除外対象パスの最後が「*」の場合、indexOfで含まれるか確認
            if (path.indexOf("*") == path.length() - 1) {
                if (thisURL.indexOf(path.substring(0, path.length() - 2)) >= 0) {
                    return true;
                }
            } else {
                // 上記以外は、完全一致
                if (thisURL.equals(path)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
        String exclude = config.getInitParameter("exclude");
        if (exclude == null) return;
        this.excludes = exclude.split(",");
    }
}

そして、web.xmlにこのフィルターを登録。init-paramに除外したいURLを指定。

	<filter>
		<filter-name>authFilter</filter-name>
		<filter-class>slim3.it.AuthFilter</filter-class>
		<init-param>
			<param-name>exclude</param-name>
			<param-value>/index.jsp,/css*,/_ah/login*</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>authFilter</filter-name>
		<url-pattern>/*</url-pattern>
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>FORWARD</dispatcher>
		<dispatcher>INCLUDE</dispatcher>
		<dispatcher>ERROR</dispatcher>
	</filter-mapping>

ここでは、「index.jsp」と「/css*」で始まるパスと、「/_ah/login*」で始まるパスを認証除外対象としている。ちなみに「/_ah/login*」はローカル環境でシミュレートされるGoogleアカウントのログイン画面のURL。実際のサーバにデプロイしたらログイン画面は違うサイトに飛ばされるからその場合は関係ないかな。
とりあえずこのコードで動くけど、ちゃんとテストしてないしこんな実装でいいのかも不明なので自己責任でお願いします(’◇’)

/memberで始まるURLに対してのみ認証をかける。

web.xml側の設定はそのまま以下のようにすればよい。

<security-constraint>
	<web-resource-collection>
		<url-pattern>/member/*</url-pattern>
	</web-resource-collection>
	<auth-constraint>
		<role-name>*</role-name>
	</auth-constraint>
</security-constraint>

そして、ここからひがさんに教えてもらった方法。Slim3で使用するコントローラにプレフィックスをつけることができるらしいので、パッケージを以下のように変更。

slim3.it.controller.todo
↓
slim3.it.controller.member.todo

memberってのが新たに付け加えたところ。そして、その下のtodoパッケージ内にEditController.javaがあり、これにアクセスする時のURLはこうなる。

http://ホスト名/member/todo/edit

なので、認証をかけたいコントローラたちは「slim3.it.controller.member.〜」って感じで追加してゆけばよい。(この例では会員が使うであろう機能をmemberパッケージ以下に押し込むことを想定しています)
ちなみにJSPの場所もwar/member/todoとする必要がある。さらっと。

使い方としてはこんな感じにすることの方が多いかもね。
ユーザ側の画面や管理者側の画面があるアプリだとこの例のように、memberとか、adminとかってパッケージ分けて作ったりしそうだね。