2009年3月 4日 (水)

JAVA 正規表現ですべての文字にマッチさせるセット

Javaの正規表現には癖がありますねぇ…
Perl癖が何年たっても抜けていないからそう感じるだけかもしれません。

Javaの正規表現でほとんどの文字にマッチしてとても便利な「.(ドット)」
ただこいつはデフォルトでは改行にマッチしてくれません。
Patternクラスを使ってマッチさせる方法もあります「DOTALL」をナンタラカンタラ…

↓詳しくはここ↓
http://www.mlab.im.dendai.ac.jp/~yamada/java/regex/

だがしかし、Patternクラスを使うと言うことで、Patternを使っていない
時この正規表現が使えません
String#replaceAll とかね

でなんか代替えできない物かと考えた結果がこれ
「(.|\\s)」 \s(ソース場では\\s)が改行などの空白文字にうまくマッチしてくれるので
.(ドット)を補完できます。

業務で使ったのですが、汎用的なサンプルが思いつきません(^^;

こんなんでfontタグを削除できるかな?
html_tag = html_tag.replaceAll("<(/)?font((.|\\s)+)?>","");
スイマセン試してないです。

| | コメント (0) | トラックバック (0)

2007年11月15日 (木)

WTP2.0が出てる

いつの間にやらWTP2.0がリリースされています。
http://www.eclipse.org/webtools/
2ヶ月遅れの情報です(=_=;

日本語版検索やるとgoogleでもyahooでもこういった国際プロジェクト(日本語ページなし)
の本家サイトになかなかたどり着けない…どうにかならないものでしょうか?

WTP 1.5系は重かったためスルーした私ですが2.0はどうなんでしょうか?
重い、軽いと言ったレポートは検索してもHITしませんでした。
自身で試せるのは…スケジュール的に12月位かな、、、
そのうちレポートします。

| | コメント (0) | トラックバック (0)

2007年10月 2日 (火)

JBossのログ(searver.log)肥大を止める

HibernateのHARアーカイブをJBossで使用しているとともかくログの肥大化に悩まされます。
単純に標準出力に出ているのかとあきらめていましたが実はこれがlog4jで
制御されていることに気がついたのでこれを利用していろんなログを黙らせて見ました。

/jboss/searver/default/conf/log4j.xml
/jboss/searver/default/conf/jboss-log4j.xml (4.2.X系)

Hibernateが五月蝿いと感じているあなたは
上記ログ制御ファイルに以下の文をぶち込みます。
   <category name="org.hibernate">
      <priority value="INFO"/>
   </category>

これでもうるさいと思う人はWARNでもいいんじゃないでしょうか?
他にもJakarta系はログが五月蝿い…もとい丁寧なログが出力されています。

HttpClientを使っていればこれも有効でしょう
   <category name="httpclient.wire">
      <priority value="INFO"/>
   </category>

EHCacheをHibernateで使っている方はこれも有効
   <category name="net.sf.ehcache">
      <priority value="INFO"/>
   </category>

自分はこんなもんでだいぶスッキリしました。
アクセスログは別に取っているんでついでにwwwのカテゴリーの出力を
黙らせたりもしましたが…

詳しくこのあたりを理解したい人はLOG4Jのドキュメントを読んでください。
LOG4Jの解説は既に優秀な先人がいくつもレポートしているのでココで取り上げる
予定はありません。

| | コメント (0) | トラックバック (0)

2007年9月19日 (水)

Commons-email で大量にメール送信する

jakarta プロジェクトの commons-email たいへん便利ですね。
あれだけしちめんどくさいBASE64エンコードしてmime/multipartに
組みなおしてだのの処理を引き受けてくれるので簡単にHTMLメールだの
添付ファイル付きのメールだのをJavaで送信できます。
ただ一回のSMTPコネクションで同時に複数のメールを送信することは
あまり考慮されていません。

アラート機能やメルマガ等々実際プログラムしていると複数の
時には大量のメールを一度に配信しなければならないことも多い
のでこれは不便です。
ということでコレ無理やりやってみました。

Jakarta Commons Email
http://commons.apache.org/email/
(基本的な使い方は扱いません↑DLするとexample付いてくるのでそれでも見てください)

◆基本形はこんな感じ


HtmlEmail email = new HtmlEmail();
email.setFrom("from@hoge");
email.setHostName("localhost");
email.setSentDate(Calendar.getInstance().getTime());
email.setSubject("example title");
email.setCharset("iso-2022-jp");
URL image_url = new URL("file:/home/homepage/public_html/image/test.gif");
String cid = email.embed(image_url, "test.gif");
email.setHtmlMsg("<html><body><img src=\"cid:"+cid+"\" /></body></html>");
email.setTextMsg("test");
//Vector Dummyto = new Vector();
//Dummyto.add(new InternetAddress("to@hoge"));
//email.setTo(Dummyto);
email.addTo("to@hoge");
email.send();             

◆メルマガを想定成功例(送信先だけ返るBCCは使わない)

Properties props = new Properties();
props.put("mail.smtp.host", "localhost");
props.put("mail.host", "localhost");
props.put("mail.from", "from@hoge");
props.put("mail.smtp.from", "from@hoge");
javax.mail.Session mail_session = javax.mail.Session.getInstance(props);
Transport transport = mail_session.getTransport("smtp");
transport.connect();

HtmlEmail email = new HtmlEmail();
email.setFrom("from@hoge");
email.setHostName("localhost");
email.setSentDate(Calendar.getInstance().getTime());
email.setSubject("example title");
email.setCharset("iso-2022-jp");
URL image_url = new URL("file:/home/homepage/public_html/image/test.gif");
String cid = email.embed(image_url, "test.gif");
email.setHtmlMsg("<html><body><img src=\"cid:"+cid+"\" /></body></html>");
email.setTextMsg("test");
email.addTo("to@hoge");
email.buildMimeMessage(); //ポイントgetMimeMessage();で返されるmessageはこの関数で精製される
MimeMessage message = email.getMimeMessage();
for(int i=0;i<10;i++){
    InternetAddress[] to_array = {new InternetAddress( "to"+i+"@hoge")};
    message.setRecipients(Message.RecipientType.TO,to_array);
    transport.sendMessage(message,to_array);
}
transport.close();

ポイント①
javax.mail のTransportクラスでSMTP接続を制御できる。
MimeMessageを精製できればTransportクラスに渡すことが可能になる。

ポイント②
email.buildMimeMessage(); とMimeMessage message = email.getMimeMessage();で
MimeMessageを作成してあて先の書き換えにはMimeMessageを使用する。
HtmlMailクラス等は基本的に書き換えを考慮していない。

◆失敗例―コード省略概要
HtmlEmail には addTo 以外にも setToがあったりするこれを利用しようとしたが
HtmlEmail は書き換えを想定していないらしく2度目以降のemail.buildMimeMessage();
で不可解なMimeMessageを精製するようになる(画像も本文も2倍になる)

| | コメント (0) | トラックバック (0)

2007年8月24日 (金)

JSPでリダイレクトをかける前にresponseを返してしまったエラー

JSPでリダイレクトをかける前に大きなデータを出力していたところ以下のようなエラーが発生した。
(割と初歩的なエラーのレポートです。)

java.lang.IllegalStateException
    at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:432)
    at org.apache.jsp.tools.melo_jsp._jspService(melo_jsp.java:868)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
    at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:524)
    at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
    at org.apache.catalina.valves.FastCommonAccessLogValve.invoke(FastCommonAccessLogValve.java:495)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
    at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:199)
    at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:282)
    at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:754)
    at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:684)
    at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:876)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
    at java.lang.Thread.run(Thread.java:595)

このエラーが発生したJSPでは以下のような感じで長々と処理前にHTMLのヘッド部分
(JavaScriptでかなり膨大な量)を返していた。
<%@ page contentType="text/html; charset=Shift_JIS" %>
<%@ page import="java.sql.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="javax.naming.*"%>
<html>
<HEAD>
<BASE target="body">
<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<META name="GENERATOR" content="IBM WebSphere Studio Homepage Builder Version 8.0.0.0 for Windows">
<META http-equiv="Content-Style-Type" content="text/css">
<TITLE></TITLE>
<LINK rel="stylesheet" href="melo-cahx.css" type="text/css">
<script language="JavaScript">
<!--
(中略とても長いJavaScript)
-->

原因はまさにこれ、JSPではある程度の出力がoutに溜まると
responseを自動的に返してしまう。
responseはHTTPのヘッダーとコンテンツ内容になる。
リダイレクトはHTTPのヘッダーで処理を行うからresponseを返し始めた
JSPでリダイレクトをすることはできない。それでこんなエラーが出てしまう。
今回対策としてはJavaScriotを外部化しリダイレクト指示までに出力する
データ量を抑えることで対処した。

| | コメント (0) | トラックバック (0)

2007年7月30日 (月)

Java6でGIF(アニメも)扱えるぞ!!

今まで読み込みまでしかデフォルトのAPIセット(Java2D)で
扱えずGIFの書き出しには外部のAPIを使用するしかありませんでした。
(自分はACMEを使っとりました)

しかし特許の問題も解決し(特許保有者が権利更新をしなかった)て久しい今
Java6からGIFが書き出しを含めて扱えるようになったようです。
アニメーションGIFをソースにした場合も最初のフレームのみ読み込めるもよう
http://java.sun.com/javase/ja/6/docs/ja/api/javax/imageio/package-summary.html
http://java.sun.com/products/java-media/jai/iio.html

プロダクトにはまだJava5主力でときにはJava1.4 1.3を採用していますが
これは今後Java6も視野に入ってきますね。
Java5の採用動機はTomcatの対応でしたが(1.4が非対応になった)
Java6の動機はGIFが扱えるようになったという前向きな動機になりそうです

| | コメント (0) | トラックバック (0)

2007年4月13日 (金)

AntのTaskを作る

Eclipse経由でAntを使うのがたいへん便利で簡単だ。
結構はまってきたのでTaskを自作してより使い倒そうとたくらんでいる
取り急ぎメモ

◆基本的 作り方
http://www.atmarkit.co.jp/fjava/javatips/076jakarta003.html


よくまとまっているけどパラメータの渡し方が書いてない

◆パラメータの渡し方

http://www.onjava.com/pub/a/onjava/2004/06/02/anttask.html

普通のBeanのように setXxxx getXxxx を用意しておけば
xxx="" でパラメータが渡せるということらしい。

[参考]
http://www.atmarkit.co.jp/fjava/javatips/076jakarta003.html

http://www.onjava.com/pub/a/onjava/2004/06/02/anttask.html

http://ant.apache.org/

| | コメント (0) | トラックバック (0)

2007年4月12日 (木)

文字のunicode表現をJavaで求める

Javaではunicodeを用いて\uXXXX の形式で文字を表すことができる
このコードを求める方法をいろいろ調べてみた。
適当な資料が見つからなかったのであたりをつけて分析

            String line = "あいうえお";
            for(int i=0;i<line.length();i++){
                String base = line.substring(i,i+1);
                byte[] codes = base.getBytes("UTF-16");
                String code = "";
                for(int j=0;j<codes.length;j++){
                    int tmp = (int)codes[j];
                    if(tmp < 0){tmp= tmp + 256;}
                    String dscode = Integer.toHexString(tmp);
                    if(dscode.length() < 2){dscode="0"+dscode;}
                    code+=dscode;
                }
                System.out.println(base+"=>"+code+"");
            }
            if(true){
                byte[] codes = line.getBytes("UTF-16");
                String code = "";
                for(int j=0;j<codes.length;j++){
                    int tmp = (int)codes[j];
                    if(tmp < 0){tmp= tmp + 256;}
                    String dscode = Integer.toHexString(tmp);
                    if(dscode.length() < 2){dscode="0"+dscode;}
                    code+=dscode;
                }
                System.out.println(line+"=>"+code+"");
            }
            System.out.println("\u304a");

出力結果
あ=>feff3042
い=>feff3044
う=>feff3046
え=>feff3048
お=>feff304a
あいうえお=>feff3042304430463048304a

こんな感じfeffはUTF16の頭につける決り文句のようであるので
feffを除いた部分がその文字のユニコード表現ということになる。

| | コメント (0) | トラックバック (0)

Javaのbyte型を16進数で表現

バイナリデータを扱う時 0x00 の形式でデータを出力したい時がままある。
Javaのbyte型 は (-27) ~(27-1) つまり -128 ~ 127 なので
0~255までを0x00~0xffで表現する同形式に素直に変換できない
http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/java/lang/Byte.html#toString()

ちなみにbyte型は
0x00 ~ 0xff ⇒ 0 ~ 127 、-128 ~ -1 のようにいったん整数で進んだ後
-128に行き-1まで数字が大きくなって進んでゆく。
そこでこんな感じにしてみた

                    int int_value = (int)byte_value;
                    if(int_value < 0){int_value = int_value + 256;}
                    String hex_value = Integer.toHexString(int_value);

| | コメント (0) | トラックバック (1)

2007年4月11日 (水)

JkMountの設定のクセ

mod_jkでApache設定ファイルに記述するJkMountの書き方にクセがある

JkMount /a/ work

<VirtualHost *:80>
      ServerName hoge.hoge
</VirtualHost>

<VirtualHost *:80>
      ServerName hoge2.hoge
      JkMount /b/ work
</VirtualHost>

↑の用に設定したとき
hoge.hogeドメインでアクセスした場合
/a/
がマウントされている(ココまでは普通)
hoge2.hogeドメインでアクセスした場合
/b/
のみがマウントされていて/a/はマウントされない
JkMountを<VirtualHost>内で使用するとそれまでの設定がリセットされることになる。
仮に/a/もマウントしたい場合は<VirtualHost>内でもう一度宣言する

JkMount /a/ work

<VirtualHost *:80>
    ServerName hoge.hoge
</VirtualHost>

<VirtualHost *:80>
    ServerName hoge2.hoge
    JkMount /b/ work
    JkMount /a/ work
</VirtualHost>

| | コメント (0) | トラックバック (0)

より以前の記事一覧