練功房推薦書單

  • Google!Android 3手機應用程式設計入門(第四版)
  • 賈伯斯傳(軟皮精裝版)
  • 猛虎出閘制霸版:最新OCP Java SE 6 Programmer專業認證(附原始程式碼及範例檔)
  • SCWCD 5 猛虎出閘:Java Web 應用程式專業認證
Messages posted by: andowson
Forum Index » Profile for andowson » Messages posted by andowson
Message
發送HTML格式的郵件
預先安裝函式庫:Apache Commons IO
假設樣板檔名為message.html,放在網頁應用程式的根目錄下,發送給somebody@andowson.com。
程式碼:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.io.File" %>
<%@ page import="java.text.MessageFormat" %>
<%@ page import="org.apache.commons.io.FileUtils" %>
<%@ page import="org.apache.commons.mail.DefaultAuthenticator" %>
<%@ page import="org.apache.commons.mail.EmailException" %>
<%@ page import="org.apache.commons.mail.HtmlEmail" %>
<%    
    String subject="測試使用 Gmail SMTP SSL發信";
    String filename = application.getRealPath("/") + "message.html";
    String template = FileUtils.readFileToString(new File(filename), "UTF-8");
    String message = "";

    HtmlEmail email = new HtmlEmail(); 
	String authuser = "username@gmail.com"; 
	String authpwd = "the_password";
	email.setHostName("smtp.gmail.com");
	email.setSmtpPort(465); 
	email.setAuthenticator(new DefaultAuthenticator(authuser, authpwd));
	email.setDebug(true);
	email.setSSL(true);
	email.setSslSmtpPort("465");
	email.setCharset("UTF-8");
	email.setSubject(subject);
	try {
	    email.setFrom("username@gmail.com", "網站客服中心");
	    message = MessageFormat.format(template, new Object[] { "somebody", "http://www.andowson.com/" });
	    email.setHtmlMsg(message); 
	    email.addTo("somebody@andowson.com", "親愛的會員");
	    email.send();
	    out.println("郵件發送成功"); 
	} catch (EmailException e) {
	    e.printStackTrace();
	}	
%>

message.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>e-paper</title>
</head>
<body>
親愛的{0}您好,請點選這個<a href="{1}">連結</a>至活動網頁。<br/>
這是一封測試信,收到請自行刪除
</body>
</html>

今天又找到幾個類似功能的網站,有興趣的人可以參考,將網址列中的網域名稱換成您有興趣的即可:
http://7zoom.com/www.andowson.com
http://websiteindepth.com/www.andowson.com

Web Site Report型:
http://site.egyfox.com/andowson.com
http://serversiders.com/andowson.com
http://www.siteluck.com/en/andowson.com
http://www.websitefigures.com/site/andowson.com
http://www.markosweb.com/www/andowson.com/

使用技術分析型:
http://builtwith.com/andowson.com
今天發現這個網站,只要輸入人名就可以找出曾經在網路上留下的紀錄,以下是我的紀錄:

http://pipl.com/directory/name/Chang/Andowson
似乎這個問題只有發生在Mac版的Firefox 3上,修改方式很簡單,請參考下面的說明:

將post_form.htm中的這段程式碼去掉包圍<#include "post_xxx_tab.htm" />前後的<div>及</div>即可。
修改前:
<!-- Post Options -->
<div id="postOptions" class="postTabContents">
    <div>
        <#include "post_options_tab.htm"/>
    </div>
</div>
 
<!-- Poll tab -->
<#if allowPoll>
    <div id="postPoll" class="postTabContents" style="display: none;">
        <div>
            <#include "post_poll_tab.htm"/>
        </div>
    </div>
</#if>
 
<!-- Attachments tab -->
<#if attachmentsEnabled || attachments?exists>
    <div id="postAttachments" class="postTabContents" style="display: none; ">
        <div>
            <#include "post_attachments_tab.htm"/>
        </div>
    </div>
</#if>


修改後:
						<!-- Post Options -->
						<div id="postOptions" class="postTabContents">
							<#include "post_options_tab.htm"/>
						</div>

						<!-- Poll tab -->
						<#if allowPoll>
							<div id="postPoll" class="postTabContents" style="display: none;">
								<#include "post_poll_tab.htm"/>
							</div>
						</#if>

						<!-- Attachments tab -->
						<#if attachmentsEnabled || attachments?exists>
							<div id="postAttachments" class="postTabContents" style="display: none;">
								<#include "post_attachments_tab.htm"/>
							</div>
						</#if>


請幫忙測試如此修改之後在 Mac 及 Windows 7 上面的Firefox 3 是否都可以正常運作,謝謝。
參考資料:
http://jforum.net/posts/list/4729.page#19138
ericboy您好:
我在我的Notebook上測試可以正常顯示,畫面如附件。我的環境是Windows Vista + Firefox 3.6.6,解析度是1280 * 800,麻煩您提供一下您的環境、解析度設定及錯誤畫面。
要避免發生java.lang.IllegalStateException: getOutputStream() has already been called for this response,可以在doDownload()後面加上下面兩行
out.clear();
out = pageContext.pushBody();
修改後的原始程式碼如下:
download.jsp
<%@ page import="java.io.*"%>
<%!
    private static final int BUFSIZE = 2048;
    /**
     *  Sends a file to the ServletResponse output stream.  Typically
     *  you want the browser to receive a different name than the
     *  name the file has been saved in your local database, since
     *  your local names need to be unique.
     *
     *  @param request The request
     *  @param response The response
     *  @param filename The name of the file you want to download.
     *  @param original_filename The name the browser should receive.
     */
    private void doDownload( HttpServletRequest request, HttpServletResponse response,
                             String filename, String original_filename )
        throws IOException
    {
        File                f        = new File(filename);
        int                 length   = 0;
        ServletOutputStream op       = response.getOutputStream();
        ServletContext      context  = getServletConfig().getServletContext();
        String              mimetype = context.getMimeType( filename );

        //
        //  Set the response and go!
        //
        //
        response.setContentType( (mimetype != null) ? mimetype : "application/octet-stream" );
        response.setContentLength( (int)f.length() );
        response.setHeader( "Content-Disposition", "attachment; filename=\"" + original_filename + "\"" );

        //
        //  Stream to the requester.
        //
        byte[] bbuf = new byte[BUFSIZE];
        DataInputStream in = new DataInputStream(new FileInputStream(f));

        while ((in != null) && ((length = in.read(bbuf)) != -1))
        {
            op.write(bbuf,0,length);
        }

        in.close();
        op.flush();
        op.close();
    }
%>
<%
    String original_filename = request.getParameter("file");
    String target_filename = "";
    
    // Chrome will auto escape the URL characters
    String userAgent = request.getHeader("user-agent");
    System.out.println(userAgent);
    String charset = "MS950";
    if (userAgent.indexOf("Chrome") != -1) {
    	charset = "UTF-8";
    }

    // Security Isuue: User can type file=../WEB-INF/web.xml
    //String filename = application.getRealPath(original_filename);
    boolean error = true;
    if (original_filename != null && !"".equals(original_filename.trim()) && !original_filename.startsWith("../")) {
    	target_filename = new String(original_filename.getBytes("ISO-8859-1"), charset);
    	String filename = application.getRealPath("/")+"WEB-INF/export/" + target_filename;
    	File file = new File(filename);	
    	if (file.exists()) {
    	    doDownload(request, response, filename, original_filename);
    	    // aviod java.lang.IllegalStateException: getOutputStream() has already been called for this response
    	    out.clear();
            out = pageContext.pushBody();
    	    // delete the file after download
    	    //boolean deleted = file.delete();
    	    //System.out.println("File " + target_filename + " deleted: " + deleted);
    	    error = false;
    	} 
    } 
    if (error) {
    	response.setContentType("text/html; charset=UTF-8");
    	out.println("File not found: " + target_filename);
    }
%>
本站今天正式升級至JForum 2.2.0版。如果有發現任何問題請回報給我。
經過一段時間的程式修改及測試,JForum 2.2.0已經可以開放來讓大家下載來安裝(及測試)了

目前測試過的環境如下:
Database Server:
HSQLDB 1.8.1.2
MySQL 5.1.48
PostgreSQL 8.4.4-1
Oracle 10g Express
SQL Server 2008 Express

AP Server:
Tomcat 6.0.26
Jetty 6.1.24

JDK: 6.0 Update 20

OS: Windows Vista/ Linux - CentOS 5.5
如有發現問題還請大家回報一下。

下載網址:
Download jforum-2.2.0.war
http://code.google.com/p/jforum2/downloads/list
自動安裝AWStats的程式awstats.sh內容如下:
#!/bin/bash
# Name: awstats.sh
# Author: Andowson Chang (andowson [at] gmail [dot] com)
# Version: 1.2
# Last Modified: 2010-05-17

#
# check the latest stable version of AWStats 6.x
#
wget http://awstats.sourceforge.net/ -q -t 1 -T 5 -O /tmp/awstats.html
if [ -s /tmp/awstats.html ]; then
   AWSTATS_URL=`grep rpm /tmp/awstats.html | cut -d"\"" -f2`
   AWSTATS_FILENAME=`echo ${AWSTATS_URL}|cut -d "/" -f5`
   AWSTATS_VERSION=`echo ${AWSTATS_FILENAME} | cut -d "-" -f2`
fi
rm -rf /tmp/awstats.html

if [ ! -r ${AWSTATS_FILENAME} ]; then
   wget http://nchc.dl.sourceforge.net/sourceforge/awstats/${AWSTATS_FILENAME}
fi
if [ ! -r ${AWSTATS_FILENAME} ]; then
   echo "Install failed: ${AWSTATS_FILENAME} not found!"
   exit 1
fi 

echo "Install AWStats ${AWSTATS_VERSION}"
yum -y install perl-libwww-perl.noarch
rpm -Uvh ${AWSTATS_FILENAME}
mkdir -p /etc/awstats
cp -rf /usr/etc/awstats/awstats.model.conf /etc/awstats/.

#
# install GeoIP plugin
#
if [ ! -d /usr/local/share/GeoIP/ ]; then
   mkdir /usr/local/share/GeoIP/
fi
if [ ! -r /usr/local/share/GeoIP/GeoIP.dat ]; then
   wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
   gunzip GeoIP.dat.gz
   mv GeoIP.dat /usr/local/share/GeoIP/GeoIP.dat
fi
if [ ! -r /usr/local/share/GeoIP/GeoLiteCity.dat ]; then
   wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
   gunzip GeoLiteCity.dat.gz
   mv GeoLiteCity.dat /usr/local/share/GeoIP/GeoLiteCity.dat
fi
yum -y install zlib-devel
if [ ! -r GeoIP.tar.gz ]; then
   wget http://geolite.maxmind.com/download/geoip/api/c/GeoIP.tar.gz
fi
tar zxvf GeoIP.tar.gz
cd GeoIP-*
./configure
make
make check
make install
echo '/usr/local/lib' >> /etc/ld.so.conf
/sbin/ldconfig /etc/ld.so.conf
cd ..
if [ ! -r Geo-IP-1.38.tar.gz ]; then
   wget http://geolite.maxmind.com/download/geoip/api/perl/Geo-IP-1.38.tar.gz
fi
tar zxvf Geo-IP-1.38.tar.gz
cd Geo-IP-*
perl Makefile.PL LIBS='-L/usr/local/lib' INC='-I/usr/local/include' 
make
make test
make install
cd ..

#
# install HostInfo plugin
#
if [ ! -r Net-XWhois-0.90.tar.gz ]; then
   wget http://cpan.nctu.edu.tw/authors/id/V/VI/VIPUL/Net-XWhois-0.90.tar.gz
fi
tar -xzvf Net-XWhois-0.90.tar.gz
cd Net-XWhois-0.90
perl Makefile.PL
make
make install 

#
# generate awstats.conf
#
echo '#
# Directives to allow use of AWStats as a CGI
#
Alias /awstatsclasses "/usr/local/awstats/wwwroot/classes/"
Alias /awstatscss "/usr/local/awstats/wwwroot/css/"
Alias /awstatsicons "/usr/local/awstats/wwwroot/icon/"
Alias /awstatsjs "/usr/local/awstats/wwwroot/js/"
ScriptAlias /awstats/ "/usr/local/awstats/wwwroot/cgi-bin/"

#
# This is to permit URL access to scripts/files in AWStats directory.
#
<Directory "/usr/local/awstats/wwwroot">
    Options None
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>' > /etc/httpd/conf.d/awstats.conf

#
# add cronjob
#
echo '
# update GeoIP.dat ('`date +%Y.%m.%d`')
00 2 5 * * root /root/admin/updateGeoIP_dat.sh >/dev/null 2>&1

# update AWstats record ('`date +%Y.%m.%d`')
01 * * * * root /usr/local/awstats/tools/awstats_updateall.pl now >/dev/null' >> /etc/crontab
這是一個比較單純的作法,用兩部機器當作DB Server,後面去掛載一個NAS的分享目錄,然後把資料庫的檔案放到NAS去。由Heartbeat來自動切換Active和Standby角色。

參考資料
http://momjian.us/main/writings/pgsql/replication.pdf
paddy您好:
感謝您的分享~給您加一個星~
準備工作:
1.先在Windows主機中建立一個使用者帳號、並設定密碼,然後建立一個資料夾,設定為共用,在使用權限中設定該使用者可以完全控制。
假設Windows主機IP=10.66.19.80
使用者帳號=postgres
密碼=postgres
共用資料夾名稱=pgdata
2.登入Linux

環境:
Windows主機IP=10.66.19.80
使用者帳號=postgres
密碼=postgres
共用資料夾名稱=pgdata

查詢/etc/passwd和/etc/group得知在Linux主機中postgres使用者的uid=26,gid=26
欲掛載之目錄為/mnt/pgdata

步驟:
1.在/etc/fstab中加入下列設定,不需要重開機
//10.66.19.80/pgdata    /mnt/pgdata             cifs    user,uid=26,gid=26,dir_mode=0700,file_mode=0700,username=postgres,password=postgres 0 0

使用cifs做為檔案系統型態,另外credentials=filename的設定,我沒有試成功,所以還是採用直接輸入username和password的方式。

2.建立掛載目錄
mkdir -p /mnt/pgdata

3.掛載目錄
mount /mnt/pgdata

4.檢查
[root@eipdb1 ~]# ll /mnt
總計 0
drwx------ 1 postgres postgres 0  6月 25 09:42 pgdata

這樣子就完成了

如果要卸載目錄,可以輸入下面的指令
umount /mnt/pgdata


參考資料:
http://linux.die.net/man/8/mount.cifs
paddy您好:
1.請試試看先訂閱一下該版面,再發表文章,然後檢查有沒有收到信。
2.有關中文化的部分請參考,下面文章:
http://www.andowson.com/posts/list/253.page
今天發現Linode.com發布了七周年慶的消息,並且來個普天同慶,所有既有客戶自動加RAM不加價,上升一級,只要做一次重開機即可。
升級後的硬體大致如下:
Linode 512 Xen VPS
CPU: Intel(R) Xeon(R) CPU L5520 @ 2.27GHz * 4
RAM: 512MB
HD: 16GB
Transfer: 200GB
價錢還是19.95美金

參考資料:
http://blog.linode.com/2010/06/16/linode-turns-7-big-ram-increase/
Linode.com: http://www.linode.com/?r=60f84faceb69fc66af4c0be8c8ffe68754b2ac58
在完成Tomcat Cluster的安裝後(請參考http://www.andowson.com/posts/list/315.page這篇),我們可以透過JConsole來監控Tomcat運行的狀態,只需要修改Tomcat啟動時的設定即可。

1.修改setenv.sh,加上下列設定
CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=${JMX_PORT} -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

修改後的完整內容如下:
JAVA_HOME="/usr/java/latest"
JAVA_OPTS="-server -XX:NewSize=503m -XX:MaxNewSize=503m -XX:SurvivorRatio=8 -XX:MaxPermSize=128m -Xss768k -Xms2013m -Xmx2013m -Djava.net.preferIPv4Stack=true -Djava.awt.headless=true"
CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=${JMX_PORT} -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

2.修改/etc/init.d/tomcat
(1)在原先的WORKER_PORT=( 8105 8205 )下面,加上JMX_PORTS=( 9105 9205 )
(2)在start()中,將原先的
su -l $TOMCAT_USER -c "export CATALINA_BASE=$CATALINA_BASE; $CATALINA_HOME/bin/startup.sh"

改為
su -l $TOMCAT_USER -c "export CATALINA_BASE=$CATALINA_BASE; export JMX_PORT=${JMX_PORTS[i]}; $CATALINA_HOME/bin/startup.sh"

修改後的完整內容如下:
#!/bin/sh
#
# Startup script for Tomcat, the Apache Servlet Engine
#
# chkconfig: - 84 16
# description: Tomcat Servlet Engine
# processname: tomcat
# pidfile: /var/run/worker1.pid /var/run/worker2.pid

# Source function library.
. /etc/rc.d/init.d/functions

# User under which tomcat will run
TOMCAT_USER=tomcat

RETVAL=0

CATALINA_HOME=/var/tomcat6
WORKER_ROOT=/var/robust
WORKER_LIST=( worker1 worker2 )
WORKER_PORT=( 8105 8205 )
JMX_PORTS=( 9105 9205 )
# start, debug, stop, and status functions
start() {
    i=$1
    SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
    if [ $SHUTDOWN_PORT -ne 0 ]; then
        echo "Tomcat ${WORKER_LIST[i]} already started"
    else
        echo "Starting tomcat ${WORKER_LIST[i]}..."
        CATALINA_BASE="$WORKER_ROOT/${WORKER_LIST[i]}"
        chown -R $TOMCAT_USER:$TOMCAT_USER $CATALINA_HOME
        chown -R $TOMCAT_USER:$TOMCAT_USER $WORKER_ROOT
        su -l $TOMCAT_USER -c "export CATALINA_BASE=$CATALINA_BASE; export JMX_PORT=${JMX_PORTS[i]}; $CATALINA_HOME/bin/startup.sh"
        SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
        while [ $SHUTDOWN_PORT -eq 0 ]; do
            sleep 1
            SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
        done
        echo "Tomcat ${WORKER_LIST[i]} started in normal mode"
        RETVAL=$?
        [ $RETVAL = 0 ] && touch /var/lock/subsys/${WORKER_LIST[i]} /var/run/${WORKER_LIST[i]}.pid
    fi
}

debug() {
    i=$1
    SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
    if [ $SHUTDOWN_PORT -ne 0 ]; then
        echo "Tomcat ${WORKER_LIST[i]} already started"
    else
        echo "Starting tomcat ${WORKER_LIST[i]} in debug mode..."
        CATALINA_BASE="$WORKER_ROOT/${WORKER_LIST[i]}"
        rm -rf $CATALINA_BASE/work/*

        chown -R $TOMCAT_USER:$TOMCAT_USER $CATALINA_HOME
        chown -R $TOMCAT_USER:$TOMCAT_USER $WORKER_ROOT
        su -l $TOMCAT_USER -c "export CATALINA_BASE=$CATALINA_BASE; $CATALINA_HOME/bin/catalina.sh jpda start"
        SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
        while [ $SHUTDOWN_PORT -eq 0 ]; do
            sleep 1
            SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
        done
        echo "Tomcat ${WORKER_LIST[i]} started in debug mode"
        RETVAL=$?
        [ $RETVAL = 0 ] && touch /var/lock/subsys/${WORKER_LIST[i]} /var/run/${WORKER_LIST[i]}.pid
    fi
}

stop() {
    i=$1
    SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
    if [ $SHUTDOWN_PORT -eq 0 ]; then
        echo "Tomcat ${WORKER_LIST[i]} already stopped"
    else
        echo "Stopping tomcat ${WORKER_LIST[i]} ..."
        CATALINA_BASE="$WORKER_ROOT/${WORKER_LIST[i]}"
        su -l $TOMCAT_USER -c "export CATALINA_BASE=$CATALINA_BASE; $CATALINA_HOME/bin/shutdown.sh"
        SHUTDOWN_PORT=`ps -ef|grep ${WORKER_LIST[i]}|grep -v grep|wc -l`
        while [ $SHUTDOWN_PORT -ne 0 ]; do
            sleep 1
            SHUTDOWN_PORT=`ps -ef|grep ${WORKER_LIST[i]}|grep -v grep|wc -l`
        done
        echo "Tomcat ${WORKER_LIST[i]} stopped"
        RETVAL=$?
        [ $RETVAL=0 ] && rm -f /var/lock/subsys/${WORKER_LIST[i]} /var/run/${WORKER_LIST[i]}.pid
    fi
}

status() {
  for (( i = 0 ; i < ${#WORKER_LIST[@]} ; i++ ))
  do
    SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
    if [ $SHUTDOWN_PORT -eq 0 ]; then
        echo "Tomcat ${WORKER_LIST[i]} stopped"
    else
        MODE="normal"
        JPDA_PORT=`netstat -vatn|grep LISTEN|grep 8000|wc -l`
        if [ $JPDA_PORT -ne 0 ]; then
            MODE="debug"
        fi
        echo "Tomcat ${WORKER_LIST[i]} running in $MODE mode"
    fi
  done
}

case "$1" in
  start)
        start 0
        start 1
        ;;
  debug)
        debug 0
        debug 1
        ;;
  stop)
        stop 0
        stop 1
        ;;
  restart)
        stop 0
        start 0
        stop 1
        start 1
        ;;
  redebug)
        stop 0
        debug 0
        stop 1
        debug 1
        ;;
  status)
  	status
	;;
  *)
	echo "Usage: $0 {start|debug|stop|restart|redebug|status}"
	exit 1
esac

exit $RETVAL


接下來就可以用jconsole來連了,
在Windows主機上安裝JDK 5以上版本,然後設定好JAVA_HOME及Path環境變數,接著開一個命令列視窗,然後輸入jconsole這個指令來執行
在Remote Process那邊輸入<Host IP>:<JMX Port>,例如
10.66.19.16:9205
再點選Connect按鈕,如果一切正常就可以看到畫面了
image
障礙排除:
如果連線失敗請參考注意事項:
*注意事項:請用"hostname -i"檢查一下是否回傳主機的真實IP,而非127.0.0.1,如果回傳127.0.0.1,則需修改/etc/hosts,將hostname另外設定IP,參考範例如下:
127.0.0.1         localhost.localdomain      localhost
10.66.19.16       www

另外執行"/sbin/iptables --list"檢查是否有防火牆設定。

參考資料
http://tomcat.apache.org/tomcat-6.0-doc/cluster-howto.html
http://java.sun.com/javase/6/docs/technotes/guides/management/faq.html#linux1
 
Forum Index » Profile for andowson » Messages posted by andowson
Go to: