けんとのブログ

ぼやき&開発メモ

MySQLの文字コードutf8の扱いについて

2009年01月29日 13時36分55秒 | MySQL
MySQLの文字コード設定全てutf8の状態では、
windowsでMySQLコマンドラインから日本語データの格納はできない。→エラーが出る。

ただし、CSEから、CSEの文字コード設定をcp932にしておくと格納できる。→CSEで日本語データとして表示もできる。
この格納したデータをMySQLコマンドラインで表示すると文字化けした状態で表示される。

MySQLコマンドラインから格納、MySQLコマンドラインで表示するには、
クライアントの文字コードと、結果の文字コードをsjisに設定する。

SET character_set_client = sjis;
SET character_set_results = sjis;

これで、OK。
sjisで渡された日本語を内部的にはutf8で格納し、表示させる際にはsjisとして表示するので、
格納も、表示も日本語が正常に扱えるようになる。

※前述の「MySQLインストール」でも文字コードについて語っています。

Struts1.3導入

2009年01月29日 09時18分27秒 | Struts
Struts1.3.10を使用。
本家「http://struts.apache.org/」からDL

解凍→libディレクトリ内のjarファイルを全て、WEB-INF下のlibディレクトリにコピーし、ビルドパスに追加


~jspをstrutsタグを使って作成~

・先頭に、使うstrutsタグの種類を指定
%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
など、そのページで使うやつだけ書き足す。

・外部ファイルの指定方法が変わる
通常
<link rel="stylesheet" type="text/css" href="../css/style1.css"/>
としてたのを、
<link rel="stylesheet" type="text/css" href=""/>
とする。


~Formクラスを作成~

・ActionFormを継承させて、パラメータ名と一致するgetter,setterを作成。



~Actionクラスを作成~

・Actionを継承させて、

public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest req, HttpServletResponse res) {

を使用し、パラメータの値を何かしたい時はFormから呼び出す。

LoginForm lform = (LoginForm) form;
String id = lform.getId();
String pass = lform.getPass();


セッションに保持させる際は、

HttpSession session = req.getSession();
session.setAttribute("id", "id");

の様にして保持させる。
最後に必ず、Forwardを返す。

return mapping.findForward("result");



web.xmlファイルをWEB-INF直下に作成

web.xml

xml version="1.0" encoding="utf-8" ?>

!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

<servlet>

<servlet-name>act</servlet-name>

<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>

<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>

<servlet-name>act</servlet-name>

<url-pattern>*.do</url-pattern>
</servlet-mapping>


<welcome-file-list>
<welcome-file>/jsp/login.jsp</welcome-file>
</welcome-file-list>

</web-app>


WEB-INF直下にstruts-config.xmlを作成

struts-config.xml

?xml version="1.0" encoding="utf-8" ?>

!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://struts.apache.org/dtds/struts-config_1_3.dtd">

<struts-config>

<form-beans>
<form-bean name="loginForm" type="form.LoginForm"/>
</form-beans>

<action-mappings>

<action path="/test"

<forward name="result" path="/jsp/result.jsp"/>
</action>
</action-mappings>

</struts-config>

遷移先のjspをstrutsタグで作成。

tomcat6、eclipse3.4では、フレームワークを使わず、servletだけでアプリを作成した際は、自動で<Context>が書かれたxmlを作ってくれるのだが、
Strutsを使ったアプリでは自動で作成されなかった。なので、手書きで作る必要がある。
$CATALINA_HOME/conf/Catalina/localhost/内にプロジェクト名.xmlを作成し、

<Context path="/StrutsTest" reloadable="true" docBase="C:workspaceStrutsTest" workDir="C:workspaceStrutsTestwork" />

※StrutsTestはプロジェクト名 pathはプロジェクトの置き場所。
を作成した。

tomcatを起動させ、「http://localhost:8080/StrutsTest/」で最初の画面がでる。StrutsTestはプロジェクト名

最後に、
このままでは扱うパラメータが文字化けするので、
Strutsで扱う文字コードの設定をしておく。
filrersパッケージ作って、文字コード設定クラスをつくる。

package filters;

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;


//文字コード設定クラス。
public class SetCharacterEncodingFilter implements Filter {

public void init(FilterConfig arg0) throws ServletException{
}

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

request.setCharacterEncoding("utf-8");
chain.doFilter(request,response);
}

public void destroy(){
}
}

んで、web.xmlにこのクラスを起動時に読み込むように設定する。

<filter>
<filter-name>EncodeFilter</filter-name>
<filter-class>filters.SetCharacterEncodingFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>EncodeFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

以上

※一部<>を使うとweb上で表示されない箇所は<>を省略しています。



MySQL格納データの暗号化

2009年01月28日 16時09分17秒 | MySQL
CREATE DATABASE test

--バイナリデータ用のBOLB型でテーブル作成。MySQLリファレンス推奨型。
CREATE TABLE login_tb (no BOLB,id BLOB,pass BLOB);
--※BOLB型だとデータ取り出し時に文字化けしたのでVARCHARAに変更。
--16進数文字列が入るのでサイズ大きめで。
CREATE TABLE login_tb (no VARCHARA(500),id VARCHARA(500),pass VARCHARA(500));

--AES_ENCRYPT('暗号化前のデータ', '暗号を解くキー')で、暗号化前のデータが暗号化(バイナリデータ化)されて格納される。
--しかし!このままでは文字化けした状態で表示される。
INSERT INTO login_tb(no,id,pass) VALUES(1, AES_ENCRYPT('aaa', 'id_key'), AES_ENCRYPT('111', 'pass_key'));

--そこで暗号化された物を、HEX()関数で16進数に変換する。これで16進数アルファベット文字として表示される。
INSERT INTO login_tb(no,id,pass) VALUES(1, HEX(AES_ENCRYPT('aa', 'key')), HEX(AES_ENCRYPT('11', 'key')));
INSERT INTO login_tb(no,id,pass) VALUES(2, HEX(AES_ENCRYPT('bb', 'key')), HEX(AES_ENCRYPT('22', 'key')));
INSERT INTO login_tb(no,id,pass) VALUES(2, HEX(AES_ENCRYPT('cc', 'key')), HEX(AES_ENCRYPT('33', 'key')));
INSERT INTO login_tb(no,id,pass) VALUES(4, HEX(AES_ENCRYPT('bb', 'key')), HEX(AES_ENCRYPT('44', 'key')));
追加していく・・・

--注意点。キーをバラバラに設定するとややこしくなる。キーは全部同じものでいい。(必要であれば管理できる範囲で設定)
INSERT INTO login_tb(no,id,pass) VALUES(2, HEX(AES_ENCRYPT('aa', 'id_key')), HEX(AES_ENCRYPT('11', 'pass_key')));

--暗号化とは関係ない。普通の条件指定select文。
SELECT * FROM login_tb WHERE no=1;

--16進数の文字列でselect。結果。(id='EF85045714A54BAEEECC87285BE529BA'のカラム&レコード。)
SELECT * FROM login_tb WHERE id='EF85045714A54BAEEECC87285BE529BA';

--暗号化前の元の文字列でselect。結果。(id='EF85045714A54BAEEECC87285BE529BA'のカラム&レコード。)結果は上記と同じ
SELECT * FROM login_tb WHERE id= HEX(AES_ENCRYPT('bb', 'key'));

--16進数文字列でselect。元の文字列で表示。結果(bb)
SELECT AES_DECRYPT(UNHEX('EF85045714A54BAEEECC87285BE529BA'), 'key') AS new_column;

--idカラムを暗号化前の文字列で表示。
SELECT AES_DECRYPT(UNHEX(id), 'key') AS new_column FROM login_tb;

--idカラムとpassカラムを暗号化前の文字列で表示。
SELECT AES_DECRYPT(UNHEX(id), 'key'), AES_DECRYPT(UNHEX(pass), 'key') FROM login_tb ;

--暗号化前の元の文字列でselectし、元の文字列で表示。結果(aa)
SELECT AES_DECRYPT(UNHEX(id), 'key') AS new_tb FROM login_tb WHERE id= HEX(AES_ENCRYPT('aa', 'key'));


---暗号化とは関係ない・・・---
--カラム型変換
--ALTER TABLE テーブル名 MODIFY カラム名 新しいデータ型;
ALTER TABLE member ALTER COLUMN name BOLB;
ALTER TABLE member MODIFY name BLOB;
ALTER TABLE users MODIFY password VARCHAR(500);
--テーブル内データ削除
DELETE FROM member;
---ここまで関係ない----


--上記方法でもよいが、ストアドファンクションを使わないと、取り出す際、日本語が文字化けする。
--また、ソースに暗号化のキーがもろに登場するので、セキュリティ上よくない。

--functionをいじると、そのfunctionを使ったプログラム全てに影響が出るため、root権限者しかいじれない(作れない)様になっている。
--下記処理は全てのユーザがfunctionをいじれる様にする為の処理。
--こいつもrootで接続して実行しないと、rootでないと設定権限がないよー!とエラー!!
--また、この設定をしないとcreate functionで権限がないよー!とエラー。
MySQLコマンド
SET GLOBAL log_bin_trust_function_creators = 1;
を実行し、functionを作成。
functionを作ったら元に戻す。

SET GLOBAL log_bin_trust_function_creators = 0;

--上記処理に関して
MySQL5.0.16から導入されました。
この値はバイナリログが有効のときに適用されます。
Stored Function(以下関数)を作成できるユーザが、
信用できない関数を作成する可能性があるかどうかを制御します。
関数の内容によっては、
危険な状況を引き起こすようなバイナリログへの書き込みがなされる事があります。

この値を0(デフォルト)にすると、
SUPER および CREATE ROUTINE(ALTER ROUTINE) 権限を持たないユーザは
関数を作成(更新)することを許可されません。
0にすることはまた、関数を
DETERMINISTIC / READS SQL DATA / NO SQL のいずれかの特性を持った
形で作らなければならないという事を意味します。
この値を1にすると、そのような制限は課せられません。


--簡単なストアドファンクションの例。hello()という関数をつくる。concat()は元々MySQLに登録されている文字連結関数。
CREATE FUNCTION hello(input VARCHAR(200)) RETURNS VARCHAR(100) RETURN concat('Hello, ', input, '!');
--hello()に引数'ttttttttttt'を渡して実行。(表示)
SELECT hello('tttttttttttt');
--結果(Hello,ttttttttttt!)

--同じ名前のファンクションは作れないので間違ったときは一旦削除。
DROP FUNCTION hello ;
DROP FUNCTION decodes ;

--同様に暗号化の為のdecodes関数を作成。格納できる文字数は必要に応じて設定。
CREATE FUNCTION decodes(input VARCHAR(500)) RETURNS VARCHAR(64) RETURN AES_DECRYPT(UNHEX(input) ,'key');

SELECT decodes(引数);


Log4jの雛型

2009年01月28日 15時52分01秒 | Log4j
プロパティファイルとして作成。

//log4jプロパティファイル内容。

ここから↓

#全てのログはデバッグレベル出力。AppenderはA1,A2という名前である。
log4j.rootLogger=DEBUG, A1,A2
#パッケージごとにデバッグレベルを変える場合は下記のように個別に指定。「packName」はパッケージ名。任意。
#log4j.logger.packName=info,A1,A2
### direct log messages to A1 ###

#A1の設定。ファイルに出力。
log4j.appender.A1=org.apache.log4j.FileAppender
#出力先
log4j.appender.A1.File=C:\\aa ←任意の出力先指定
log4j.appender.A1.Append=true
#出力レイアウト
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
#レイアウト定義
log4j.appender.A1.layout.ConversionPattern=%d %-5p %c - %m [%t] (%F:%L)%n

### direct log messages to A2 ###

#A2の設定。コンソールに出力。
log4j.appender.A2 = org.apache.log4j.ConsoleAppender
log4j.appender.A2.Target = System.out
#出力レイアウト
log4j.appender.A2.layout = org.apache.log4j.PatternLayout
#レイアウト定義
log4j.appender.A2.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

↑ここまで


log4j.jarをビルドパスに通す。
javaですること↓

//Loggerクラスをインポート。
import org.apache.log4j.Logger;

//Loggerを作成する。
Logger logger = Logger.getLogger(First.class); ←このソースを書くクラス名
logger.debug("initメソッド通過");

プロパティエディタについて

2009年01月28日 15時45分39秒 | プロパティファイル・エディタ
J2EEアプリケーションの設定ファイル(あるいは国際化対応)は、プロパティファイルを利用することになる。
しかし、仕様上プラットホーム非依存を実現するために、
ファイル内のマルチバイト文字をJ2SDKに付属の「native2ascii」ツールでUnicodeに変換しなければならない。
たいした手間ではないものの、頻繁に「native2ascii」を実行するのも面倒である。

そこで、プロパティファイル編集用のeclipseプラグインをインストールする。
このプラグインでは、プロパティ編集中はマルチバイト文字で表示させ、
保存時に自動的にUnicodeに変換してくれる。

プラグインのインストール手順は「rough justice プロパティエディタ プラグインのインストール」
「http://www.esco-sb.jp/blog/roughjustice/archives/2006/02/post_1.php」参照。
完了後はEclipseで作った拡張子「.properties」のプロパティファイルを自動的にプロパティエディタで開いてくれる。

プロパティファイルについて

2009年01月28日 15時37分59秒 | プロパティファイル・エディタ
拡張子は「.properties」
classesフォルダに置く。srcフォルダの方を変更しても、classesファイルの方には反映されないので、
必ずclassesフォルダの方を変更する必要がある。

~DB接続設定をプロパティファイルで書く場合~
//プロパティファイル内容。
mysql.jdbc.driver=org.gjt.mm.mysql.Driver
mysql.jdbc.url=jdbc:mysql:///database名?useUnicode=true&characterEncoding=SJIS
mysql.jdbc.user=root
mysql.jdbc.password=root ←設定していない場合は「mysql.jdbc.password=」となる

//プロパティファイル読み込み。
ResourceBundle rb = ResourceBundle.getBundle("mysqljdbc");

// プロパティファイルから値を取得。
String driver = rb.getString("mysql.jdbc.driver");
String url = rb.getString("mysql.jdbc.url");
String user = rb.getString("mysql.jdbc.user");
String password = rb.getString("mysql.jdbc.password");


プロパティファイルを直接指定する場合にはストリームクラスとPropertiesクラスを用いて取得する。
また、ResourceBundleクラスを用いて取得することもできる。
ResourceBundleクラスの方がロケールの解決等をしてくれ取得が楽なため、
ResourceBundleクラスを用いて取得した方がよい。

プロパティファイルにASCII文字以外の文字列を記述する場合には、Unicodeに変換する必要がある。
Unicodeへの変換は、J2SEに付属しているnative2asciiコマンドを使用する。
変換後のファイルは「プロパティファイル名_言語コード.properties」とする。
「言語コード」はロケールで使用される言語コードであり、日本語であれば「ja」となる。
この命名規則を使用することで、リソースバンドル使用時にロケールの自動解決が行われる。

プロパティファイルを使用することで、プログラムの設定を外部ファイル化することができる。
そうしない場合、設定はプログラム上にハードコーディングされることになり、
設定の変更に再コンパイルが必要となる。プロパティファイルを用いることで、
再コンパイルをせずに設定を変更でき、また設定をひとつにまとめることができるようになる。

Linuxにサーバー構築

2009年01月28日 15時16分26秒 | Linux
まずWinSCPをWindowsにインストールする。

必要なインストールデータを全てWindowsの任意のフォルダにダウンロードする。
※Windous用と間違わないようにする。Linux用!

WinSCPを起動させ、インストールデータをLinuxのrootフォルダにコピーする。

java,tomcatのインストール。
環境設定はHP「JavaでHello World」を参照。分かりやすい。

MySQLのインストールは「データベースサーバー構築(MySQL) - Fedoraで自宅サーバー構築」
「http://fedorasrv.com/mysql.shtml」を参照。分かりやすい。

それぞれ動作確認しながら確実にインストールを完了させる。

インストールしたtomcatのwebappsフォルダ内にwindowsで作成したアプリケーションフォルダをコピーする。

URLに「http://linuxサーバーのアドレス:8080/コピーしたフォルダ名/表紙のjspファイル名」を指定すると、表示される。

だた、Linuxは文字コードSjisを知らないため、MySQLで文字化けが起こる。
DBから取り出した日本語のデータが文字化けする。

そこで、MySQLの文字コードをUTF8に設定する。
「MySQL 文字化けを防ぐ、文字コードの確認と設定 渋谷生活」
「http://www.avant-tokyo.com/linux/mysql_character_set.html」

ここの「文字コードを設定する」のところを引用させて頂いた。

[client]の項目は追加した。

MySQLを起動させ、
mysql>statusでステータスを確認し、全てのCHARACTER(文字コード)がUTF8になっていることを確認。

mysql>select * from テーブル名;でテーブル内容を表示させ、内容が文字化けしていないことを確認。

tomcatを再起動させ、確認。web上でも文字化けが直っていればOK!

Linuxについて

2009年01月28日 15時11分46秒 | Linux
Linuxにも様々なOSがある。
今回はCentOS5.0をインストール。
※インストール方法、Linux,CentOSの利点に関しては参考書を参照。

インストールはLinuxをインストールするPCのコマンド上で行い。
インストール後はWindousにUTF-8 Tera Term Proをインストールし、リモートでLinuxを操作する。

UTF-8 Tera Term Proを起動しログインすると、はじめに
[root@redhat src]# と出てくる。
この横にコマンドを入力することとなる。

ファイル管理コマンド
テキスト表示コマンド
に関しては実際に入力してみて、動きの確認をしながら操作に慣れるしかない。

エディタ(vi)の操作として、今までと最も違う点は、コマンドモードと、入力モードがある点。
入力モードでソースを書いたり、書き換えたりする。
コマンドモードではキーボードのキーに様々な意味があるので、うかつに触ると危ない。
vi {エンター}でviエディタが起動。
何かのファイルのソースをいじりたいときは、vi ファイル名 {エンター}でそのファイルのソースを開く。
その他、データを保存して終了、しないで終了、入力モード・コマンドモードの切り替え、コマンドモードでのカーソル移動など、
詳細は「Linuxコマンド」「http://cyberam.dip.jp/linux_command/command/com_main.html」参照。