部落客廣告聯播

2009年9月18日 星期五

啟用tomcat內建之HTTPS

1. 到 %JAVA_HOME%\bin目錄, 執行:
keytool -genkey -alias tomcat -keyalg RSA
輸入keystore密碼: **********
您的名字與姓氏是什麼?
[Unknown]: Lili.Wang
您的組織單位名稱是什麼?
[Unknown]: myCompany
您的組織名稱是什麼?
[Unknown]: myCompany
您所在的城市或區域名稱是什麼?
[Unknown]: Taipei
您所在的州或省份名稱是什麼?
[Unknown]: Taiwan
該單位的兩字母國家代碼是什麼
[Unknown]: TW
CN=Lili.Wang, OU=myCompany, O=myCompany, L=Taipei, ST=Taiwan, C=TW正確嗎?
[否]: y

輸入的主密碼
(如果和 keystore 密碼相同,按回車): {{直接按enter}}

2. 編輯 tomcat 的conf\server.xml找到下面區段,取消註解,並加上紅字部分,紅字雙引號內的值與第一步的密碼要相同
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true" keystorePass="**********"
clientAuth="false" sslProtocol="TLS" />

3. 重啟Tomcat

4. 開啟瀏覽器 https://localhost:8443 ,測試是否成功

(P.S. 要注意的是如果用admin1身份執行tomcat,則就要以admin1登入執行
keytool -genkey指令)

2009年9月17日 星期四

Tomcat 開啟 Access Log

Access Log會紀錄哪個時間哪個IP連入tomcat哪個網址,
tomcat是使用VALV的機制達成(類似filter),預設並無開啟,
若要開啟則須 修改conf\server.xml,找到內有一段
directory="logs" prefix="localhost_access_log." suffix=".log"
pattern="common" resolveHosts="false"/>
把前後包夾的註解符號拿掉後,存檔,重啟tomcat,便會在log目錄裡面看到
localhost_access_log.開頭的紀錄檔了。

2009年8月19日 星期三

tomcat server.xml設定全域的DataSource / mailSession資源

所謂全域就是指同一tomcat中的所有context

1. 在server.xml的<globalnamingresources>中加入新的<resource>元素。
2. 在context.xml的<context>中加入 <resourcelink name="mail/MailSession" global="mail/MailSession" type="javax.sql.DataSource"></resourcelink>

2009年8月4日 星期二

JAVA Cache System

Java Cache System 是Apache Jakarta下的一個子專案,
下為一篇介紹Java Cache System的文章:

Knowing Cache and Java Cache System(英文)

Apache的Mail Server、FTP Server都是純JAVA的

Apache JAMES Mail Server

而要將JAMES使用Windows Services的方式執行:
\bin>wrapper -i ..\conf\wrapper.conf
移除windows service:
\bin>wrapper -r ..\conf\wrapper.conf

Apache FTP Server

要將FTP Server以服務方式執行:
\bin\
service install
移除windows service:
\bin\service remove

2009年7月20日 星期一

Eclipse + tomcat 遠端Debug

[Tomcat端]
修改catalina.bat
set JAVA_OPTS=%JAVA_OPTS% -Xmx256m 這行後面加上
-Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888

[Eclipse端]
自己google一下吧

2009年6月21日 星期日

Apache Directory Server

Apache DS是一個通過LDAP v3相容性認證open source目錄伺服器。
Apache DS是100%的JAVA應用程式,可內嵌於Java應用程式或是以獨立伺服器方式運作。

官方網站: http://directory.apache.org/
除了Directory Server外, 還有Apache Directory Studio是Eclipse-based工具,可用來操作Directory Server的內容。

相關參考文章:

ApacheDS and Tomcat For J2EE Authentication

Articals

2009年5月21日 星期四

用Java壓縮/解壓縮Zip檔案

相當實用的文章:
[JAVA] zip壓縮 與 解壓縮

jBPM 3.2.6安裝後問題

jBPM 3.2.6安裝後登入web-console後發現,
所有資料表內的資料都被清空了,
要解決這個問題要修改 hibernate.cfg.xml 內的
<property name="hibernate.hbm2ddl.auto">create</property>
改為
<property name="hibernate.hbm2ddl.auto">update</property>

2009年5月19日 星期二

jBPM 3.2.6安裝於Tomcat 6 由eclipse啟動

1. 依
http://www.javaworld.com.tw/jute/post/view?bid=43&id=255869
安裝,並記得將build path 的output目錄設到/WEB-INF/classes並將hibernate.cfg.xml放到其中。

2. 接著參考
http://linliangyi2007.javaeye.com/blog/176339
step5的sql指令將user資料插入mysql
或使用下列sql指令:

INSERT INTO JBPM_ID_GROUP VALUES(2,'G','admin','security-role',NULL);
INSERT INTO JBPM_ID_GROUP VALUES(3,'G','user','security-role',NULL);
INSERT INTO JBPM_ID_GROUP VALUES(5,'G','manager','security-role',NULL);

INSERT INTO JBPM_ID_USER VALUES(1,'U','user','user@sample.domain','user');
INSERT INTO JBPM_ID_USER VALUES(2,'U','manager','manager@sample.domain','manager');
INSERT INTO JBPM_ID_USER VALUES(3,'U','admin','admin@sample.domain','admin');

INSERT INTO JBPM_ID_MEMBERSHIP VALUES(5,'M',NULL,NULL,1,3);
INSERT INTO JBPM_ID_MEMBERSHIP VALUES(6,'M',NULL,NULL,2,3);
INSERT INTO JBPM_ID_MEMBERSHIP VALUES(7,'M',NULL,NULL,3,3);
INSERT INTO JBPM_ID_MEMBERSHIP VALUES(8,'M',NULL,NULL,3,2);
INSERT INTO JBPM_ID_MEMBERSHIP VALUES(9,'M',NULL,NULL,2,2);
INSERT INTO JBPM_ID_MEMBERSHIP VALUES(10,'M',NULL,NULL,2,5);


3. 另外若在jbpm_id_group裡面若有另外新增security-role,便須修改web.xml,如下範例:

....略....
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>user</role-name>
</security-role>
<security-role>
<role-name>participant</role-name>
</security-role>
....略....
<security-constraint>
<web-resource-collection>
<web-resource-name>Secure Area</web-resource-name>
<url-pattern>/app/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
<role-name>admin</role-name>
<role-name>participant</role-name>
</auth-constraint>
</security-constraint>
....略....

上列的role-name對應到jbpm_id_group的name_

4.
ok ~

2009年3月4日 星期三

[XX隱藏關卡XX] BIRT中使用外部.js檔案

當在使用BIRT開發多個報表時,常會有多張報表需要使用相同函數的時候,偏偏在BIRT中無法使用外部.js當作函數庫使用。
但在BIRT 2.3的Release Note指出, 該版確實是提供了該功能,但好笑的是並沒有說如何做。

原來GUI Designer並沒有提供介面,必須以XML Source內修改ptdesign,加入:

<list-property name="includeScripts">
<property>system.js</property>
</list-property>

2009年2月18日 星期三

JAVA 寫UTF-8文字檔關於BOM議題...

如果各位使用JAVA IO的OutputStreamWriter指定編碼為UTF-8寫檔時,單純寫ASCII英文字和數字、符號不包含中文字寫出的檔案,使用windows的記事本另存新檔看其編碼為「ANSI」但若檔案內包含中文字(或任何非ASCII文字)會發現記事本另存新檔看其編碼為「UTF-8」。
明明不是我們指定UTF-8了嗎?一切都是BOM的問題,這又是另一段故事了,欲知詳情請上Google....

這裡單純說明如何在上列兩任一情況下如何一致讓記事本另存新檔看其編碼為「UTF-8」,下列兩隻CLASS供各位參考:

import java.io.IOException;
import java.io.PushbackInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import sun.nio.cs.StreamDecoder;

public class UnicodeInputStreamReader extends InputStreamReader {

private static final int BOM_SIZE = 4;
private final StreamDecoder decoder;
private PushbackInputStream pushBack;
private String encode;
private String defaultEnc;

public UnicodeInputStreamReader(InputStream input, String defaultEnc) throws UnsupportedEncodingException {

super(input);

try {
this.defaultEnc = defaultEnc;
this.pushBack = new PushbackInputStream(input, BOM_SIZE);
init();
} catch (Exception e) {
e.printStackTrace();
}

this.decoder = StreamDecoder.forInputStreamReader(this.pushBack, this, this.encode);
}

private void init() throws IOException {

byte[] bom = new byte[BOM_SIZE];
int n, unread;

// 初始讀取一次
n = this.pushBack.read(bom, 0, bom.length);

// 比對表頭
if ( (bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF) ) {
this.encode = "UTF-32BE";
unread = n - 4;
} else if ( (bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00) ) {
this.encode = "UTF-32LE";
unread = n - 4;
} else if ( (bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF) ) {
this.encode = "UTF-8";
unread = n - 3;
} else if ( (bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF) ) {
this.encode = "UTF-16BE";
unread = n - 2;
} else if ( (bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) ) {
this.encode = "UTF-16LE";
unread = n - 2;
} else {
// 如果沒有找到任何表頭, 則退回長度等於原先總長
this.encode = this.defaultEnc;
unread = n;
}

// System.out.println("has BOM=" + ((unread == n) ? false : true) + ", encode=" + encode + ", read=" + n + ", unread=" + unread);
// 計算應該退回多少byte
if ( unread > 0 ) {
this.pushBack.unread(bom, (n - unread), unread);
}

}

public String getEncoding() {
return this.encode;
}

public int read() throws IOException {
return this.decoder.read();
}

public int read(char cbuf[], int offset, int length) throws IOException {
return this.decoder.read(cbuf, offset, length);
}

public boolean ready() throws IOException {
return this.decoder.ready();
}

public void close() throws IOException {
this.decoder.close();
}
}




import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

public class UTF8OutputStreamWriter extends OutputStreamWriter{
public UTF8OutputStreamWriter(OutputStream pos) throws IOException{
super(pos,"UTF-8");

// write UTF8 BOM mark if file is empty
final byte[] bom = new byte[] { (byte)0xEF, (byte)0xBB, (byte)0xBF };
pos.write(bom);

}

public UTF8OutputStreamWriter(OutputStream pos,String pencoding) throws IOException{
this(pos);
}
}