2005年05月14日

jsp文件是UTF-8编码。

然后在使用ant进行jsp预编译打包时候出现下面的错误:

    [javac] E:\lizongbo\\WEB-INF\src\org\apache\jsp\lizongbo_jsp.java:977:

warning: unmappable character for encoding GBK

查资料之后,得到解决方法:

对jasper2(org.apache.jasper.JspC)设置

javaEncoding="UTF-8"

对javac设置 encoding="UTF-8"

,然后再次ant就可以成功预编译了。

2005年05月13日

在jstl中也可以像php那样随时声明变量而且不操心变量的类型。
下面的代码只需要修改数据库连接的参数,和需要显示的表名即可。


<%@page contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x" %>
<html>
<head>
<title>lizongbo 的 jstl 例子</title>
</head>
<body bgcolor="#ffffff">
<c:set var="db_driver" value="org.gjt.mm.mysql.Driver"/>
<c:set var="db_url" value="jdbc:mysql://localhost:3306/lizongbo?useUnicode=true&characterEncoding=UTF-8"/>
<c:set var="db_user" value="lizongbo"/>
<c:set var="db_password" value="lizongbo"/>
<c:set var="table_name" value="tbl_login_log"/>
<c:set var="crtpageno" value="${param.crtpageno > 0? param.crtpageno:1}"/>
<c:set var="countperpage" value="${param.countperpage > 0? param.countperpage:5}"/>
<c:set var="limitb" value="${(crtpageno-1)*countperpage}"/>
<sql:setDataSource driver="${db_driver}" user="${db_user}" password="${db_password}" url="${db_url}" var="mydb" scope="application"/>
<sql:query var="myrs" sql="select count( * ) as countnum from ${table_name}" dataSource="${mydb}" scope="request"></sql:query>
<c:out value="一共有${myrs.rows[0].countnum}条记录<br/>" escapeXml="false"></c:out>
<c:set var="allpageno" value="${myrs.rows[0].countnum % countperpage ==0 ? (myrs.rows[0].countnum) / countperpage : (myrs.rows[0].countnum) / countperpage +1}" scope="request"/>
<%String alpn =String.valueOf( java.lang.Math.round(Double.parseDouble(String.valueOf(request.getAttribute("allpageno")))));%>
<c:set var="allpageno" value="<%=alpn%>"/>
<c:set var="crtpageno" value="${crtpageno > allpageno ? allpageno : crtpageno}"/>
<c:set var="prepageno" value="${crtpageno>1 ? crtpageno-1 : crtpageno}"/>
<c:set var="nrepageno" value="${crtpageno >= allpageno? allpageno : crtpageno+1}"/>
<a href="<%=request.getRequestURI()%>?crtpageno=1">第一页</a>
<a href="<%=request.getRequestURI()%>?crtpageno=<c:out value="${prepageno}" />">上一页</a>
<a href="<%=request.getRequestURI()%>?crtpageno=<c:out value="${nrepageno}" />">下一页</a>
<a href="<%=request.getRequestURI()%>?crtpageno=<c:out value="${allpageno}" />">最后一页</a>
<sql:query var="myrs" sql="select * from ${table_name} LIMIT ${limitb}, ${countperpage} " dataSource="${mydb}" scope="request"></sql:query>
<table border="1">
<c:forEach var="row" items="${myrs.rows}" varStatus="status">
<c:if test="${status.first}">
<tr>
<c:forEach var="colname" items="${row}">
<td>
<c:out value="${colname.key}" escapeXml="true"/>
</td>
</c:forEach>
</tr>
</c:if>
<tr>
<c:forEach var="col" items="${row}">
<td>
<c:out value="${col.value}" escapeXml="true"/>
</td>
</c:forEach>
</tr>
<c:set var="crtrsnum" value="${status.count}"/>
</c:forEach>
</table>
当前是第:<c:out value="${limitb+1}"/>到第<c:out value="${limitb+crtrsnum}"/>条记录
<br/>
</body>
</html>


2005年05月09日

<%@page contentType="text/html; charset=UTF-8"%>
<%@page import="java.util.*"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x"%>
<html>
<head>
<title>language choose</title>
</head>
<body bgcolor="#ffffff">

copyright @ lizongbo @ donews.net


<c:if test="${param['locale'] != null}">
  <fmt:setLocale value="${param['locale']}" scope="session"/>
  <fmt:setTimeZone value="${param['locale']}" scope="session"/>
</c:if>
<c:if test="${param['locale'] == null}">
  <fmt:setLocale value="${header['locale']}" scope="session"/>
  <fmt:setTimeZone value="${header['locale']}" scope="session"/>
</c:if>
<%
  Locale crtl = Locale.getDefault();
  Object cobj = session.getAttribute("javax.servlet.jsp.jstl.fmt.locale.session");
  if (cobj != null && cobj instanceof Locale) {
    crtl = (Locale) cobj;
  }
  Locale[] la = java.text.NumberFormat.getAvailableLocales();
%>
<form method="POST" action="">
  language choose:
  <br />
<select name="locale">
<%for (int i = 0; i < la.length; i++) {%>
  <option value="<%=la[i]%>" <%if (la[i].equals(crtl)) {
                                 out.print("selected=\"selected\"");
                               }%>><%= la[i].getDisplayName(crtl)%></option>
<%
  }
%>
</select>
<br />
<input type="submit" value="change"/>
</form>
</body>
</html>

2005年04月29日
在对一些字符串格式的时间进行比较的时候,
我看到的做法绝大部分都是先把字符串转换成Date类型,然后再进行比较。
 
 
而实际情况中,
如果是确定格式的,并且长度固定一样长的字符串。
完全可以直接借助String 的compareTo就进行比较:
例如:
String aa="2004/03/04";//("2004-02-03 11:22:33")
String bb="2004/03/05";//("2005-02-06 12:21:33")
if (aa.compareTo(aa)>0) {
System.out.println("aa da ");
}else{
System.out.println("bb da");
}
这样完全可以省略掉对字符串进行时间转换的开销。
我喜欢这样的做法:)偷懒也是一种乐趣。
 
 

例如:
String aa="2004/03/04";//("2004-02-03 11:22:33")
String bb="2004/03/05";//("2005-02-06 12:21:33")
if (aa.compareTo(aa)>0) {
System.out.println("aa da ");
}else{
System.out.println("bb da");
}
这样完全可以省略掉对字符串进行时间转换的开销。
我喜欢这样的做法:)偷懒也是一种乐趣。
 
 
2005年04月24日

例如想只把log4j的debug信息输出到debug.log.error信息输出到error.log,info信息输出到info.log

log4j提供了下面一种方式来实现.

必须使用xml方式进行配置才能够支持filter过滤元素。

配置文件来自:

http://www.mail-archive.com/log4j-user@jakarta.apache.org/msg09720.html

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j=’http://jakarta.apache.org/log4j/’>

        <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
                <layout class="org.apache.log4j.PatternLayout">
                     <param name="ConversionPattern" value="%c %d{ISO8601}
– %p — %m%n"/>
                </layout>
        </appender>

        <appender name="DEBUG" class="org.apache.log4j.RollingFileAppender">
      <param name="File" value="C:\\logs\\app-debug.log"/>
      <param name="Append" value="true"/>
      <param name="MaxFileSize" value="500KB"/>
      <param name="MaxBackupIndex" value="2"/>
                <layout class="org.apache.log4j.PatternLayout">
                     <param name="ConversionPattern" value="%c %d{ISO8601}
– %p — %m%n"/>
                </layout>
                <filter class="org.apache.log4j.varia.LevelRangeFilter">
                        <param name="LevelMin" value="DEBUG" />
                        <param name="LevelMax" value="DEBUG" />
                </filter>
        </appender>

        <appender name="INFO" class="org.apache.log4j.RollingFileAppender">
      <param name="File" value="C:\\logs\\app-info.log"/>
      <param name="Append" value="true"/>
      <param name="MaxFileSize" value="500KB"/>
      <param name="MaxBackupIndex" value="2"/>
                <layout class="org.apache.log4j.PatternLayout">
                     <param name="ConversionPattern" value="%c %d{ISO8601}
– %p — %m%n"/>
                </layout>
                <filter class="org.apache.log4j.varia.LevelRangeFilter">
                        <param name="LevelMin" value="INFO" />
                        <param name="LevelMax" value="INFO" />
                </filter>
   </appender>

        <appender name="WARN" class="org.apache.log4j.RollingFileAppender">
      <param name="File" value="C:\\logs\\app-warn.log"/>
      <param name="Append" value="true"/>
      <param name="MaxFileSize" value="500KB"/>
      <param name="MaxBackupIndex" value="2"/>
                <layout class="org.apache.log4j.PatternLayout">
                     <param name="ConversionPattern" value="%c %d{ISO8601}
– %p — %m%n"/>
                </layout>
                <filter class="org.apache.log4j.varia.LevelRangeFilter">
                        <param name="LevelMin" value="WARN" />
                        <param name="LevelMax" value="WARN" />
                </filter>
   </appender>

        <appender name="ERROR" class="org.apache.log4j.RollingFileAppender">
      <param name="File" value="C:\\logs\\app-error.log"/>
      <param name="Append" value="true"/>
      <param name="MaxFileSize" value="500KB"/>
      <param name="MaxBackupIndex" value="2"/>
                <layout class="org.apache.log4j.PatternLayout">
                     <param name="ConversionPattern" value="%c %d{ISO8601}
– %p — %m%n"/>
                </layout>
                <filter class="org.apache.log4j.varia.LevelRangeFilter">
                        <param name="LevelMin" value="ERROR" />
                        <param name="LevelMax" value="ERROR" />
                </filter>
   </appender>

        <root>
                <priority value="debug"/>
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="DEBUG"/>
        <appender-ref ref="INFO"/>
        <appender-ref ref="WARN"/>
        <appender-ref ref="ERROR"/>
        </root>

</log4j:configuration>

2005年04月08日

无意中搜索到的信息,却不全面.

从网上看到的一段话:

来自:http://bbs.055.cn/t197594.html

———————————————————————————-

用迷你歌词的,不要担心注册了!!

强烈提醒
现在中国大陆所谓的迷你歌词软体属于剽窃型软体,还要收费,这不是明摆着盗窃加
销赃!请各位看官方网站登陆点击download now就可以下载了!!

http://www.philocode.com/minilyrics/release.htm

看看,下载上面的迷你歌词,不用注册;再到

http://www.minilyrics.com/static/

看看。你们去那两个网站下载的同一软体,虽然版本号不一样,是国内的所谓迷你歌词只是把别人的
软件的版本号改一下就拿出来骗钱了!更讽刺的是,先前有几位网友提出:在3.4版本前,打开迷你歌
词的帮助文档,是英文帮助文档,在"support"中,可以找到

http://www.philocode.com/minilyrics/

此事一经曝光,大陆的迷你歌词组织立即出了一版有中文帮助的迷你歌词,并把

http://www.philocode.com/minilyrics/

删除!改变官方原版版本号!居心何在?!
如果大家不懂英文那里有个download now.点击那里就得了!
你们不要再受注册的烦扰了!国内的是骗人的~~~~~~想要免费的,就马上行动吧
下载地址:点击download now就可以下载了!!!

http://fileforum.betanews.com/download/1101013226/1

注意:中方最新版3.4.1491就是官方3.3.1480版本

———————————————————————————-

参考连接:

http://www.google.com/search?q=philocode&hl=zh-CN&lr=lang_zh-CN&ie=gb2312

http://www.philocode.com/minilyrics/release.htm

http://www.minilyrics.com/static/index.htm

http://www.viewlyrics.com/

http://seventh.jsphome.com/index.php?job=art&articleid=a_20050315_160813

http://www.viewlyrics.com/download/minilyrics.exe

http://www.donews.net/wushantao/archive/2005/03/30/317986.aspx

2005年03月31日

在使用Apache AJP方式整合Tomcat集群之后,

如果启用sticky session,就可以关闭session replication功能,提高集群效率。

通过使用sticky session来减少session replication的开销,

并且不受session replication所要求的几个必要条件限制

(session replication最最麻烦的一点,

所有存放在Session中的Attribute必须序列化,

根据Sessiont同步机制,Attribute还得尽可能是不可变类的实例),

大大降低开发难度。

下面是效果图(两台tomcat上的test.jsp经过修改以显示出不同内容):

2005年03月30日
1.使用DNS轮询.
2.使用Apache R-proxy方式。
3.使用Apache mod_jk方式.
 
DNS轮询的缺点是,当集群中某台服务器停止之后,用户由于dns缓存的缘故,便无法访问服务,
必须等到dns解析更新,或者这台服务器重新启动。
还有就是必须把集群中的所有服务端口暴露给外界,没有用apache做前置代理的方式安全,
并且占用大量公网IP地址,而且tomcat还要负责处理静态网页资源,影响效率。
优点是集群配置最简单,dns设置也非常简单。
 
R-proxy的缺点是,当其中一台tomcat停止运行的时候,apache仍然会转发请求过去,导致502网关错误。
但是只要服务器再启动就不存在这个问题。
 
mod_jk方式的优点是,Apache 会自动检测到停止掉的tomcat,然后不再发请求过去。
缺点就是,当停止掉的tomcat服务器再次启动的时候,Apache检测不到,仍然不会转发请求过去。
 
R-proxy和mod_jk的共同优点是.可以只将Apache置于公网,节省公网IP地址资源。
可以通过设置来实现Apache专门负责处理静态网页,让Tomcat专门负责处理jsp和servlet等动态请求。
共同缺点是:如果前置Apache代理服务器停止运行,所有集群服务将无法对外提供。
R-proxy和mod_jk对静态页面请求的处理,都可以通设置来选取一个尽可能优化的效果。
这三种方式对实现最佳负载均衡都有一定不足,mod_jk相对好些,可以通过设置lbfactor参数来分配请求任务。
 
所有这些在实际使用中都应该根据具体情况来选择。
 
简略配置如下:
 
前期准备:
1。下载Apache和Tomcat:
Apache2.0.53:
http://www.eu.apache.org/dist/httpd/binaries/win32/apache_2.0.53-win32-x86-no_ssl.msi
 
Tomcat5.5.9:
http://www.eu.apache.org/dist/jakarta/tomcat-5/v5.5.9/bin/jakarta-tomcat-5.5.9.zip
http://www.eu.apache.org/dist/jakarta/tomcat-5/v5.5.9/bin/jakarta-tomcat-5.5.9-fulldocs.tar.gz
http://www.eu.apache.org/dist/jakarta/tomcat-5/v5.5.9/bin/jakarta-tomcat-5.5.9-compat.zip
http://www.eu.apache.org/dist/jakarta/tomcat-5/v5.5.9/bin/jakarta-tomcat-5.5.9-admin.zip
 
mod_jk.so
http://www.eu.apache.org/dist/jakarta/tomcat-connectors/jk/binaries/win32/jk-1.2.8/mod_jk-1.2.8-apache-2.0.52.so
(可选,因为Apache2.0.53已经自带).
 
 
2.配置Tomcat集群。
同时发布有clusterapp这个web应用,,修改test.jsp,
使得打开:
http://192.168.9.235:12080/clusterapp/test.jsp
http://192.168.9.226:12080/clusterapp/test.jsp
看到的是不同的页面效果。
 
3.安装Apache2.0.53。
 
此时Tomcat集群的服务器为:
192.168.9.226:12080和192.168.9.235:12080
 
编辑c:/windows/system32/drivers/etc/host文件,
最后一行加上
127.0.0.1   lizongbo.com
 
先来R-proxy方式。
 
接下来是mod_jk方式。
 
重新启动apache,同样打开
不停的刷新这个页面,也将会看到页面显示出不同的内容。
 

参考资料:
Tomcat cluster:
http://www.onjava.com/onjava/2004/04/14/examples/tomcatclustering.zip
http://www.onjava.com/pub/a/onjava/2004/11/24/replication1.html
http://www.onjava.com/pub/a/onjava/2004/11/24/replication1.html?page=2
http://www.onjava.com/pub/a/onjava/2004/04/14/clustering.html
http://www.onjava.com/pub/a/onjava/2004/04/14/clustering.html?page=2
 
R-proxy:
 
mod_jk:
 
 
 
相对已经过时的资料(因为mod_jk2方式已经不被推荐,mod_jk2已经不再被更新了):
 
 
可能有用的资料:(因为我还没有仔细看过)
 
 
 
 

 
2005年03月20日
Tomcat5.5.x 的集群配置非常简单,几乎只需要取消server.xml的对cluster的注释即可。
并且每个服务器都必须部署了相同的webapp。
 
但是这样的情况,需要用如果要用到Session复制,而Session是基于Cookie的话,就必须与dns轮询配合才能够维持好会话状态。
使用URL重写的不存在这个问题。
 
或者使用前置一个负载均衡代理服务器进行url转发,这样的一般用于大量的访问而不涉及会话交互的场合,减少或者不使用session复制以减少集群压力。
 
weblogic的集群配置就太复杂了 :(
 
 
参考:
 
http://www.onjava.com/pub/a/onjava/2004/04/14/clustering.html?page=2
 
2005年03月15日
 
 
12.如果你的webapp需要只能够进行https方式访问,那么在webapp的web.xml里加上:
 <security-constraint>
  <web-resource-collection>
   <web-resource-name>must https</web-resource-name>
   <url-pattern>/lizongbo/*</url-pattern>
  </web-resource-collection>
  <user-data-constraint>
   <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>
 </security-constraint>
 
13.修改远程关闭服务器的命令。
server.xml默认有下面一行:
<Server port=”8005″ shutdown=”SHUTDOWN”>
这样允许任何人只要telnet到服务器的8005端口,输入”SHUTDOWN”,然后回车,服务器立即就被关掉了。
从安全的角度上考虑,我们需要把这个shutdown指令改成一个别人不容易猜测的字符串。
例如修改如下:
<Server port=”8006″ shutdown=”lizongbo”>,这样就只有在telnet到8006,并且输入”lizongbo”才能够关闭Tomcat.
注意:这个修改不影响shutdown.bat的执行。运行shutdown.bat一样可以关闭服务器。
 
 
 
 
14.配置http访问日志。Tomcat自带的能够记录的http访问日志已经很详细了
取消下面这段的注释:
 
        <Valve className=”org.apache.catalina.valves.AccessLogValve”
                 directory=”logs”  prefix=”localhost_access_log.” suffix=”.txt”
                 pattern=”common” resolveHosts=”false”/>
 
然后修改为:
        <Valve className=”org.apache.catalina.valves.FastCommonAccessLogValve”
                 directory=”logs”  prefix=”localhost_access_log.” suffix=”.txt”
                 pattern=”combined” resolveHosts=”false” fileDateFormat=”yyyy-MM-dd.HH”/>
 
pattern=”combined” 记录的日志内容更详细,fileDateFormat=”yyyy-MM-dd.HH”,会让日志文件按小时进行滚卷,
比默认的按天滚卷要好些,尤其是访问量大的网站,可以考虑写成fileDateFormat=”yyyy-MM-dd.HH.mm”,就会是每分钟一个日志文件了。
而且可以分别按Engine, Host, or Context,来记录自己的日志
详情参考:
而且还可以配合awstats来进行日志统计分析: http://www.chedong.com/tech/awstats.html
 
15.限制ip,限制主机访问等。
如果想禁止指定的ip或者主机名来拒绝某些机器访问,或者指定某些机器来访问。
也支持分别按Engine, Host, or Context,进行以下配置:
<Context path=”/examples” …>  …
  <Valve className=”org.apache.catalina.valves.RemoteHostValve”
         allow=”*.mycompany.com,www.yourcompany.com”/>
  <Valve className=”org.apache.catalina.valves.RemoteAddrValve”
         deny=”192.168.1.*”/>
</Context>
参考:
 
16.发布webapp到网站根目录
1。直接复制到ROOT目录下。
2.因为无法创建无名字的xml文件,并且在xml文件里指定path也是无效的(tomcat靠文件名字来判断的),
因此必须在server.xml里写下面一段:
<Context docBase=”${catalina.home}/vhost/www.lizongbo.com” path=”/”
         privileged=”true” antiResourceLocking=”false” antiJARLocking=”false”>
<Manager className=”org.apache.catalina.session.StandardManager” algorithm=”SHA-512″
entropy=”suijisifuchuansuijisifuchuansuijisifuchuansuijisifuchuan”
maxActiveSessions=”800″ />
        <Valve className=”org.apache.catalina.valves.FastCommonAccessLogValve”
                 directory=”logs”  prefix=”localhost_mytest_access_log.” suffix=”.txt”
                 pattern=”combined” resolveHosts=”true” fileDateFormat=”yyyy-MM-dd.HH”/>       
 
</Context>
而且必须把ROOT目录删除掉,否则Tomcat还是优先部署ROOT目录为”/”。
 
17.在重新启动Tomcat的webapp的时候,禁止把session写入文件。
修改conf/web.xml
取消注释:
 <!—->
    <Manager pathname=”" />
 
18.增强SessiionID的生成算法和长度。
 

         <Manager className=”org.apache.catalina.session.StandardManager” algorithm=”SHA-512″ sessionIdLength=”40″>
         </Manager>
 
(默认的是MD5,长度是16位。)
 
 

在D:\jakarta-tomcat-5.5.8\common\classes\新建log4j.properties

 
内容:
log4j.rootLogger=debug, R
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${catalina.home}/logs/tomcat5.5.log
log4j.appender.R.MaxFileSize=10MB
log4j.appender.R.MaxBackupIndex=10
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c – %m%n
log4j.logger.org.apache.catalina=DEBUG, R
log4j.logger.org.apache.catalina.core.ContainerBase.Catalina.localhost=DEBUG, R
log4j.logger.org.apache.catalina.core=DEBUG, R
log4j.logger.org.apache.catalina.session=DEBUG, R
复制log4j-1.2.9.jar和commons-logging.jar到
D:\jakarta-tomcat-5.5.8\common\lib
 
20.使用windows域用户验证