• 2007年01月23日

    用Java进行LDAP编程的方式

    Tag:Java
    1、直接用JNDI的方式。
    shark的LDAPUserGroupManager是采用这种方式。这种方式不需要采用其他的SDK,难度较大。

    2、采用Netscape Directory SDK for Java。在sun的网站可以找到相应的开发文档:http://docs.sun.com/db/doc/816-6402-10

    3、采用jldap。jldap支持“LDIF and DSML read/write functionality and DSML web services ”。不知道Netscape Directory SDK支不支持这些特性。
    openldap上面还有JDBC-LDAP,是用JDBC的方式访问LDAP服务器。估计支持的特性更少。
  • 在用记事本之类的程序将文本文件保存为UTF-8格式时,记事本会在文件头前面加上几个不可见的字符(EF BB BF),就是所谓的BOM(Byte Order Mark)。JDK1.5之前的Reader都不能处理BOM,解析这种格式的xml文件时,会抛出异常:Content is not allowed in prolog. 据说JDK1.6已经解决了这个bug。(参考http://www.uuzone.com/blog/mao/98921.htm
    在未使用JDK1.6之前,解决办法有三:
    1、不要使用有BOM头的xml文件,就是说不要用记事本保存utf-8的xml文件,editplus就很好用;
    2、使用这位仁兄的unicodereader,可以正确处理有BOM的xml文件:
    http://koti.mbnet.fi/akini/java/unicodereader/
    3、如果是用Xerces解析器,直接传Stream给Xerces,而不是传Reader,Xerces就可以正确的处理了。总之不要用Reader就好了。

  • 2006年07月27日

    j2ee系统与rtx的整合实现

    Tag:Java

         在rtx的论坛可以看到很多类似下面的论调:
        “您好,所有用我们的api开发的jsp或java程序都必须放在SDK的安装包的java目录下,与RTXSvrApi.java同一目录(注意不能单独 copy出RTXSvrApi.java文件)。”简直让人吐血不止啊,幸好实际情形不是这样(也不可能是这样,要这样tx的程序员都找块豆腐撞死算了,否则也会给其他的java开发者口水淹死:-))。实际情形是:可以单独copy出RTXSvrApi.java,只是不能改掉RTXSvrApi.java的包名。

    整合步骤(在3.61版本下通过):
        1、将Crypt.dll、RTXParser.dll、SDKAPI.dll、SDKAPIC.dll、SDKAPIJava.dll复制到%windir%\system32目录下面;
        2、定义一个简单的servlet:RtxServlet,覆盖doGet方法,在服务器端获得sessionkey,并传给客户端:
        protected void doGet(HttpServletRequest request,HttpServletResponse response)
                throws ServletException,IOException
        {
            RTXSvrApi RtxsvrapiObj=new RTXSvrApi();
            if(RtxsvrapiObj.Init())
            {
                String userID=new OperatorAdminObj().getCurrentUserId(request);
                String sessionKey=RtxsvrapiObj.GetSessionKey(userID);
                request.setAttribute("loginUser",userID);
                request.setAttribute("rtxSessionKey",sessionKey);
                RtxsvrapiObj.UnInit();
            }
            getServletContext().getRequestDispatcher("/rtx/rtx.jsp").forward(
                    request,response);
        }
        3、在rtx.jsp中,在客户端调用activex控件,自动登录rtx客户端。
    <%@ page contentType="text/html; charset=utf-8" %>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>rtx</title>
    <script type="text/javascript" src="javascript/global.js"></script>
    <link rel="stylesheet" type="text/css" href="css/style.css">
    <script language="vbscript">
    Sub window_onload
       Set objProp = RTXAX.GetObject("Property")
       objProp.Value("RTXUsername") = "${loginUser}"
       objProp.Value("LoginSessionKey") = "${rtxSessionKey}"
       objProp.Value("ServerAddress") = "127.0.0.1"
       objProp.Value("ServerPort") = 8000
       RTXAX.Call 2, objProp
       window.close
    End Sub
    </script>
    </head>

    <body bgcolor="#FFFFFF" leftmargin="0" topmargin="0" >
    <OBJECT id=RTXAX
    data=data:application/x-oleobject;base64,fajuXg4WLUqEJ7bDM/7aTQADAAAaAAAAGgAAAA==
    classid=clsid:5EEEA87D-160E-4A2D-8427-B6C333FEDA4D VIEWASTEXT>
    </OBJECT>
    </body>
    </html>
         4、在你的系统登录验证完毕后,通过打开新窗口调用RtxServlet,
    window.open("RtxServlet","","")就可以了。

        rtx这种通过SessionKey的方式来实现其他系统与其的集成,对程序员来说是很方便的,但有其安全性问题:系统管理员可以很容易在服务器端获得SessionKey,再冒充其他人登录。不过这个世界上从无攻不破的堡垒,没有最好,只有更好。

  • 在广州地铁管理后台中使用了commons-fileupload来上传文件,发现中文路径或文件名都会变成乱码。但是上传部分的代码是已经在我们的QuickOA里面应用了的,而在QuickOA里面完全没有乱码问题。搜索fileupload的代码,发现在 FileUploadBase类里面有setHeaderEncoding方法,根据其说明,当读取上传表单的各部分时会用到该encoding,如果没有指定encoding则使用系统缺省的encoding。在QuickOA中因为页面是使用“GBK”编码,所以在简体中文的系统下面不会有乱码问题;而在广州地铁管理后台中页面是使用“UTF-8”编码,就必须指定编码。考虑到QuickOA以后有可能运行在英文或繁体中文之类的系统中,在 QuickOA中也指定编码。
    代码:
        /**
         * Specifies the character encoding to be used when reading the headers of
         * individual parts. When not specified, or <code>null</code>, the platform
         * default encoding is used.
         *
         * @param encoding The encoding used to read part headers.
         */
        public void setHeaderEncoding(String encoding)
        {
            headerEncoding = encoding;
        }

  • 2005年10月19日

    javadbf中文问题的解决

    Tag:DB j2se Java

    前面shuyanxu朋友提到javadbf(http://fireshort.blogbus.com/logs/2005/09/1420670.html)的中文支持问题,由于我测试得不够仔细就忽略掉了。最近发现读取中文是没有问题的,但写入dbf的时候就会产生乱码。

    设了几个断点之后跟踪发现是Utils中的textPadding方法有错,原来的方法是

    代码:
       public static byte[] textPadding( String text, String characterSetName, int length, int alignment,
       byte paddingByte) throws java.io.UnsupportedEncodingException {

          if( text.length() >= length) {

             return text.substring( 0, length).getBytes( characterSetName);
          }

          byte byte_array[] = new byte[ length];
          Arrays.fill( byte_array, paddingByte);

          switch( alignment) {

             case ALIGN_LEFT:
                System.arraycopy( text.getBytes( characterSetName), 0, byte_array, 0, text.length());
                break;

             case ALIGN_RIGHT:
                int t_offset = length - text.length();
                System.arraycopy( text.getBytes( characterSetName), 0, byte_array, t_offset, text.length());
                break;
             }   

          return byte_array;
       }

    我改为了
    代码:
        public static byte[] textPadding(String text,String characterSetName,
                int length,int alignment,byte paddingByte)
                throws java.io.UnsupportedEncodingException
        {
            byte[] srcByteArray=text.getBytes(characterSetName);
            byte[] dstByteArray=new byte[length];
            Arrays.fill(dstByteArray,paddingByte);

            int dstLength=0;
            if(srcByteArray.length>=length)
            {
                dstLength=length%2==0?length:length-1;
            }else
            {
                dstLength=srcByteArray.length;
            }

            switch(alignment)
            {

            case ALIGN_LEFT:
                System.arraycopy(srcByteArray,0,dstByteArray,0,dstLength);
                break;

            case ALIGN_RIGHT:
                System.arraycopy(srcByteArray,0,dstByteArray,length-dstLength,dstLength);
                break;
            }
            return dstByteArray;
        }

    中文输出完全正常了。