2007年10月16日

新注册了个独立域名,使用独立的blog了。

http://618119.com

rss订阅地址: http://feed.feedsky.com/lizongbo

从最早的 http://blog.csdn.net/lizongbo,

到 http://blog.donews.com/lizongbo

再到http://www.blogjava.net/lizongbo

现在终于拥有自己的域名和独立的blog了。

2006年02月10日

struts validator的注意事项
struts 与commons validator版本搭配不当的时候会导致js出错(生成的js里没有retrieveFormName方法),
或者是validator-rules里的arg里的 resource="true" bundle="someRes"不起作用
(比如如下配置
——————————-
struts-config里
  <message-resources parameter="ApplicationResources" />
  <message-resources key="testrs" parameter="com.lizongbo.localstring.TestRs" />

validator.xml里
    <form name="EditActionForm">
    <field property="rowid" depends="required">
      <arg key="EditActionForm.rowid" position="0" resource="true"/>
    </field>
    <field property="msgid" depends="required">
      <arg key="msgid" position="0" resource="true" bundle="testrs"/>
    </field>
    </form>
ApplicationResources.properties中
EditActionForm.rowid = 测试id
com/lizongbo/localstring/TestRs.properties中
msgid =  消息编号
——————————–
这个时候rowid的资源捆绑会成功,而msgid的资源捆绑确是无效的,
jb2006自带在struts1.2.4版本上会导致国际化版本校验捆绑不了资源。),
经过试验,成功解决这两个问题的版本搭配是使用struts1.2.8版本和commons validator 1.2.0版本结合。

2.正确的操作如下:
a.下载
struts1.2.8
http://www.eu.apache.org/dist/struts/binaries/struts-1.2.8-bin.zip
http://www.eu.apache.org/dist/struts/source/struts-1.2.8-src.zip

commons validator1.2
http://www.eu.apache.org/dist/jakarta/commons/validator/binaries/commons-validator-1.2.0.zip
http://www.eu.apache.org/dist/jakarta/commons/validator/source/commons-validator-1.2.0-src.zip

用commons-validator-1.2.0.zip\commons-validator-1.2.0\commons-validator-1.2.0.jar
替换D:\Borland\JBuilder2006\thirdparty\jakarta-struts-1.2-lib\commons-validator.jar,
用struts-1.2.8-bin.zip\struts-1.2.8-bin\lib\struts.jar替换
D:\Borland\JBuilder2006\thirdparty\jakarta-struts-1.2-lib\struts.jar,
用struts-1.2.8-bin.zip\struts-1.2.8-bin\lib\validator-rules.xml替换
D:\Borland\JBuilder2006\thirdparty\jakarta-struts-1.2-lib\validator-rules.xml

编辑D:\Borland\JBuilder2006\thirdparty\jakarta-struts-1.2-lib\validation.xml,修改后内容如下:
(dtd使用1.2.0版本的)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE form-validation PUBLIC
     "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.2.0//EN"
     "http://jakarta.apache.org/commons/dtds/validator_1_2_0.dtd">
<form-validation>
</form-validation>
(下面这步好像可以不用,如果没有发现validator_1_2_0.dtd,则进行这个操作)
下载http://jakarta.apache.org/commons/dtds/validator_1_2_0.dtd并将它保存到
D:\Borland\JBuilder2006\lib\dtd\apache\下面。

(顺便建议把D:\Borland\JBuilder2006\thirdparty\jakarta-struts-1.2-lib\下的commons*.jar全部升级为当前最新的版本)
至此,在jbuilder里新建的使用struts1.2的webapp都可以正常的使用validator了。


注意:struts的validator对消息的国际化是根据formset来识别的
因此假设需要支持zh_CN和en以及zh_HK。
因此需要如下配置,(formset内的form设置可以复制多份即可)
validator-test.xml
—————————
<form-validation>
  <formset><!–这个是默认的必须的–>
  </formset>
  <formset language="zh"><!–这个是zh的–>
  </formset>
  <formset language="en"><!–这个是en的–>
  </formset>
  <formset language="zh" country="CN"><!–这个是zh_CN的–>
  </formset>
  <formset language="zh" country="HK"><!–这个是zh_HK的–>
  </formset>
</form-validation>

同时注意,如果指定了一个Locale,这个locale是当然web应用没有支持的语言,
比如用户选择了locale为fr,此时服务器会使用一个默认的,
但是这个默认的不是我们所认为对应的ApplicationResources不带任何后缀的资源。
而好像是request.getLocale得到的,或者是jdk自己的。
(我的测试情况如下,formset里只支持默认,zh,zh_CN,zh_HK,当我选择locale为en_GB的时候
,页面返回的消息是zh版本的,而我的浏览器是zh的,jdk也是zh的,我没有去看struts的src了,
因此无从判定struts到底依据的是哪一个)

webapp里使用struts validator。
FormBean里, import org.apache.struts.validator.ValidatorForm; 继承extends ValidatorForm 。

用最新版本的commons validator ,把js单独提取为:commonsvalidator.js,然后使用下面这样的代码:
jsp里
显示出错信息:
<logic:messagesPresent>
  <bean:message key="errors.header"/>
  <ul>
  <html:messages id="error">
     <li><bean:write name="error"/></li>
  </html:messages>
  </ul><hr>
</logic:messagesPresent>

引用js
<script type="text/javascript" language="Javascript1.1" src="<%=request.getContextPath()%>/commonsvalidator.js"/>
<html:javascript formName="myActionForm" dynamicJavascript="true" staticJavascript="false"/>
html form里 <html:form  onsubmit="return validateMyActionForm(this);"(注意大小写变化:myActionForm–>validateMyActionForm);

2005年03月15日
 
接 : Tomcat 5.5.x 配置集锦(x表示4,5,.6,7)
 
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>
参考:http://jakarta.apache.org/tomcat/faq/security.html#https
http://marc.theaimsgroup.com/?l=tomcat-user&m=104951559722619&w=2
 
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一样可以关闭服务器。
参考:http://jakarta.apache.org/tomcat/faq/security.html#8005
 
 
以下皆可以参考:http://www.cnjsp.org/document/user/tuman/valve.html
 
 
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,来记录自己的日志
详情参考:
http://jakarta.apache.org/tomcat/tomcat-5.5-doc/config/valve.html
http://jakarta.apache.org/tomcat/tomcat-5.0-doc/config/logger.html
http://jakarta.apache.org/tomcat/tomcat-5.0-doc/config/host.html#Access%20Logs
而且还可以配合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>
参考:
http://jakarta.apache.org/tomcat/tomcat-5.0-doc/config/context.html
 
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位。)
 
19.配置日志:(http://jakarta.apache.org/tomcat/tomcat-5.5-doc/logging.html)
 

在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域用户验证
 
http://jcifs.samba.org/src/docs/ntlmhttpauth.html
 
 
 
2005年03月05日

java代码:

—————————————————————————————

package com.lizongbo;

import java.util.*;
import javax.mail.internet.*;
import javax.mail.*;

/**
 * <p>Title: javamail to 163 </p>
 *
 * <p>Description: 用javamail免认证方式发送邮件给163.com的用户,
 * 具体原理不在此作详细解说,有兴趣者请自行查阅相关资料。
 * /p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: lizongbo </p>
 *
 * @author lizongbo http://www.donews.net/lizongbo
 * @version 1.0
 */
public class javamail163 {

  public static void main(string[] args) throws addressexception,
      messagingexception {
    properties mailpro = new properties();
    mailpro.setproperty(“mail.smtp.host”, “202.108.44.210″);
    session session = session.getdefaultinstance(mailpro);
    session.setdebug(true);
    mimemessage msg = new mimemessage(session);
    msg.setfrom(new internetaddress(“lizongbo@gmail.com“));
    msg.setrecipient(message.recipienttype.to,
                     new internetaddress(“li_zongbo@163.com“));
    msg.setsubject(“测试免认证方式发送邮件!!!”);
    msg.settext(“测试一下,邮件来自 http://www.donews.net/lizongbo “);
    transport.send(msg);
  }
}


—————————————————————————————

执行结果:

—————————————————————————————

DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]

DEBUG SMTP: useEhlo true, useAuth false


DEBUG: SMTPTransport trying to connect to host “202.108.44.210″, port 25


DEBUG SMTP RCVD: 220 Coremail SMTP(Anti Spam) System (163com[20050206])


DEBUG: SMTPTransport connected to host “202.108.44.210″, port: 25


DEBUG SMTP SENT: EHLO lizongbo

DEBUG SMTP RCVD: 250-mx7
250-PIPELINING
250-AUTH LOGIN PLAIN NTLM
250-AUTH=LOGIN PLAIN NTLM
250 8BITMIME


DEBUG SMTP Found extension “PIPELINING”, arg “”

DEBUG SMTP Found extension “AUTH”, arg “LOGIN PLAIN NTLM”

DEBUG SMTP Found extension “AUTH=LOGIN”, arg “PLAIN NTLM”

DEBUG SMTP Found extension “8BITMIME”, arg “”

DEBUG SMTP: use8bit false

DEBUG SMTP SENT: MAIL FROM:<lizongbo@gmail.com>

DEBUG SMTP RCVD: 250 Ok


DEBUG SMTP SENT: RCPT TO:<li_zongbo@163.com>

DEBUG SMTP RCVD: 250 Ok


Verified Addresses

  li_zongbo@163.com

DEBUG SMTP SENT: DATA

DEBUG SMTP RCVD: 354 End data with <CR><LF>.<CR><LF>


DEBUG SMTP SENT:

.

DEBUG SMTP RCVD: 250 Ok: queued as NkBMWIV9KUKqYBoE.1


DEBUG SMTP SENT: QUIT

Tomcat的class加载的优先顺序一览

1.最先是$JAVA_HOME/jre/lib/ext/下的jar文件。

2.环境变量CLASSPATH中的jar和class文件。

3.$CATALINA_HOME/common/classes下的class文件。

4.$CATALINA_HOME/commons/endorsed下的jar文件。

5.$CATALINA_HOME/commons/i18n下的jar文件。

6.$CATALINA_HOME/common/lib 下的jar文件。
(JDBC驱动之类的jar文件可以放在这里,这样就可以避免在server.xml配置好数据源却出现找不到JDBC Driver的情况。)
7.$CATALINA_HOME/server/classes下的class文件。

8.$CATALINA_HOME/server/lib/下的jar文件。

9.$CATALINA_BASE/shared/classes 下的class文件。

10.$CATALINA_BASE/shared/lib下的jar文件。

11.各自具体的webapp /WEB-INF/classes下的class文件。

12.各自具体的webapp /WEB-INF/lib下的jar文件。

class的搜寻顺序如下:
————-
Bootstrap classes of your JVM
System class loader classses (described above)
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
$CATALINA_HOME/common/classes
$CATALINA_HOME/common/endorsed/*.jar
$CATALINA_HOME/common/i18n/*.jar
$CATALINA_HOME/common/lib/*.jar
$CATALINA_BASE/shared/classes
$CATALINA_BASE/shared/lib/*.jar
————–


因此放在不同webapp里的class文件,会被classloader加载成不同的实例。
例如假设下面两个不同内容的class。分别放在不同的webapp的class目录下。

package com.lizongbo;
public class TestClass {
  private String NAME=”lizongbo”;
}

package com.lizongbo;
public class TestClass {
  private String NAME=”li_zongbo”;
}

在不同的webapp得到的com.lizongbo.NAME结果是不同的,且互不影响。

但是注意,以下包名开头的class例外:
javax.*
org.xml.sax.*
org.w3c.dom.*
org.apache.xerces.*
org.apache.xalan.*

ps,注意.在各个jar中的\META-INF\MAINFEST.MF文件里Class-Path键值对,也会提供jar的加载优先顺序。
例如某jar的MAINFEST.MF内容如下:
Manifest-Version: 1.0
Created-By: lizongbo
Class-Path: commons-beanutils.jar
Class-Path: commons-collections.jar
Class-Path: commons-dbcp.jar
Class-Path: commons-digester.jar
Class-Path: commons-logging.jar
Class-Path: commons-pool.jar
Class-Path: commons-services.jar
Class-Path: commons-validator.jar
Class-Path: jakarta-oro.jar
Main-Class: com.lizongbo.MyTestClass


那么在加载这个jar的时候,会先在此jar所在目录下依次先加载commons-beanutils.jar,commons-collections.jar。。。等jar文件。

在不同的地方放置jar和class可能会产生意想不到的后果,,尤其是不同版本的jar文件,因此在实际应用部署web应用时候要特别留心.

例如 使用javamail常见的一个出错信息:
javax.mail.NoSuchProviderException: No provider for smtp
其真实原因就很可能如下:
在不同的加载jar的目录下放置了不同版本的mail.jar,比如一个是javamail1.3.1的mail.jar
在D:\jakarta-tomcat-5.5.8\common\lib下,而另外一个是javamail1.3.2的mail.jar在
D:\jakarta-tomcat-5.5.8\webapps\lizongbo\WEB-INF/lib下,
那么lizongbo这个webapp中使用到javamail进行邮件发送的时候,便会出现No provider for smtp的错误。

详情见google:http://www.google.com/search?hl=zh-CN&inlang=zh-CN&newwindow=1&q=javax.mail.NoSuchProviderException%3A+smtp&btnG=%E6%90%9C%E7%B4%A2&lr=lang_zh-CN

 

其它详情可参考:
http://java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html#JAR%20Manifest

http://jakarta.apache.org/tomcat/tomcat-5.5-doc/class-loader-howto.html

 

 

2005年03月04日

 Axis 1.2 RC3 在 tomcat 5.5.8下的配置。

axis最新下载地址:

http://www.eu.apache.org/dist/ws/axis/1_2RC3/axis-src-1_2RC3.zip
http://www.eu.apache.org/dist/ws/axis/1_2RC3/axis-bin-1_2RC3.zip
解压到: E:\javalibs\axis-1_2RC3
然后复制E:\javalibs\axis-1_2RC3\webapps\axis到D:\jakarta-tomcat-5.5.8\webapps\axis.
xmlsec的jar下载地址在:
http://xml.apache.org/security/dist/java-library/xmlsec-1.2.1.jar

下载之后复制到D:\jakarta-tomcat-5.5.8\webapps\axis\WEB-INF\lib下.
再复制E:\javalibs\jaf-1.0.2\activation.jar和E:\javalibs\javamail-1.3.2\mail.jar,
E:\javalibs\xmllibs\xerces-2_6_2\下的xercesImpl.jar,xml-apis.jar,xmlParserAPIs.jar
E:\javalibs\xmllibs\xalan-j_2_6_0\bin\xalan.jar到D:\jakarta-tomcat-5.5.8\webapps\axis\WEB-INF\lib下.
(如果不复制xalan.jar,访问: http://localhost:8080/axis/happyaxis.jsp,会得到以下警告:
Warning: could not find a dependency of class org.apache.xml.security.Init from file XML Security is not supported.
See http://xml.apache.org/security/ {4}
The root cause was: org/apache/xpath/compiler/FuncLoader
This can happen e.g. if org.apache.xml.security.Init is in the ‘common’ classpath, but a dependency like activation.jar is only in the webapp classpath
)

————

http://blog.csdn.net/lizongbo/

————

至此,完整的axis环境配置完毕.
访问http://localhost:8080/axis/happyaxis.jsp将看不到任何警告了。