2005年9月13日

在这里工作也有半年了,有得有失. 近来心里十分的茅盾, 项目已经黄色第5周了.我还是没有去改变它. 我不知道是自己不行, 还是自己不想. 学了不多的自我激励方法, 可是都不见效果. 也知道这个时候只有自己才能解救自己.

posted @ 2006-11-21 13:25 rodney 阅读(371) | 评论 (0)编辑 收藏
 
以下内容转载于http://www.aspxboy.com/private/5294/default.aspx,感谢该作者的分享.
1.     如何设置一个From的边界

2.     如何建立一个透明的From

3.     如何设置窗体在屏幕中的位置

4.     如何使最小化和最大化按钮不可用

5.     如何使一个窗体不见

6.     如何设置使窗体成为非矩形的.

7.     如何使一个窗体在屏幕的最顶端.

8.     如何显示一个Model和非Model的窗体

9.     如何制作一个MDI的窗体

10.  如何将你的窗体不显示在任务条上.

11.  如何制作一个带启动屏幕的窗体.

12.  如何使你的窗体TrayIcon.

13.  如何修改控制窗体的尺寸和长宽尺寸.

14.  如何建立一个Windows Explorer风格的窗体.

15.  如何设置初始的启动窗体

16.  如何建立一个有背景图像的窗体
==========================================================================================

1.     如何设置一个From的边界

form总共有七种不同的边界风格让你设置,你可以在设计时刻也可以运行时通过代码动态的来设置它.这七种边界风格分别是:

none (System.Windows.Forms.FormBorderStyle.None )

fixed 3D (System.Windows.Forms.FormBorderStyle.Fixed3D)

fixed Dialog (System.Windows.Forms.FormBorderStyle.FixedDialog)

fixed Single(System.Windows.Forms.FormBorderStyle.FixedSingle)

fixed Tool Window(System.Windows.Forms.FormBorderStyle.FixedToolWindow)

sizable(system.windows.forms.formborderstyle.sizable)

sizable  Tool Window

(system.windows.forms.formborderstyle.sizabletoolwindow)

在设计方式下在vs.net IDE的 Properties window中设置FormBorderStyle属性就可以了.

在运行方式下你可以用代码来完成:

dlgbx1.formborderstyle = System.Windows.Forms.FormBorderStyle.FixedDialog
这七种边界类型VB6中就有,没有什么大的变化,运行方式下你需要对照不同的枚举变量进行设置.

 

2.     如何建立一个透明的From

你可以通过两种方法在设计时刻和运行时刻来做到这一点.

设计时刻,你可以在vs.net IDE的 Properties window, 设置Opacity 属性达到这个效果.这个值从0.0到1.0 . 0表示完全透明,1.0表示完全不透明.

运行时刻你可以用下面的编码设置窗体的opactiy属性来做到.具体:

frmtransparentform.opacity = 0.76; ( C# )

看得出现在很简单了,你已经不用再去了解什么alpha变量了.透明始终只是一种效果,不要滥用它.

 

3.     如何设置窗体在屏幕中的位置

你可以设置窗体的startposition属性,vs.net一般给你一个保守的选项” WindowsDefaultLocation“ 这样系统在Load窗体时将根据用户当前的计算机设置来确定一个值,你也可以在设计时将它改成另一个值”Center”.

如果你一定要在设计方式下确定窗体在屏幕出现的位置你可以先设置startposition为manual,然后设置location的x和y的值.

运行时用代码实现似乎更简洁一些:

  Form1.Location = new Point (100, 100) ( VB.NET )
当然你也可以分别修改的Location的X和Y值,对应的是窗体的Left和Top属性,比如:

form1.left += 200 ( VB.NET )

form1.top -= 100 ( VB.NET )

另外一个属性将也将影响窗体在屏幕的位置:desktoplocation 这个属性主要是在你设置窗体的位置相对于任务栏时非常实用(当你把任务条放在屏幕的顶或左边时,其实相应改动了desktop coordinates (0,0)),你可以这样设置这个不出现在设计属性窗口中的属性,

form1.desktoplocation = new Point (100,100)

窗体在屏幕中的位置将主要取决于各自用户具体的硬件和设置情况,所以保守的作法是用默认的” WindowsDefaultLocation”或 ”Center”;专业的作法是自己先获取系统的设置然后编码动态计算后进行设置,不然很容易在屏幕上找不到你的窗体.

 

4.     如何使最小化和最大化按钮不可用

在设置窗体的form.minimizebox和form.maximizebox 当为True时表示显示,False时表示不可.用编程方式见下:

frmmaxmin.minnimizebox = False ( VB.NET)

frmmaxmin.maxmnimizebox = True  ( VB.NET )

 

5.     如何使一个窗体不见

我想最直接的办法是你调用 Hide()方法来做到这一点.不过我想提供另一种方法,看了之后你会获得一些其它的启发. ( VB.NET )

    Private Const WS_EX_TOOLWINDOW As Int32 = &H80

    Private Const WS_POPUP As Int32 = &H80000000

    Private Const WS_VISIBLE As Int32 = &H10000000

    Private Const WS_SYSMENU As Int32 = &H80000

    Private Const WS_MAXIMIZEBOX As Int32 = &H10000

 

    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams

        Get

            Dim cp As System.Windows.Forms.CreateParams

            cp = MyBase.CreateParams

            cp.ExStyle = WS_EX_TOOLWINDOW

            cp.Style = WS_POPUP Or WS_VISIBLE Or WS_SYSMENU Or WS_MAXIMIZEBOX

            cp.Height = 0

            cp.Width = 0

            Return cp

        End Get

    End Property

    原来是把Height 和Width都设置成0 ,我想这种方式和Hide()调用的底层可能是不同的。

 

6.     如何设置使窗体成为非矩形的.

这个问题我想我提供的不是最专业的作法,至少它还不能达到我期望的那样,也就是说它在某些事件中它还会变回矩形.但至少我可以告诉你:如果试图调用原来的win32’s API SetWindowRng是不行的,我曾如此的尝试过.现在你可能需要知道有关窗体的Region属性

     ' // ( VB.NET ) 

    Public Sub SetWindowRegion()

 

        Dim FormPath As System.Drawing.Drawing2D.GraphicsPath

        Dim Reg As Drawing.Region

        Dim lRet As Long

 

        FormPath = New Drawing2D.GraphicsPath()

        FormPath.AddEllipse(New Rectangle(0, 0, 250, 120))

 

        Me.Region = New Region(FormPath)

 

    End Sub

 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Me.Region = Nothing

        SetWindowRegion()

    End Sub

 

    Protected Overrides Sub OnResize(ByVal e As System.EventArgs)

          Me.Region = Nothing

          SetWindowRegion()

    End Sub

 

7.     如何使一个窗体在屏幕的最顶端.

这是很实用的一个功能,现在你不用在调用其它api了,只用设置topmost 属性为True就可以了.对于这个属性在设计时刻和运行时刻都是可以进行修改的.代码方式:

         myTopForm.TopMost = True ( VB.NET)
 

8.     如何显示一个Model和非Model的窗体

model和modeless的窗体主要将取决于你的应用,最多的是用在显示对话框.当你需要model的窗体时你调用myform. ShowDialog而非Model的调用MyForm.Show,对于ShowDialog有一个可选参数ower可以让你为一个窗体建立父子关系.比如:

' Visual Basic
Private Sub mnuAbout_Click(…args…)
   Dim f As New FormOption
   f.ShowDialog Me
End Sub
有一点需要注意的是对于ShowDialog来说,当执行到这一句,窗体显示,但这之后的代码将不会执行,只到窗口关闭之后才继续执行,而对于Show来说是即时的,显示窗体之后将立即执行下面的代码.
9.     如何制作一个MDI的窗体

1.     建立一个新的Windows Application项目

2.     分别加入两个窗体Form1 、Form2

3.     设置Form1的IsMdiContainer属性为True。使它成为MDI主窗体。

4.     在Form2中加入一个RichTextBox控件,并设置Dock为:Fill

5.     在Tools 窗体中拖一个MainMenu到窗体Form1,然后建立一个菜单File|Windows|Help三个菜单项,File中包括New、Exit菜单项;Windows中包括Cascade、Horizontal等。

6.     设置Windows菜单项的MdiList属性=True, 这样每一个MDI子窗口将自动加在Windows菜单项下面。

7.     双击New菜单项,然后加入以下代码:

     private void menuNew_Click(object sender, System.EventArgs e)

     {

         Form2  NewMdiChild ;

         NewMdiChild = new Form2() ;

         NewMdiChild.MdiParent = this ;

         NewMdiChild.Show() ;

 

     }

8.     在Windows的Cascade等菜单项中加入以下代码:

     private void menuWindowCasca_Click(object sender, System.EventArgs e)

     {

         this.LayoutMdi( MdiLayout.Cascade) ;

        

     }

另外还有以下常用的:

this.layoutmdi(mdilayout.tilehorizontal);

this.layoutmdi(mdilayout.tilevertical);

9.     F5运行。

最终版的vs.net 不知是否会有一个通用的模板,不过用完全手工的方式产生一个MDI的窗口,显得有些繁琐,不如VS.NET的IDE方式下那么简洁。

 

10.     如何将你的窗体不显示在任务条上.

当窗体的边界风格是tools Window时它都不会出现在任务条上的.另外上面标题5中介绍的方法不仅窗体看不见,也不会出现在任务条上.

    如果你现在在Dotnet的世界,这件事也变的简单,任何的Winform窗体现在都有ShowInTaskbar属性,所以你只要简单的设置这个属性就可以了。同样你可以选择在属性窗口中将ShowInTaskbar由True改为False。或是用代码的方式:

    MyTaskBarFrm.ShowInTaskbar = false ; ( C# )

 

11.     如何制作一个带启动屏幕的窗体.

需要你准备两个winform的窗体,一个叫它:splashscreen,把它做成一个漂亮的窗体。然后你需要一个主窗体叫它:form1吧,然后在这个窗体加入下面的代码。

     // ( C# )

     protected override void OnLoad ( System.EventArgs e )

     {

         //make load take a long time

         Thread.Sleep(2000);

 

         base.OnLoad(e);

 

     }

然后在main中加入这样的代码:

     [STAThread]

     static void Main()

     {

         SplashScreen splashForm = new SplashScreen();

         splashForm.Show();

 

         Form1 mainForm = new Form1() ;

         mainForm.Load += new EventHandler(splashForm.MainScreen_Load);

         Application.Run(mainForm);

 

     }

不要忘了加上对threading的引用: using System.Threading;

 

12.     如何使你的窗体TrayIcon.

实现这个功能你可以运用notifyicon控件来达到,从tools Windows中将NotifyIcon拖到你的窗体上然后在下面的事件加入如下代码,F5。

    

   ' // VB.NET

    Private mIconA As Icon = New Icon("Icon1.ico")

    Private mIconB As Icon = New Icon("Icon2.ico")

    Private mIconDisplayed As Boolean

   

    Public Sub New()

        MyBase.New

 

        Form1 = Me

 

        'This call is required by the Win Form Designer.

        InitializeComponent

 

        'TODO: Add any initialization after the InitializeComponent() call

       

        'this form isn't used directly so hide it immediately

        Me.Hide()

       

        'setup the tray icon

        Initializenotifyicon()

    End Sub

   

    Private Sub Initializenotifyicon()

        'setup the default icon

        notifyicon = New System.Windows.Forms.NotifyIcon()

        NotifyIcon.Icon = mIconA

        NotifyIcon.Text = "Right Click for the menu"

        NotifyIcon.Visible = True

        mIconDisplayed = True

 

        'Insert all MenuItem objects into an array and add them to

        'the context menu simultaneously

        Dim mnuItms(3) As MenuItem

        mnuItms(0) = New MenuItem("Show Form...", New EventHandler(AddressOf Me.ShowFormSelect))

        mnuItms(0).DefaultItem = True

        mnuItms(1) = New MenuItem("Toggle Image", New EventHandler(AddressOf Me.ToggleImageSelect))

        mnuItms(2) = New MenuItem("-")

        mnuItms(3) = New MenuItem("Exit", New EventHandler(AddressOf Me.ExitSelect))

        Dim notifyiconMnu As ContextMenu = New ContextMenu(mnuItms)

        notifyicon.ContextMenu = notifyiconMnu

    End Sub

 

    Public Sub ShowFormSelect(ByVal sender As Object, ByVal e As System.EventArgs)

        'Display the settings dialog

        Dim SettingsForm As New SettingsForm()

        SettingsForm.ShowDialog()

 

    End Sub

 

    Public Sub ToggleImageSelect(ByVal sender As Object, ByVal e As System.EventArgs)

        'called when the user selects the 'Toggle Image' context menu

 

        'determine which icon is currently visible and switch it

        If mIconDisplayed Then

            'called when the user selects the 'Show Form' context menu

            NotifyIcon.Icon = mIconB

            NotifyIcon.Text = "Sad"

            mIconDisplayed = False

        Else

            NotifyIcon.Icon = mIconA

            NotifyIcon.Text = "Happy"

            mIconDisplayed = True

        End If

 

    End Sub

 

    Public Sub ExitSelect(ByVal sender As Object, ByVal e As System.EventArgs)

        'called when the user selects the 'Exit' context menu

 

        'hide the tray icon

        NotifyIcon.Visible = False

 

        'close up

        Me.Close()

    End Sub

 

    'Form overrides dispose to clean up the component list.

    Public Overloads Overrides Sub Dispose()

        MyBase.Dispose()

        components.Dispose()

    End Sub

    图标文件你自己准备了,如果成功你可以看到有关NotifyIcond的各种功能了。

 

13.     如何修改控制窗体的尺寸和长宽尺寸.

主要是修改winform的size, Width 和Height属性。同样它们都是可以在设计和运行时刻进行修改和设置。

form1.size = New System.Drawing.Size(100, 100) ( VB.NET )

form1.width += 100  (VB.NET )

form1.height -= 20  (VB.NET )

 

14.     如何建立一个Windows Explorer风格的窗体.

1.建立一个新的windows Application

2.从toolbox窗口拖一个treeview控件、、一个splitterk控件、一个listview控件,分别在属性窗口中设置treeview的dock属性为::left;设置listview控件的dock属性为:fill

3: F5 运行

 

15.     如何设置初始的启动窗体

无论是c#还是visual Basic的Winform项目中你都可以在Solution Explorer窗口中右键你的Project,然后选择属性,从你Project的属性页中选择你启动的窗体或是Main()方法。

有些不同的是在目前的vs.net Beta2中C#项目会自动产生Main() 方法,Visual Basic.Net 的项目中你必须自己添加Main()代码,C#中你可以将Form1改成任何你可以启动的窗体名:

     // ( C# )

        static void Main()

        {

            Application.Run(new Form1());

        }

 

16.     如何建立一个有背景图像的窗体

现在的winform中所有的窗体都有一个backgroundimage属性,只用对它赋值就可以了。普通窗体可以在运行模式也可以在运行模式完成这个设置。比如在initializecomponent()或窗体的构造函数中加入这样的代码:

this.backgroundimage = new Bitmap("C:\\DotNetApp\\WinForm\\Tile.bmp" ) ;

    对于MDI的主窗体要麻烦一些,在VS.NET的IDE窗体中,当你设置完IsMdiContainer属性为True后,你需要查看一下InitializeComponent()中是否有这样的代码 ( C# ):

            this.mdiClient1.Dock = System.Windows.Forms.DockStyle.Fill;

            this.mdiClient1.Name = "mdiClient1";

或是在窗口的属性窗口组合框中看到mdiclient1 System.Windows.Forms.mdiClient.这就是主MDI窗口,不过我没有在dotnet的文档中找到任何有关System.Windows.Forms.mdiClient的说明。然后你可以在InitializeComponent()或窗体的构造函数中加入这样的代码( C# ):

this.mdiclient1.backgroundimage  = new Bitmap("C:\\DotNetApp\\WinForm\\Tile.bmp" ) ;

    网上有一个ImageView的例子,里面演示了给MDI主窗体中背景上加入一行Logo文字的方法,这样使你的MDI窗体看起来很商业化,具体的你可以这样做:

1.   先在VS.NET 自动产生代码的InitializeComponent中看是否有这样的语句( C# ):

this.controls.addrange(new System.Windows.Forms.Control[] {this.mdiClient1});

    又是这个mdiClient (haha)

2.   建立以下两个函数用于显示这个Logo字符:

// ( C# )

        protected  void Mdi_OnPaint (  Object s,  System.Windows.Forms.PaintEventArgs e )

        {

            Control c = (Control)s;

           

 

            Rectangle r1 = c.ClientRectangle;

            r1.Width -= 4;

            r1.Height -= 4;

 

            Rectangle r2 = r1;

            r2.Width -= 1;

            r2.Height -= 1;

 

            Font f = new Font("Tahoma", 8);

 

            String str = "MyWinform.NET ?2001 MyWinform Application V1.0";

 

            StringFormat sf = new StringFormat();

            sf.Alignment = StringAlignment.Far;

            sf.LineAlignment = StringAlignment.Far;

 

            e.Graphics.DrawString(str, f, new SolidBrush(SystemColors.ControlDarkDark), r1, sf);

            e.Graphics.DrawString(str, f, new SolidBrush(SystemColors.ControlLight), r2, sf);

 

        }

 

        protected  void Mdi_OnResize ( Object s ,  System.EventArgs e )

        {

           

            Control c = (Control)s;

            c.Invalidate();

        }

3.   在InitializeComponent()或窗体的构造函数中加入这样的代码:

( C# )

    this.Controls[0].Paint += new PaintEventHandler( Mdi_OnPaint ) ;

    this.Controls[0].Resize += new EventHandler( Mdi_OnResize ) ;

        注意将它加在InitializeComponent()后面或是在InitializeComponent函数中this.Controls.AddRange函数之后。

posted @ 2006-05-10 10:01 rodney 阅读(570) | 评论 (0)编辑 收藏
 

昨天下班是计算机已经关机了。可今天早上一开到启动Windows时系统一片蓝屏。我用安全模式也进入不了。后来把硬盘拆下来,安装到同事的机子上进行硬盘检查。如果分区,坏道等。结果没有什么问题,但为了资料的安全,我把有用的资料都copy到他机子上。把硬盘重新安装回我的机子上。结果怎么样。。。
神了一点问题也没有。真是虚惊一场呀。

posted @ 2006-04-25 09:33 rodney 阅读(708) | 评论 (0)编辑 收藏
 

我用记事本打开一个以前的分页程序。把其中的一部份代码copy到我的现在的程序中,可是编译器提示illegal character \12288错误。我按它提示的错误找到发生错误的行。我用别的变量名试了一下是可以的。难道是这个变量名输入时用了中文的输入法。我check一下,可是还是没有解决。我又重新声明了一个与这个变量名一样的变量,把原来的注释起来。后来发现可以了,我再把现在的注释掉,用原来的变量,还是不行。我把它删除掉重新写了一遍包括空格也删除。OK,就可以了。我想可能还是有中文的输入字符或是空格。

以面的问题可真是不是问题的问题,如果遇到同样的问题的朋友看看是否也是犯了同样的错。

最后发现是一个中文的空格,我在删除该变量时发现有一个空格的距离较大。

posted @ 2006-04-21 09:37 rodney 阅读(1024) | 评论 (0)编辑 收藏
 

因我的机子内存才512M要运行JBuilder2006,还要运行oracle9i时速度很慢,所以我先把oracle的几个服务关了。后来我要使用oracle是一直连接不上,提示“没有TNS监听”。我一查看服务,果然那个oracleOraHome90TNSListener没有启动,我一接点击启动,可还是提示那句没有TNS监听。这是为什么呢?lt;br />第一种可能是否把计算机名改了。如果是就按下面的步骤做?lt;br />把安装目录下的listener.ora打开察看。如:d:\oracle\ora90\network\admin\listener.ora.
打开该配置文件后发现如下一段配置信息:
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS_LIST =
        (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
      )
      (ADDRESS_LIST =
        (ADDRESS = (PROTOCOL = TCP)(HOST = local)(PORT = 1521))
      )
    )
  )
看到这一行HOST=local这个是计算机名字,这个名字要与现在的计算机名对应。如果不知道自己的计算机名是什么可以到“我的电脑”的属性中有一个“网络标识”的tab?你在完整的计算机名称后面看到的就是你的计算机名了?lt;br />以下内容转载http://www3.ccw.com.cn/club/essence/200202/8252.htm版权归原作?
近来,浏览BBS时,常看到“急急急!如何启动OMS?”的字眼,就针对以上这类问题,我有些经验想和大家共同分享?lt;br />能否正常启动OEM或OMS关键有以下两点:
    第一.Oracle的系统服务是否开启;
    第二.登录时用的用户名和口令是否正确?lt;br />
    那么先针对第一点谈谈Oracle的系统服务。在完全安装的情况下,Oracle的系统服务共?1项:
    1.Oracle OLAP 9.0.1.0.1
    2.Oracle OLAP Agent
    3.OracleOraHome90Agent
    4.OracleOraHome90ClientCache
    5.OracleOraHome90HTTPServer
    6.OracleOraHome90ManagementServer(0.5M)
    7.OracleOraHome90PagingServer
    8.OracleOraHome90SNMPPeerEncapsulator
    9.OracleOraHome90SNMPPeerMasterAgent
    10.OracleOraHome90TNSListener(5.2M)
    11.OracleServiceORACLE(70M)
        (注:OraHome90是可以在安装时改变的Oracle的主目录名称,是安装时的默认?

    其中最重要的服务有3个,分别是OracleOraHome90ManagementServer、OracleOraHome90TNSListener?lt;br />OracleServiceORACLE。下面就来看一下有哪些启动错误与它们有关?lt;br />
    1.Oracle系统提示:Ora-12541:TNS:没有监听器;
    2.操作系统提示:在本地计算机无法启动OMS服务
                     错误?053:服务并未及时响应来控制请求附带?lt;br />    以上两种错误提示大都是由OracleOraHome90TNSListener监听服务引起的?lt;br />解决方法:控制面?>管理工具->服务->右键单击“OracleOraHome90TNSListener”,再单击“启动”?lt;br />
    3.Oracle系统提示:Ora-12500:TNS:监听程序无法启动专用服务器进程;
    该错误是由OracleServiceORACLE专用服务器进程引起的?lt;br />解决方法:控制面?>管理工具->服务->右键单击“OracleServiceORACLE”,再单击“启动”?lt;br />
    4.Oracle系统提示:VTK-1000:无法连接到Management Server?lt;br />                       请验证您已输入Oracle Management Server的正确主机名和状态?lt;br />    该错误引起的原因有两种,一是OracleOraHome90ManagementServer还没启动;二是没有输入主机名?lt;br />解决方法:控制面?>管理工具->服务->右键单击“OracleOraHome90ManagementServer”,再单击“启动?
或是输入您这台计算机的完整名称?lt;br />小结:这三个服务的启动或关闭还有先后的顺序。一般来讲,启动时必须先启动OracleOraHome90TNSListener启动OracleOraHome90ManagementServer或OracleServiceORACLE,在启动OracleOraHome90ManagementServer时,同时也启动了OracleServiceORACLE。而关闭时必须先关闭OracleOraHome90ManagementServer再关闭OracleOraHome90TNSListener或OracleServiceORACLE,关闭OracleOraHome90ManagementServer时,若有提示输入用户名和口令,请输入sysman的用户名和口令,以确保成功的执行。有些其他提示如:资源已被占用,I/O重复,端口已被使用等等之类的话,那最好与系统管理员联系,再寻求解决办法?lt;br />

 

posted @ 2006-04-20 08:52 rodney 阅读(1027) | 评论 (1)编辑 收藏
 

type Status report

message /zz3in1/SrvTest

description The requested resource (/zz3in1/SrvTest) is not available.
这是为什呢?
用过了../../SrvTest 这个是不行的。././SrvTest这样可以。还有./SrvTest也可以。

posted @ 2006-04-17 17:01 rodney 阅读(355) | 评论 (0)编辑 收藏
 
用document.getElementById("01").innerHTML/innerText都可以。如:<tr><td id="01">Hello</td></tr>要把Hello取出来就可以用document.getElementById("01").innerHTML/innerText。
但是用innerHTML与用innerText有什么区别吗?用innerHTML会把这个标记中的所有HTML标记与值取出来。innerText只会取最后的值。
posted @ 2006-04-14 12:49 rodney 阅读(493) | 评论 (0)编辑 收藏
 
如果你在安装oracle8i时,系统会自己给你安装一个JDK1.1的或1.2的。然后你安装JDK1.5后,在系统环境中设置了JAVA_HOME是JDK1.5的,path中也设置了javaroot\JDK1.5\bin可是你怎么样也不能用JDK1.5中的命令。C:\Documents and Settings\Administrator>java
Registry key 'Software\JavaSoft\Java Runtime Environment\CurrentVersion'
has value '1.1', but '1.2' is required.
改注册表HKEY_LOCAL_MACHINE   中的SOFTWARE--JavaSoft--Java Runtime Environment--CurrentVersion的值改成了1.5
系统会提示你:C:\Documents and Settings\Administrator>java
Registry key 'Software\JavaSoft\Java Runtime Environment\CurrentVersion'
has value '1.5', but '1.2' is required.这是为什么呢?因你的系统中安装了旧的版本JDK,而且有程序程序有使用到它。这时你只要在当前的用户系统环境下设置一个JAVA_HOME(可以不要)并且在系统环境的path的最前面加上javaroot\jdk1.5\bin。这样就OK了。你可以把DOS窗口关闭再开启。WINDOWS2K不要重启计算机。WINDOWS98的要重启。
posted @ 2006-04-11 09:10 rodney 阅读(871) | 评论 (0)编辑 收藏
 

以下信息是转载http://www.aaunion.net/cn/blog/more.asp?name=magicmao&id=687
document
文挡对象 - JavaScript脚本语言描述

---------------------------------------------------------------------

:页面上元素name属性和JavaScript引用的名称必须一致包括大小写

   否则会提示你一个错误信息 "引用的元素为空或者不是对象"

---------------------------------------------------------------------

 

对象属性

document.title             // 设置文档标题等价于HTML<title>标签

document.bgColor           // 设置页面背景色

document.fgColor           // 设置前景色(文本颜色)

document.linkColor         // 未点击过的链接颜色

document.alinkColor        // 激活链接(焦点在此链接上)的颜色

document.vlinkColor        // 已点击过的链接颜色

document.URL               // 设置URL属性从而在同一窗口打开另一网页

document.fileCreatedDate   // 文件建立日期,只读属性

document.fileModifiedDate  // 文件修改日期,只读属性

document.fileSize          // 文件大小,只读属性

document.cookie            // 设置和读出cookie

document.charset           // 设置字符集 简体中文:gb2312

---------------------------------------------------------------------

对象方法

document.write()                  // 动态向页面写入内容

document.createElement(Tag)       // 创建一个html标签对象

document.getElementById(ID)       // 获得指定ID值的对象

document.getElementsByName(Name)  // 获得指定Name值的对象

---------------------------------------------------------------------

 

images 集合(页面中的图象)

 

a) 通过集合引用

document.images             // 对应页面上的<img>标签

document.images.length      // 对应页面上<img>标签的个数

document.images[0]          // 1<img>标签

document.images[i]          // i-1<img>标签

 

b) 通过nane属性直接引用

<img name="oImage">

document.images.oImage      //document.images.name 属性

 

c) 引用图片的src属性

document.images.oImage.src  //document.images.name 属性.src

 

d) 创建一个图象

var oImage

oImage = new Image()

document.images.oImage.src="/1.jpg"

// 同时在页面上建立一个<img>标签与之对应就可以显示

 

<html>

<img name=oImage>

<script language="javascript">

   var oImage

   oImage = new Image()

   document.images.oImage.src="/1.jpg"

</script>

</html>

 

----------------------------------------------------------------------

 

forms 集合(页面中的表单)

 

a) 通过集合引用

document.forms                 // 对应页面上的<form>标签

document.forms.length          // 对应页面上<form>标签的个数

document.forms[0]              // 1<form>标签

document.forms[i]              // i-1<form>标签

document.forms[i].length       // i-1<form>中的控件数

document.forms[i].elements[j]  // i-1<form>中第j-1个控件

 

b) 通过标签name属性直接引用

<form name="Myform"><input name="myctrl"></form>

document.Myform.myctrl         //document. 表单名.控件名

 

-----------------------------------------------------------------------

<html>

<!--Text 控件相关Script-->

<form name="Myform">

<input type="text" name="oText">

<input type="password" name="oPswd">

<form>

<script language="javascript">

// 获取文本密码框的值

document.write(document.Myform.oText.value)

document.write(document.Myform.oPswd.value)

</script>

</html>

-----------------------------------------------------------------------

<html>

<!--Select 控件相关Script-->

<form name="Myform">

<select name="oSelect">

<option value="1">1</option>

<option value="2">2</option>

<option value="3">3</option>

</select>

</form>

 

<script language="javascript">

   // 遍历select控件的option

   var length

   length=document.Myform.oSelect.length

   for(i=0;i<length;i++)

   document.write(document.Myform.oSelect[i].value)

</script>

 

<script language="javascript">

   // 遍历option项并且判断某个option是否被选中

   for(i=0;i<document.Myform.oSelect.length;i++){

   if(document.Myform.oSelect[i].selected!=true)

    document.write(document.Myform.oSelect[i].value)

   else

   document.write("<font color=red>"+document.Myform.oSelect[i].value+"</font>")  

   }

</script>

 

<script language="javascript">

   // 根据SelectedIndex打印出选中的option

   //(0 document.Myform.oSelect.length-1)

   i=document.Myform.oSelect.selectedIndex

   document.write(document.Myform.oSelect[i].value)

</script>

 

<script language="javascript">

   // 动态增加select控件的option

   var oOption = document.createElement("OPTION");

   oOption.text="4";

   oOption.value="4";

   document.Myform.oSelect.add(oOption);

</script>

<html>

-----------------------------------------------------------------------

<Div id="oDiv">Text</Div>

document.all.oDiv                       // 引用图层oDiv

document.all.oDiv.style                

document.all.oDiv.style.display=""      // 图层设置为可视

document.all.oDiv.style.display="none"  // 图层设置为隐藏

/*document.all 表示document中所有对象的集合

只有ie支持此属性,因此也用来判断浏览器的种类*/

-----------------------------------------------------------------------

posted @ 2006-04-10 14:07 rodney 阅读(7488) | 评论 (1)编辑 收藏
 
我写了一个测试oracle8.1的连接程序。用thin的方式连接。URL:jdbc:oracle:thin:@127.0.0.1:1521:orc;这个URL是正确的。我在thin与@中间少写一个冒号。这是一个很低级的错误,以后要小心呀。
posted @ 2006-04-05 12:02 rodney 阅读(370) | 评论 (0)编辑 收藏
 
如果下面的连接有出现class没有找到的异常,有可能是没有加裁到驱动程序,还有一种是驱动不对。
1、Oracle8/8i/9i数据库(thin模式)
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url="jdbc:oracle:thin:@localhost:1521:rcl"; //orcl为数据库的SID
String user="test";
String password="test";
Connection conn= DriverManager.getConnection(url,user,password);

2、DB2数据库

Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance();
String url="jdbc:db2://localhost:5000/sample"; //sample为你的数据库名
String user="admin";
String password="";
Connection conn= DriverManager.getConnection(url,user,password);

3、Sql Server7.0/2000数据库

Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
String url="jdbc:microsoft:sqlserver://lin56:1433;DatabaseName=pubs";
//mydb为数据库
String user="sa";
String password="";
Connection conn= DriverManager.getConnection(url,user,password);

4、Sybase数据库

Class.forName("com.sybase.jdbc.SybDriver").newInstance();
String url =" jdbcybase:Tds:localhost:5007/myDB";//myDB为你的数据库名
Properties sysProps = System.getProperties();
SysProps.put("user","userid");
SysProps.put("password","user_password");
Connection conn= DriverManager.getConnection(url, SysProps);
5、Informix数据库


Class.forName("com.informix.jdbc.IfxDriver").newInstance();
String url = "jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver;
user=testuser;password=testpassword"; //myDB为数据库名
Connection conn= DriverManager.getConnection(url);

6、MySQL数据库

Class.forName("org.gjt.mm.mysql.Driver").newInstance();
String url ="jdbc:mysql://localhost/myDB?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1"
//myDB为数据库名
Connection conn= DriverManager.getConnection(url);

7、PostgreSQL数据库

Class.forName("org.postgresql.Driver").newInstance();
String url ="jdbcostgresql://localhost/myDB" //myDB为数据库名
String user="myuser";
String password="mypassword";
Connection conn= DriverManager.getConnection(url,user,password);

8、access数据库直连用ODBC的
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver") ;
String url="jdbcdbc:Driver={MicroSoft Access Driver (*.mdb)};DBQ="+application.getRealPath("/Data/ReportDemo.mdb");
Connection conn = DriverManager.getConnection(url,"","");
Statement stmtNew=conn.createStatement() ;

二、JDBC连接MySql方式
  下面是使用JDBC连接MySql的一个小的教程

1、查找驱动程序
  MySQL目前提供的java驱动程序为Connection/J,可以从MySQL官方网站下载,并找到mysql-connector-java-3.0.15-ga-bin.jar文件,此驱动程序为纯java驱动程序,不需做其他配置。

2、动态指定classpath
  如果需要执行时动态指定classpath,就在执行时采用-cp方式。否则将上面的.jar文件加入到classpath环境变量中。

3、加载驱动程序

try{
 Class.forName(com.mysql.jdbc.Driver);
 System.out.println(Success loading Mysql Driver!);
}catch(Exception e)
{
 System.out.println(Error loading Mysql Driver!);
 e.printStackTrace();
}


4、设置连接的url
jdbc:mysql://localhost/databasename[?pa=va][&pa=va]

三、以下列出了在使用JDBC来连接Oracle数据库时可以使用的一些技巧
1、在客户端软件开发中使用Thin驱动程序
  在开发Java软件方面,Oracle的数据库提供了四种类型的驱动程序,二种用于应用软件、applets、servlets等客户端软件,另外二种用于数据库中的Java存储过程等服务器端软件。在客户机端软件的开发中,我们可以选择OCI驱动程序或Thin驱动程序。OCI驱动程序利用Java本地化接口(JNI),通过Oracle客户端软件与数据库进行通讯。Thin驱动程序是纯Java驱动程序,它直接与数据库进行通讯。为了获得最高的性能,Oracle建议在客户端软件的开发中使用OCI驱动程序,这似乎是正确的。但我建议使用Thin驱动程序,因为通过多次测试发现,在通常情况下, Thin驱动程序的性能都超过了OCI驱动程序。

2、关闭自动提交功能,提高系统性能
   在第一次建立与数据库的连接时,在缺省情况下,连接是在自动提交模式下的。为了获得更好的性能,可以通过调用带布尔值false参数的Connection类的setAutoCommit()方法关闭自动提交功能,如下所示:

conn.setAutoCommit(false);

  值得注意的是,一旦关闭了自动提交功能,我们就需要通过调用Connection类的commit()和rollback()方法来人工的方式对事务进行管理。

3、在动态SQL或有时间限制的命令中使用Statement对象
  在执行SQL命令时,我们有二种选择:可以使用PreparedStatement对象,也可以使用Statement对象。无论多少次地使用同一个 SQL命令,PreparedStatement都只对它解析和编译一次。当使用Statement对象时,每次执行一个SQL命令时,都会对它进行解析和编译。这可能会使你认为,使用PreparedStatement对象比使用Statement对象的速度更快。然而,我进行的测试表明,在客户端软件中,情况并非如此。因此,在有时间限制的SQL操作中,除非成批地处理SQL命令,我们应当考虑使用Statement对象。

   此外,使用Statement对象也使得编写动态SQL命令更加简单,因为我们可以将字符串连接在一起,建立一个有效的SQL命令。因此,我认为,Statement对象可以使动态SQL命令的创建和执行变得更加简单。

4、利用helper函数对动态SQL命令进行格式化
  在创建使用Statement对象执行的动态SQL命令时,我们需要处理一些格式化方面的问题。例如,如果我们想创建一个将名字O'Reilly插入表中的SQL命令,则必须使用二个相连的“''”号替换O'Reilly中的“'”号。完成这些工作的最好的方法是创建一个完成替换操作的helper方法,然后在连接字符串心服用公式表达一个SQL命令时,使用创建的helper方法。与此类似的是,我们可以让helper方法接受一个Date型的值,然后让它输出基于Oracle的to_date()函数的字符串表达式。

5、利用PreparedStatement对象提高数据库的总体效率
  在使用PreparedStatement对象执行SQL命令时,命令被数据库进行解析和编译,然后被放到命令缓冲区。然后,每当执行同一个 PreparedStatement对象时,它就会被再解析一次,但不会被再次编译。在缓冲区中可以发现预编译的命令,并且可以重新使用。在有大量用户的企业级应用软件中,经常会重复执行相同的SQL命令,使用PreparedStatement对象带来的编译次数的减少能够提高数据库的总体性能。如果不是在客户端创建、预备、执行PreparedStatement任务需要的时间长于Statement任务,我会建议在除动态SQL命令之外的所有情况下使用PreparedStatement对象。

6、在成批处理重复的插入或更新操作中使用PreparedStatement对象
  如果成批地处理插入和更新操作,就能够显著地减少它们所需要的时间。Oracle提供的Statement和 CallableStatement并不真正地支持批处理,只有PreparedStatement对象才真正地支持批处理。我们可以使用 addBatch()和executeBatch()方法选择标准的JDBC批处理,或者通过利用PreparedStatement对象的 setExecuteBatch()方法和标准的executeUpdate()方法选择速度更快的Oracle专有的方法。要使用Oracle专有的批处理机制,可以以如下所示的方式调用setExecuteBatch():

PreparedStatement pstmt3D null;
try {
 ((OraclePreparedStatement)pstmt).setExecuteBatch(30);
 ...
 pstmt.executeUpdate();
}
    调用setExecuteBatch()时指定的值是一个上限,当达到该值时,就会自动地引发SQL命令执行,标准的executeUpdate()方法就会被作为批处理送到数据库中。我们可以通过调用PreparedStatement类的sendBatch()方法随时传输批处理任务。
 
7、使用Oracle locator方法插入、更新大对象(LOB)
  Oracle的PreparedStatement类不完全支持BLOB和CLOB等大对象的处理,尤其是Thin驱动程序不支持利用 PreparedStatement对象的setObject()和setBinaryStream()方法设置BLOB的值,也不支持利用 setCharacterStream()方法设置CLOB的值。只有locator本身中的方法才能够从数据库中获取LOB类型的值。可以使用 PreparedStatement对象插入或更新LOB,但需要使用locator才能获取LOB的值。由于存在这二个问题,因此,我建议使用 locator的方法来插入、更新或获取LOB的值。

8、使用SQL92语法调用存储过程
  在调用存储过程时,我们可以使用SQL92或Oracle PL/SQL,由于使用Oracle PL/SQL并没有什么实际的好处,而且会给以后维护你的应用程序的开发人员带来麻烦,因此,我建议在调用存储过程时使用SQL92。

9、使用Object SQL将对象模式转移到数据库中
  既然可以将Oracle的数据库作为一种面向对象的数据库来使用,就可以考虑将应用程序中的面向对象模式转到数据库中。目前的方法是创建Java bean作为伪装的数据库对象,将它们的属性映射到关系表中,然后在这些bean中添加方法。尽管这样作在Java中没有什么问题,但由于操作都是在数据库之外进行的,因此其他访问数据库的应用软件无法利用对象模式。如果利用Oracle的面向对象的技术,可以通过创建一个新的数据库对象类型在数据库中模仿其数据和操作,然后使用JPublisher等工具生成自己的Java bean类。如果使用这种方式,不但Java应用程序可以使用应用软件的对象模式,其他需要共享你的应用中的数据和操作的应用软件也可以使用应用软件中的对象模式。

10、利用SQL完成数据库内的操作
  我要向大家介绍的最重要的经验是充分利用SQL的面向集合的方法来解决数据库处理需求,而不是使用Java等过程化的编程语言。

  如果编程人员要在一个表中查找许多行,结果中的每个行都会查找其他表中的数据,最后,编程人员创建了独立的UPDATE命令来成批地更新第一个表中的数据。与此类似的任务可以通过在set子句中使用多列子查询而在一个UPDATE命令中完成。当能够在单一的SQL命令中完成任务,何必要让数据在网上流来流去的?我建议用户认真学习如何最大限度地发挥SQL的功能。

   

ORACLE 数据库备份技术
  ORACLE数据库是一种大型关系型的数据库,可以存贮达到存贮TB的数据,那么如何保证这些数据的安全尤其至关重要,我们从1991年开始使用 ORACLE数据库,通过这些年的使用,我们制定了一整套的ORACLE数据库的备份制度。现在把我们的备份制度介绍给大家,供大家参考。

1.根据实际需要决定数据库的运行方式
ORACLE数据库有两种运行方式:一是归档方式(ARCHIVELOG),归档方式的目的是当数据库发生故障时最大限度恢复所有已提交的事物;二是不归档方式(NOARCHIVELOG),恢复数据库到最近的回收点。我们根据数据库的高可用性和用户可承受丢失的工作量的多少,把我们正式运行的数据库采用为归档方式;那些正在开发和调试的数据库采用不归档方式。

2如何改变数据库的运行方式
2.1在创建数据库时设置数据库的运行的方式
  在创建数据库时,作为创建数据库的一部分,就决定了数据库初始的存档方式。一般情况下为NOARCHIVELOG方式。当数据库创建好以后,根据我们的需要把需要运行在归档方式的数据库改成ARCHIVELOG方式。
  
2.2改变不归档方式为为归档方式
  关闭数据库,备份已有的数据
  改变数据库的运行方式是对数据库的重要改动,所以要对数据库做备份,对可能出现的问题作出保护。
  启动Instance ,Mount数据库但不打开数据库,来改变归档方式

  sqldba lmode=y(svrmgrl)
  sqldba>connect internal
  sqldba>startup mount
  sqldba>alter database archivelog;

  使能自动存档
  在初始化文件init*.ora(一般放ORACLE根目录的下层目录dbs下)加参数:
  log_archive_start=true
  指定存档的重做登录文件名和存放的位置
  同样是在初始化文件init*.ora中加入下面的参数:
  log_archive_format=%S.arc
  log_archive_dest=/arch12/arch (arch12 是日志文件存放的目录)
  关闭数据库,重新启动数据库,归档方式转换完成。

3回收制度
3.1根据数据库的运行方式和可承受丢失的工作量来决定数据库的回收制度对于不归档方式,我们用的是ORACLE数据库的逻辑备份Export ,回收的制度是:一个月作一次全备份(x01.dmp),一周作一次累积备份(c*.dmp),一天一次增量备份(I*.dmp),具体的是星期一到星期五作增量备份,星期六做累积备份或全备份,每次做完备份后自动传到其它的机器上存储。这些备份都是自动执行的,后面给出程序文本。

  对于归档方式,我们用的是ORCALE的物理备份:当数据库创建好以后,做一次物理上的全备份,平时在不关闭数据库的前提下,一个星期对经常改变的数据文件做联机的数据库数据文件的物理备份;当数据库的结构发生改变,如:增加表空间,加数据文件等,如允许关机,正常关闭数据库,重新做数据库全备份,否则,备份控制文件,备份数据文件照常。联机的日志文件我们是写在阵列上的,不用镜象和备份。

3.2回收的方法
3.2.1不归档方式
   我们拿曙光AIX操作系统为例,来讲解以下如何做自动备份:
---- a.首先建UNIX用户 demo/demo
---- b.拷贝oracle用户下的 .profile 到 demo 用户下,以保证 demo 用户可以用 Export命令
---- c.用root用户登录,编辑 /var/adm/cron/cron.allow 加入用户名demo,这样demo用户就有权自动执行数据库备份的shell程序;
---- d.创建数据库备份程序,放到本用户的下层目录bin下,并且这些文件要有可执行权文件zlbf1:(增量备份1,星期一执行的程序)

. /u11/demo/.profile 
exp system/manager inctype=INCREMENTAL file=i01.dmp 
ftp -n< < ! 
open 10.10.10.40 
user demo demo 
binary 
prompt 
cd backup40 
put i01.dmp 
close 
bye 
! 

文件zlbf2:(增量备份2, 星期二执行的程序) 

. /u11/demo/.profile 
exp system/manager inctype=INCREMENTAL file=i02.dmp 
ftp -n< < ! 

open 10.10.10.40 
user demo demo 
binary 
prompt 
cd backup40 
put i02.dmp 
close 
bye 
! 

文件zlbf3:(增量备份3, 星期三执行的程序) 
. /u11/demo/.profile 
exp system/manager inctype=INCREMENTAL file=i03.dmp 
ftp -n< < ! 
open 10.10.10.40 
user demo demo 
binary 
prompt 
cd backup40 
put i03.dmp 
close 
bye 
! 
文件zlbf4:(增量备份4, 星期四执行的程序) 
. /u11/demo/.profile 
exp system/manager inctype=INCREMENTAL file=i04.dmp 
ftp -n< < ! 
open 10.10.10.40 
user demo demo 
binary 
prompt 
cd backup40 
put i04.dmp 
close 
bye 
! 
文件zlbf5:(增量备份5, 星期五执行的程序) 
. /u11/demo/.profile 
exp system/manager inctype=INCREMENTAL file=i05.dmp 
ftp -n< < ! 
open 10.10.10.40 
user demo demo 
binary 
prompt 
cd backup40 
put i05.dmp 
close 
bye 
! 
文件zlbf6:(增量备份6, 星期六执行的程序) 
. /u11/demo/.profile 
js=`ls c*.dmp|wc -l` 
if test  = 0 
then 
exp system/manager inctype=CUMULATIVE file=c01.dmp 
ftp -n< < ! 
open 10.10.10.40 
user demo demo 
binary 
prompt 
cd backup40 
put c01.dmp 
close 
bye 
! 
fi 
if test  = 1 
then 
exp system/manger inctype=CUMULATIVE file=c02.dmp 
ftp -n< < ! 
open 10.10.10.40 
user demo demo 
binary 
prompt 
cd backup40 
put c02.dmp 
close 
bye 
! 
fi 
if test  = 2 
then 
exp system/maneger inctype=CUMULATIVE file=c03.dmp 
ftp -n< < ! 
open 10.10.10.40 
user demo demo 
binary 
prompt 
cd backup40 
put c03.dmp 
close 
bye 
! 
fi 
if test  = 3 
then 
exp system/manager inctype=COMPLETE file=x01.dmp 
ftp -n< < ! 
open 10.10.10.40 
user demo demo 
binary 
prompt 
cd backup40 
put x01.dmp 
close 
bye 
! 
rm c*.dmp 
fi 

---- e.在demo 用户下建一个文件,假如叫:cron.demo,文件内容如下 
59 22 * * 1 bin/zlbf1 
59 22 * * 2 bin/zlbf2 
59 22 * * 3 bin/zlbf3 
59 22 * * 4 bin/zlbf4 
59 22 * * 5 bin/zlbf5 
59 22 * * 6 bin/zlbf6 

---- f.在demo用户下执行下面的命令:
crontab cron.demo 执行的结果放到
/var/spool/cron/crontabs/demo文件里

---- g.重新启动cron 进程,命令:kill -1 进程号
---- h.执行结果放在本用户的邮件里
---- i.查看结果是否执行,请看:/var/adm/cron/log文件

3.2.2归档方式
---- a. 找到要回收的数据文件、联机重做登录文件、控制文件和参数文件
---- b. 正常关闭数据库,作一次全回收(用操作系统的TAR命令,可以写成shell程序),然后打开数据库供正常使用,shell程序如下:
tar cvf /dev/rmt/ctape2 /u1/oracle/dbs/ctrl1ora7.ctl
/u1/oracle/dbs/ctrl2ora7.ctl
/u1/oracle/dbs/ctrl3ora7.ctl
/u1/oracle/dbs/systora7.dbf
/u1/oracle/dbs/rbsora7.dbf
/u1/oracle/dbs/tempora7.dbf
/u1/oracle/dbs/toolora7.dbf
/u1/oracle/dbs/usrora7.dbf
/ls1/ls1.dbf
/u1/oracle/dbs/log1ora7.dbf
/u1/oracle/dbs/log2ora7.dbf
/u1/oracle/dbs/log3ora7.dbf
---- c. 经常作联机的表空间和数据文件的部分回收
首先标记联机表空间回收的开始
alter tablespace 表空间名 begin backup;
用操作系统命令备份数据文件
最后标记联机的表空间回收结束
alter tablespace 表空间名 end backup
---- 多个表空间可以一起做标记,备份做标记的所有数据文件后,一起标记结束。
---- d. 当数据库结构发生改变后,要对它的控制文件做回收
sqldba >alter database backup
controlfile to ’文件名’ reuse;   

数据库设计中的14个技巧
1. 原始单据与实体之间的关系
  可以是一对一、一对多、多对多的关系。在一般情况下,它们是一对一的关系:即一张原始单据对应且只对应一个实体。在特殊情况下,它们可能是一对多或多对一的关系,即一张原始单证对应多个实体,或多张原始单证对应一个实体。这里的实体可以理解为基本表。明确这种对应关系后,对我们设计录入界面大有好处。
  〖例1〗:一份员工履历资料,在人力资源信息系统中,就对应三个基本表:员工基本情况表、社会关系表、工作简历表。这就是“一张原始单证对应多个实体”的典型例子。

2. 主键与外键
  一般而言,一个实体不能既无主键又无外键。在E—R 图中, 处于叶子部位的实体, 可以定义主键,也可以不定义主键(因为它无子孙), 但必须要有外键(因为它有父亲)。
  主键与外键的设计,在全局数据库的设计中,占有重要地位。当全局数据库的设计完成以后,有个美国数据库设计专家说:“键,到处都是键,除了键之外,什么也没有”,这就是他的数据库设计经验之谈,也反映了他对信息系统核心(数据模型)的高度抽象思想。因为:主键是实体的高度抽象,主键与外键的配对,表示实体之间的连接。

3. 基本表的性质
  基本表与中间表、临时表不同,因为它具有如下四个特性:
  (1) 原子性。基本表中的字段是不可再分解的。
  (2) 原始性。基本表中的记录是原始数据(基础数据)的记录。
  (3) 演绎性。由基本表与代码表中的数据,可以派生出所有的输出数据。
  (4) 稳定性。基本表的结构是相对稳定的,表中的记录是要长期保存的。
   理解基本表的性质后,在设计数据库时,就能将基本表与中间表、临时表区分开来。

4. 范式标准
  基本表及其字段之间的关系, 应尽量满足第三范式。但是,满足第三范式的数据库设计,往往不是最好的设计。为了提高数据库的运行效率,常常需要降低范式标准:适当增加冗余,达到以空间换时间的目的。
  〖例2〗:有一张存放商品的基本表,如表1所示。“金额”这个字段的存在,表明该表的设计不满足第三范式,因为“金额”可以由“单价”乘以“数量”得到,说明“金额”是冗余字段。但是,增加“金额”这个冗余字段,可以提高查询统计的速度,这就是以空间换时间的作法。
  在Rose 2002中,规定列有两种类型:数据列和计算列。“金额”这样的列被称为“计算列”,而“单价”和“数量”这样的列被称为“数据列”。
  表1 商品表的表结构
  商品名称商品型号单价数量金额
  电视机 29吋 2,500 40 100,000

5. 通俗地理解三个范式
  通俗地理解三个范式,对于数据库设计大有好处。在数据库设计中,为了更好地应用三个范式,就必须通俗地理解三个范式(通俗地理解是够用的理解,并不是最科学最准确的理解):
  第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;
  第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;
  第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。
  没有冗余的数据库设计可以做到。但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是:在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余。

6. 要善于识别与正确处理多对多的关系
  若两个实体之间存在多对多的关系,则应消除这种关系。消除的办法是,在两者之间增加第三个实体。这样,原来一个多对多的关系,现在变为两个一对多的关系。要将原来两个实体的属性合理地分配到三个实体中去。这里的第三个实体,实质上是一个较复杂的关系,它对应一张基本表。一般来讲,数据库设计工具不能识别多对多的关系,但能处理多对多的关系。
  〖例3〗:在“图书馆信息系统”中,“图书”是一个实体,“读者”也是一个实体。这两个实体之间的关系,是一个典型的多对多关系:一本图书在不同时间可以被多个读者借阅,一个读者又可以借多本图书。为此,要在二者之间增加第三个实体,该实体取名为“借还书”,它的属性为:借还时间、借还标志(0表示借书,1表示还书),另外,它还应该有两个外键(“图书”的主键,“读者”的主键),使它能与“图书”和 “读者”连接。

7. 主键PK的取值方法
  PK是供程序员使用的表间连接工具,可以是一无物理意义的数字串, 由程序自动加1来实现。也可以是有物理意义的字段名或字段名的组合。不过前者比后者好。当PK是字段名的组合时,建议字段的个数不要太多,多了不但索引占用空间大,而且速度也慢。

8. 正确认识数据冗余
  主键与外键在多表中的重复出现, 不属于数据冗余,这个概念必须清楚,事实上有许多人还不清楚。非键字段的重复出现, 才是数据冗余!而且是一种低级冗余,即重复性的冗余。高级冗余不是字段的重复出现,而是字段的派生出现。
  〖例4〗:商品中的“单价、数量、金额”三个字段,“金额”就是由“单价”乘以“数量”派生出来的,它就是冗余,而且是一种高级冗余。冗余的目的是为了提高处理速度。只有低级冗余才会增加数据的不一致性,因为同一数据,可能从不同时间、地点、角色上多次录入。因此,我们提倡高级冗余(派生性冗余),反对低级冗余(重复性冗余)。

9. E--R图没有标准答案
  信息系统的E--R图没有标准答案,因为它的设计与画法不是惟一的,只要它覆盖了系统需求的业务范围和功能内容,就是可行的。反之要修改E--R图。尽管它没有惟一的标准答案,并不意味着可以随意设计。好的E—R图的标准是:结构清晰、关联简洁、实体个数适中、属性分配合理、没有低级冗余。

10. 视图技术在数据库设计中很有用
  与基本表、代码表、中间表不同,视图是一种虚表,它依赖数据源的实表而存在。视图是供程序员使用数据库的一个窗口,是基表数据综合的一种形式, 是数据处理的一种方法,是用户数据保密的一种手段。为了进行复杂处理、提高运算速度和节省存储空间, 视图的定义深度一般不得超过三层。若三层视图仍不够用, 则应在视图上定义临时表, 在临时表上再定义视图。这样反复交迭定义, 视图的深度就不受限制了。
  对于某些与国家政治、经济、技术、军事和安全利益有关的信息系统,视图的作用更加重要。这些系统的基本表完成物理设计之后,立即在基本表上建立第一层视图,这层视图的个数和结构,与基本表的个数和结构是完全相同。并且规定,所有的程序员,一律只准在视图上操作。只有数据库管理员,带着多个人员共同掌握的“安全钥匙”,才能直接在基本表上操作。请读者想想:这是为什么?

11. 中间表、报表和临时表
  中间表是存放统计数据的表,它是为数据仓库、输出报表或查询结果而设计的,有时它没有主键与外键(数据仓库除外)。临时表是程序员个人设计的,存放临时记录,为个人所用。基表和中间表由DBA维护,临时表由程序员自己用程序自动维护。

12. 完整性约束表现在三个方面
  域的完整性:用Check来实现约束,在数据库设计工具中,对字段的取值范围进行定义时,有一个Check按钮,通过它定义字段的值城。
  参照完整性:用PK、FK、表级触发器来实现。
  用户定义完整性:它是一些业务规则,用存储过程和触发器来实现。

13. 防止数据库设计打补丁的方法是“三少原则”
  (1) 一个数据库中表的个数越少越好。只有表的个数少了,才能说明系统的E--R图少而精,去掉了重复的多余的实体,形成了对客观世界的高度抽象,进行了系统的数据集成,防止了打补丁式的设计;
  (2) 一个表中组合主键的字段个数越少越好。因为主键的作用,一是建主键索引,二是做为子表的外键,所以组合主键的字段个数少了,不仅节省了运行时间,而且节省了索引存储空间;
  (3) 一个表中的字段个数越少越好。只有字段的个数少了,才能说明在系统中不存在数据重复,且很少有数据冗余,更重要的是督促读者学会“列变行”,这样就防止了将子表中的字段拉入到主表中去,在主表中留下许多空余的字段。所谓“列变行”,就是将主表中的一部分内容拉出去,另外单独建一个子表。这个方法很简单,有的人就是不习惯、不采纳、不执行。
  数据库设计的实用原则是:在数据冗余和处理速度之间找到合适的平衡点。“三少”是一个整体概念,综合观点,不能孤立某一个原则。该原则是相对的,不是绝对的。“三多”原则肯定是错误的。试想:若覆盖系统同样的功能,一百个实体(共一千个属性) 的E--R图,肯定比二百个实体(共二千个属性) 的E--R图,要好得多。
  提倡“三少”原则,是叫读者学会利用数据库设计技术进行系统的数据集成。数据集成的步骤是将文件系统集成为应用数据库,将应用数据库集成为主题数据库,将主题数据库集成为全局综合数据库。集成的程度越高,数据共享性就越强,信息孤岛现象就越少,整个企业信息系统的全局E—R图中实体的个数、主键的个数、属性的个数就会越少。
  提倡“三少”原则的目的,是防止读者利用打补丁技术,不断地对数据库进行增删改,使企业数据库变成了随意设计数据库表的“垃圾堆”,或数据库表的“大杂院”,最后造成数据库中的基本表、代码表、中间表、临时表杂乱无章,不计其数,导致企事业单位的信息系统无法维护而瘫痪。
  “三多”原则任何人都可以做到,该原则是“打补丁方法”设计数据库的歪理学说。“三少”原则是少而精的原则,它要求有较高的数据库设计技巧与艺术,不是任何人都能做到的,因为该原则是杜绝用“打补丁方法”设计数据库的理论依据。

14. 提高数据库运行效率的办法
  在给定的系统硬件和系统软件条件下,提高数据库系统的运行效率的办法是:
  (1) 在数据库物理设计时,降低范式,增加冗余, 少用触发器, 多用存储过程。
  (2) 当计算非常复杂、而且记录条数非常巨大时(例如一千万条),复杂计算要先在数据库外面,以文件系统方式用C++语言计算处理完成之后,最后才入库追加到表中去。这是电信计费系统设计的经验。
  (3) 发现某个表的记录太多,例如超过一千万条,则要对该表进行水平分割。水平分割的做法是,以该表主键PK的某个值为界线,将该表的记录水平分割为两个表。若发现某个表的字段太多,例如超过八十个,则垂直分割该表,将原来的一个表分解为两个表。
  (4) 对数据库管理系统DBMS进行系统优化,即优化各种系统参数,如缓冲区个数。
  (5) 在使用面向数据的SQL语言进行程序设计时,尽量采取优化算法。
   总之,要提高数据库的运行效率,必须从数据库系统级优化、数据库设计级优化、程序实现级优化,这三个层次上同时下功夫。
  上述十四个技巧,是许多人在大量的数据库分析与设计实践中,逐步总结出来的。对于这些经验的运用,读者不能生帮硬套,死记硬背,而要消化理解,实事求是,灵活掌握。并逐步做到:在应用中发展,在发展中应用。
特别声明以上内容是转至http://dev2dev.bea.com.cn/bbsdoc/20060112181.html,如果您认为该文档的内容侵犯了您的权益,请与整理者(excelarthur.com.cn)联系,与Dev2Dev网站无关。

posted @ 2006-04-04 14:36 rodney 阅读(1357) | 评论 (0)编辑 收藏
 
在安装完了JBuilder9时,打开JB9会弹出一个对话框讲你要注册。这时你没有注册号时,有一个叫JB9_Ent_KeyGen.exe的文件,这时你只要将这个文件copy to 你安装的目录下。double click this file,这时你只要点击"Generate",再点击"Save"就OK了。例如:E:\JBuilder9\jdk1.4\bin下放入copy的文件。这个文件一定要放入jdk1.4\bin下面。
posted @ 2006-04-03 17:27 rodney 阅读(1506) | 评论 (0)编辑 收藏
 
如果你做过很多java程序,你可能对java集合类很熟悉,例如Vector和ArrayList。你可以创建一个集合并向其中增加元素:
  1.     List lst = new ArrayList();
  2.     lst.add(new Integer(37));

在这个特殊的范例中,一个整型值37用于构造一个Integer封装类对象,然后那个对象被加入到列表。

这个简单的范例展示集合的一个基础-他们用于操纵一列对象,其中的每个对象是一个类或者接口类型。因此,一个ArrayList可以包含Object,String,Float以及Runnable类型的对象。集合类不能用于原始数据类型的列表,例如整型数组。

如果你在你的程序中使用原始类型的数组,你如何操纵它们呢?这个技巧就给你展示几个你可以使用的技术。

第一个技术是排序。java.util.Arrays类包含一套排序和查找数组的类方法,例如:
  1.     import java.util.Arrays;
  2.     public class ArrayDemo1 {
  3.         public static void main(String args[]) {
  4.             int vec[] = {37, 47, 23, -5, 19, 56};
  5.             Arrays.sort(vec);
  6.             for (int i = 0; i < vec.length; i++) {
  7.                 System.out.println(vec[i]);
  8.             }
  9.         }
  10.     }

这个演示程序初始化一个整数数组然后调用Arrays.sort升序排序那个数组。

类似的,你可以在排完序的数组上进行二分法查找:
  1.     import java.util.Arrays;
  2.     public class ArrayDemo2 {
  3.         public static void main(String args[]) {
  4.             int vec[] = {-5, 19, 23, 37, 47, 56};
  5.             int slot = Arrays.binarySearch(vec, 35);
  6.             slot = -(slot + 1);
  7.             System.out.println("insertion point = " + slot);
  8.         }
  9.     }

这个程序有个微妙的概念,如果二分法查找失败它将返回:

    -(insertion point) - 1

这个演示程序以参数35调用查找方法,而那个参数在数组中不存在,方法返回值-4,如果这个值加一再取其负数就得到3,这就是35应该被插入到数组中的位置,换言之,值-5, 19和23在数组中占据的位置是0,1和2。因此值35应该在索引3的位置,而37, 47以及56顺延。搜索方法并不进行实际的插入操作而只是指出应该在何处插入。

除了排序和查找,我们还可以对原始类型数组做什么?另一个有用的技术是将一个原始数组转换为等价的对象类型数组。每个对应元素使用它们的封装器类,例如在封装数组中,37成为Integer(37)。
  1.     import java.util.Arrays;
  2.     import java.lang.reflect.Array;
  3.     
  4.     public class ArrayDemo3 {
  5.     
  6.         // if input is a single-dimension primitive array,
  7.         // return a new array consisting of wrapped elements,
  8.         // else just return input argument
  9.     
  10.         public static Object toArray(Object vec) {
  11.     
  12.             // if null, return
  13.     
  14.             if (vec == null) {
  15.                 return vec;
  16.             }
  17.     
  18.             // if not an array or elements not primitive, return
  19.     
  20.             Class cls = vec.getClass();
  21.             if (!cls.isArray()) {
  22.                 return vec;
  23.             }
  24.             if (!cls.getComponentType().isPrimitive()) {
  25.                 return vec;
  26.             }
  27.     
  28.             // get array length and create Object output array
  29.     
  30.             int length = Array.getLength(vec);
  31.             Object newvec[] = new Object[length];
  32.     
  33.             // wrap and copy elements
  34.     
  35.             for (int i = 0; i < length; i++) {
  36.                 newvec[i] = Array.get(vec, i);
  37.             }
  38.     
  39.             return newvec;
  40.         }
  41.     
  42.         public static void main(String args[]) {
  43.     
  44.             // create a primitive array
  45.     
  46.             int vec[] = new int[]{1, 2, 3};
  47.     
  48.             // wrap it
  49.     
  50.             Object wrappedvec[] = (Object[])toArray(vec);
  51.     
  52.             // display result
  53.     
  54.             for (int i = 0; i < wrappedvec.length; i++) {
  55.                 System.out.println(wrappedvec[i]);
  56.             }
  57.         }
  58.     }

方法"toArray"的参数是一个Object对象(数组可以被赋值给一个Object引用)。如果参数是null或者代表的不是原始类型数组那么这个方法简单的返回参数值。java.lang.Class工具类用于判断参数是否是一个数组并获取数组的底层元素的类型。

一旦做完这些检查,使用java.lang.reflect.Array工具类的反射工具方法就可以获取原始数组的长度并获得数组的单个元素。Array.get获得的每个元素被返回到封装器类中,例如Integer或者Double。

最终的范例基于前面的那个并向你展示如何在数组上使用集合特性。这假设你已经有一个对象数组。
  1.     import java.util.Arrays;
  2.     import java.util.List;
  3.     public class ArrayDemo4 {
  4.         public static void main(String args[]) {
  5.             Object vec[] = {new Integer(37), new Integer(47)};
  6.             List lst = Arrays.asList(vec);
  7.             lst.set(1, new Integer(57));
  8.             for (int i = 0; i < vec.length; i++) {
  9.                 System.out.println(vec[i]);
  10.             }
  11.         }
  12.     }

在这个程序中,vec是一个对象数组,包含Integer(37)和Integer(47),然后Arrays.asList被调用。它返回一个集合(List接口类型),使用数组作为集合的后台存储。换言之,ArrayList这样的集合类型在它内部有某种存储类型去存储集合元素。在这个例子中,使用的存储类型是作为参数传递到Arrays.asList的数组。这意味着集合方法所做的改变会被反射到底层的数组。

修改集合中的元素1导致底层的数组也改变,程序的输出是:

    37
    57

因此如果你有一个对象数组,你可以在它上面使用集合特性,数组自身作为底层存储。

我们也可以将集合转换为一个对象数组,例如:

    Object vec[] = lst.toArray();

package com.cucu.test;

/**
* @author http://www.linewell.com <a href=mailto:cg@linewell.com>cg@linewell.com</a>
* @version 1.0
*/
public class Sort {

public void swap(int a[], int i, int j) {
int tmp = a;
a = a[j];
a[j] = tmp;
}

public int partition(int a[], int low, int high) {
int pivot, p_pos, i;
p_pos = low;
pivot = a[p_pos];
for (i = low + 1; i <= high; i++) {
if (a > pivot) {
p_pos++;
swap(a, p_pos, i);
}
}
swap(a, low, p_pos);
return p_pos;
}

public void quicksort(int a[], int low, int high) {
int pivot;
if (low < high) {
pivot = partition(a, low, high);
quicksort(a, low, pivot - 1);
quicksort(a, pivot + 1, high);
}

}

public static void main(String args[]) {
int vec[] = new int[] { 37, 47, 23, -5, 19, 56 };
int temp;
//选择排序法(Selection Sort)
long begin = System.currentTimeMillis();
for (int k = 0; k < 1000000; k++) {
for (int i = 0; i < vec.length; i++) {
for (int j = i; j < vec.length; j++) {
if (vec[j] > vec) {
temp = vec;
vec = vec[j];
vec[j] = temp;
}
}

}
}
long end = System.currentTimeMillis();
System.out.println("选择法用时为:" + (end - begin));
//打印排序好的结果
for (int i = 0; i < vec.length; i++) {
System.out.println(vec);
}
// 冒泡排序法(Bubble Sort)
begin = System.currentTimeMillis();
for (int k = 0; k < 1000000; k++) {
for (int i = 0; i < vec.length; i++) {
for (int j = i; j < vec.length - 1; j++) {
if (vec[j + 1] > vec[j]) {
temp = vec[j + 1];
vec[j + 1] = vec[j];
vec[j] = temp;
}
}

}
}
end = System.currentTimeMillis();
System.out.println("冒泡法用时为:" + (end - begin));
//打印排序好的结果
for (int i = 0; i < vec.length; i++) {
System.out.println(vec);
}

//插入排序法(Insertion Sort)
begin = System.currentTimeMillis();
for (int k = 0; k < 1000000; k++) {
for (int i = 1; i < vec.length; i++) {
int j = i;
while (vec[j - 1] < vec) {
vec[j] = vec[j - 1];
j--;
if (j <= 0) {
break;
}
}
vec[j] = vec;
}
}
end = System.currentTimeMillis();
System.out.println("插入法用时为:" + (end - begin));
//打印排序好的结果
for (int i = 0; i < vec.length; i++) {
System.out.println(vec);
}

//快速排序法(Quick Sort)

Sort s = new Sort();
begin = System.currentTimeMillis();
for (int k = 0; k < 1000000; k++) {
s.quicksort(vec, 0, 5);
}
end = System.currentTimeMillis();
System.out.println("快速法用时为:" + (end - begin));
//打印排序好的结果
for (int i = 0; i < vec.length; i++) {
System.out.println(vec);
}
}

}
以下是运行结果:
选择法用时为:234
56
47
37
23
19
-5
冒泡法用时为:172
56
47
37
23
19
-5
插入法用时为:78
56
47
37
23
19
-5
快速法用时为:297
56
47
37
23
19
-5*
posted @ 2006-03-06 10:16 rodney 阅读(372) | 评论 (0)编辑 收藏
 
dwg,img,iso,sub怎么打开?这个问题在google去查询一下有许多都可找到答案。我个人有过的的工具有:dwg用daemon,其它的用虚拟光驱就OK了。
posted @ 2006-03-02 09:55 rodney 阅读(757) | 评论 (0)编辑 收藏
 
因一个QQ的网友发了一个链接给我,我一点击,完了中他的套了。我的IE弹出了许多的广告,在任务栏中有连接的小图标不见了。我在设置中打开网络和拔号连接,可这里也没有呀。只是图标不见了,连接还是可以用。不知道为什么,是哪里被改了。
这可能是你的Network Connections服务被禁用了原因造成的,查看方法如下:在“运行”窗口中输入“services.msc”,然后在打开的“服务”窗口右侧服务列表中找到名称为“Network Connections”的服务,看看其状态是否为“已启动”。如果不是,那么就需要将其设置为“已启动”。
posted @ 2006-03-01 10:03 rodney 阅读(456) | 评论 (0)编辑 收藏
 

这个异常是在测试EJB的时候,程序执行到ctx.lookup("testEJB")时抛出的。由NamingException捕捉到。打印出栈轨迹是
javax.naming.NameNotFoundException: Unable to resolve 'TestEJB'. Resolved ''; remaining name 'TestEJB'
 at weblogic.jndi.internal.BasicNamingNode.newNameNotFoundException(BasicNamingNode.java:1123)
 at weblogic.jndi.internal.BasicNamingNode.lookupHere(BasicNamingNode.java:250)
 at weblogic.jndi.internal.ServerNamingNode.lookupHere(ServerNamingNode.java:171)
 at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:204)
 at weblogic.jndi.internal.WLEventContextImpl.lookup(WLEventContextImpl.java:267)
 at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:362)
 at javax.naming.InitialContext.lookup(InitialContext.java:351)
 at testejb.servlet.SrvEJB.init(SrvEJB.java:26)
 at javax.servlet.GenericServlet.init(GenericServlet.java:256)
 at weblogic.servlet.internal.StubSecurityHelper$ServletInitAction.run(StubSecurityHelper.java:265)
 at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
 at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
 at weblogic.servlet.internal.StubSecurityHelper.createServlet(StubSecurityHelper.java:61)
 at weblogic.servlet.internal.StubLifecycleHelper.createOneInstance(StubLifecycleHelper.java:58)
 at weblogic.servlet.internal.StubLifecycleHelper.<init>(StubLifecycleHelper.java:48)
 at weblogic.servlet.internal.ServletStubImpl.prepareServlet(ServletStubImpl.java:502)
 at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:224)
 at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:165)
 at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3022)
 at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
 at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
 at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:1925)
 at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:1848)
 at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1288)
 at weblogic.work.ExecuteThread.execute(ExecuteThread.java:207)
 at weblogic.work.ExecuteThread.run(ExecuteThread.java:179)
我的ejb-jar.xml文件描述如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">

<ejb-jar>
  <display-name>EJB</display-name>
  <enterprise-beans>
    <session>
      <ejb-name>TestEJB</ejb-name>
      <home>testejb.ejb.TestEJBHome</home>
      <remote>testejb.ejb.TestEJBRemote</remote>
      <ejb-class>testejb.ejb.TestEJBBean</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>
    </session>
  </enterprise-beans>
  <assembly-descriptor>
    <container-transaction>
      <method>
        <ejb-name>TestEJB</ejb-name>
        <method-name>*</method-name>
      </method>
      <trans-attribute>Required</trans-attribute>
    </container-transaction>
  </assembly-descriptor>
</ejb-jar>

weblogic-ejb-jar.xml文件描述如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN" "http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd">

<weblogic-ejb-jar>
  <weblogic-enterprise-bean>
    <ejb-name>TestEJB</ejb-name>
    <jndi-name>TestEJB</jndi-name>
  </weblogic-enterprise-bean>
</weblogic-ejb-jar>
这些配置我都写了为什么还有名字没有找到的异常呢?
请大家帮忙看看。谢谢! QQ:86322591。MSN:rodney_luo@163.com

posted @ 2006-02-20 17:24 rodney 阅读(13760) | 评论 (2)编辑 收藏
 
系统环境:
OS: Windows Server 2000 SP4
开发工具:JBuilder 2006。
WEB服务器:Weblogic9.0
数据库:DB2 V7.2
使用Type2的JDBC连接方式。因为DB2 V7.2只支持Type2与Type3的连接。
我新建了一个TestDB类,在这个类中我可以连接到DB2中,并且取出数据。可是我把这个连接的方法写到Servlet中就不能连接到该数据库中了。抛出ClassNotFoundException的异常。  请大家帮忙看,我在系统环境有设置Classpath的DB2驱动程序包。并在WEB-INF\lib目录下也有这个驱程驱动程序包。它就是在Sevelt中要抛出ClassNotFoundException的异常。。。。。
QQ:86322591
MSN: rodney_luo@163.com
Email: rodney_luo@163.com

谢谢大家。
posted @ 2006-02-17 13:17 rodney 阅读(472) | 评论 (0)编辑 收藏
 
我想各位网上的朋友常为了找不到自己合适的工具而烦吧。http://www.9iv.com/down/index.htm?eid=236712这里有你想要的一切工具软件,开发工具,商务软件。一切的软件尽在http://www.9iv.com/down/index.htm?eid=236712中。
posted @ 2006-02-15 09:46 rodney 阅读(434) | 评论 (0)编辑 收藏
 
1.查询返回结果数量的设置
  缺省的情况下,一个全文本索引查询的结果被限制为250个文档,如果你想改变查询返回
  QueryMaxResults=XXXX;
  XXXX代表一个小于5000的数,如果XXXX超过5000,查询将会变得很不稳定,我建议最好将
  2.NOTES.INI中PREFERENCES变量的设置
  在NOTES.INI中的PREFERENCES变量的值一直是个迷,LOTUS公司一直没有提供详细的说明
。直到现在,经过国内外LOTUS爱好者的研究,才弄清楚它的大体含义。其实,PREFERENCES
变量的值是一个有正负的32位WORD变量的十进制表示法,其中每一位代表一个不同的优先设置
  位位置 = 用户优先设置选择
  0 = 不详
  1 =扫描未读文档
  2 =不详
  3 =大字体
  4 =不详
  5 =将Internet URLs地址 (http//:)变为热点
  6 =不详
  7 = 只有打字机字体
  8 =单色显示
  9 = Scandinavian 校验
  10 =不详
  11 = 保存已发送邮件
  12 =发送邮件签名
  13 =发送邮件加密
  14 = Metric(1)/Imperial(0)度量
  15 =最近校验的次数
  16 = 法国包装
  17 =不详
  18 = 每隔X分钟检查一次新邮件
  19 = 使能本地后台索引
  20 = 加密保存的邮件
  21 =不详
  22 =不详
  23 =右键双击关闭窗口
  24 =位置提示
  25 =不详
  26 = 在预览框中打开文档后将文档标记为已读
  27 = 使能本地预定代理
  28 =保存发送邮件(总是提示,1=YES,0=NO)
  29 = 使新邮件提示可见
  30 =使新邮件提示可以听见
  31 =有纹理的工作台
  3.DOMINO最大限度获得系统可用内存的设置
  在NOTES.INI文件中加入以下变量:
  Platform_Statistics_Enabled=1
  强烈建议在NOTES.INI文件中加入上面一行,这样会让DOMINO可以最大限度的获得系统的
内存,提高DOMINO服务器的性能。Domino 5.0.2 (或更高版本)的这个属性支持NT和Solaris
  4.取消NOTES的缺省邮件程序地位
  大家可能都遇到过,如果NOTES被当作缺省的邮件程序时,当你点击MAILTO联接的时候,
就会启动NOTES,耗时费劲,那么怎样改变NOTES的缺省邮件程序地位呢?在NOTES.INI中加
  NotDefaultMailTo=1
  将取消NOTES的缺省邮件程序地位。
  5.用层叠地址本(cascaded address book)鉴别WEB用户
  在Domino 4.6.1以前的版本中,都可以使用层叠地址本(cascaded address book)鉴别
WEB用户,但是到了Domino 4.6.2以后,不再支持用层叠地址本鉴别WEB用户,取而代之的是
用主NAB鉴别WEB用户。为了鉴别WEB用户,我们不得不使用主地址本,不过在NOTES.INI中加
入以下行,你将会重新可以使用层叠地址本鉴别WEB用户。
  NoMABForWebNames=1
  6.在工作站上隐藏设计菜单
  如果你不想让工作站上的用户创建个人视图,可以用以下的方法隐藏设计菜单:
  NoDesignMenu=1或0
  1------隐藏设计菜单
  0------不隐藏设计菜单
  7.改变邮件到达的提示声音
  大家可能已经厌烦了LOTUS却省的邮件到达提示声音,不用急,改变一下notes.ini,你
可以使用任何的声音了。方法如下,在notes.ini中加入以下行:
  NewMailTune=[相对于NOTES DATA目录的.wav文件的完整路径].
  如:NewMailTune=c:winntmediamessage.wav
  现在你可以使用任何喜欢的声音了。
  8.使用附加的地址本
  在NOTES.INI文件中加入以下行:
  Names=NAMES.NSF,NAMES1.NSF
  NOTES将会在NAMES.NSF和NAMES1.NSF两个地址本中寻找用户。

9.设置新邮件检查时间间隔
  在NOTES.INI文件中加入以下行:
  MinNewMailPoll= 时间(分钟)
  工作站将会根据以上的设置,每隔一定时间检查服务器上的新邮件。却省的设置是15分钟
  10.指定NOTES所用内存大小
  通过在NOTES.INI中使用以下行:
  Memory_Quota = xx
  可以指定NOTES客户端使用的PC的内存大小,其中XX代表所用内存的大小,注意XX值设得
不要太小,否则会出现问题,NOTES R5比NOTES4.X需要的内存多。
  11.记录已经索引的数据库
  可以通过改变NOTES.INI设置,让日志记录已经索引的数据库。这个设置在数据库更新所
引的时候突然崩溃时非常有用。设置选项如下:
  要想记录索引数据库的视图和文件夹:
  Log_Update=2
  要想只记录索引过的数据库:
  Log_Update=1
  完全关闭更新日志
  Log_Update=0
  12.调试代理
  在NOTES.INI文件中加入以下行,你就可以调试代理了:
  DEBUG_AMGR = n ,n代表以下的数值
  r = 代理运行
  l = 代理加载
  m = 代理内存警告
  p = 代理性能状态
  e = 事件
  s = 计划安排
  c = 代理控制参数显示
  v = 详细
  * =使能以上所有选项
  13.指定运行的NOTES程序
  当你在同一台机器上安装NOTES客户端和DOMINO服务器的时候,在NOTES.INI文件中有一
项会随之变化:
  KitType=
  1 ? 客户端
  2 ? 服务器和客户端
  14.加速视图索引的速度
  在NOTES.INI文件中加入以下行,就能在一个视图首次打开时加速索引的速度:
  GOFASTER=1
  加速视图索引
  GOFASTER=0
  放慢视图索引
  15.平行运行WEB触发代理
  DominoAsynchronizeAgents = 1
  在NOTES.INI文件中加入以上行之后,可以平行的运行WEB触发的代理。
  例如,如果有一个WEBQUERYOPEN代理,同时运行这个代理的几率很大,但是NOTES不支持
同时运行同一个代理,因此,如果三个用户同时申请了运行这个代理,那么只有一个用户的申
请被批准,其余的只有等待。用了以上的设置之后,三个用户可以同时运行这个代理。
  16.将服务器窗口的内容写入一个文件
  在NOTES.INI文件中写入以下行,就可以将服务器端窗口的内容写入一个文件:   Debug_Outfile = < filename >
  在NOTES4.X中,文件名必须是DEBUG.TXT,每次服务器重新启动之后,就会产生一个文件
DEBUG1.TXT,DEBUG2.TXT等等,依次类推,DEBUG.TXT代表最新的服务器端的内容
posted @ 2006-01-16 16:05 rodney 阅读(1074) | 评论 (0)编辑 收藏
 
初次接触IBM 的WEbsphere产品系列。大家要注意的几个地方是在配置与编程程序。一在编程时EJB的在调用时的lookup("java:comp/env/JNDIEJB")这个名字一定要与EJB的配置描述符一样,有区分大小写。同时最好与BEAN的名字也一样。二。在用连接池编写程序时的JNDI也一样要加上lookup("java:comp/env/JNDIName")这里的JNDI名是在配置连接池指定的JNDI,也有区分大小写。在配置WEB,EJB应用程序时这两个程序可以分开配置。但EJB的配置时会多几步,要把Enteprice Bean这个复选框选上。
posted @ 2005-12-28 09:26 rodney 阅读(761) | 评论 (0)编辑 收藏
 
java.rmi.RemoteException: Transaction Rolledback.; nested exception is: 
	weblogic.transaction.internal.TimedOutException: Transaction timed out after 32 seconds 
Name=[EJB testpool.EJBPoolBean.isLogin(java.lang.String,java.lang.String)],Xid=BEA1-0001D529A50E7F28EDB9(10061327),Status=Active,numRepliesOwedMe=0,numRepliesOwedOthers=0,seconds since begin=32,seconds left=30,activeThread=Thread[ExecuteThread: '13' for queue: 'weblogic.kernel.Default',5,Thread Group for Queue: 'weblogic.kernel.Default'],XAServerResourceInfo[weblogic.jdbc.wrapper.JTSXAResourceImpl]=(ServerResourceInfo[weblogic.jdbc.wrapper.JTSXAResourceImpl]=(state=started,assigned=none),xar=weblogic.jdbc.wrapper.JTSXAResourceImpl@1304e60),SCInfo[mydomain+myserver]=(state=active),properties=({weblogic.transaction.name=[EJB testpool.EJBPoolBean.isLogin(java.lang.String,java.lang.String)], weblogic.jdbc=t3://192.168.1.98:7001}),OwnerTransactionManager=ServerTM[ServerCoordinatorDescriptor=(CoordinatorURL=myserver+192.168.1.98:7001+mydomain+t3+, XAResources={},NonXAResources={})],CoordinatorURL=myserver+192.168.1.98:7001+mydomain+t3+)
	at weblogic.rmi.internal.ServerRequest.sendReceive(ServerRequest.java:186)
	at weblogic.rmi.cluster.ReplicaAwareRemoteRef.invoke(ReplicaAwareRemoteRef.java:284)
	at weblogic.rmi.cluster.ReplicaAwareRemoteRef.invoke(ReplicaAwareRemoteRef.java:244)
	at testpool.EJBPool_isb7ao_EOImpl_811_WLStub.isLogin(Unknown Source)
	at testpool.SrvLogin.doPost(SrvLogin.java:62)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
	at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1053)
	at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:387)
	at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:305)
	at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:6310)
	at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:317)
	at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:118)
	at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3622)
	at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2569)
	at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:197)
	at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:170)
Caused by: weblogic.transaction.internal.TimedOutException: Transaction timed out after 32 seconds 
Name=[EJB testpool.EJBPoolBean.isLogin(java.lang.String,java.lang.String)],Xid=BEA1-0001D529A50E7F28EDB9(10061327),Status=Active,numRepliesOwedMe=0,numRepliesOwedOthers=0,seconds since begin=32,seconds left=30,activeThread=Thread[ExecuteThread: '13' for queue: 'weblogic.kernel.Default',5,Thread Group for Queue: 'weblogic.kernel.Default'],XAServerResourceInfo[weblogic.jdbc.wrapper.JTSXAResourceImpl]=(ServerResourceInfo[weblogic.jdbc.wrapper.JTSXAResourceImpl]=(state=started,assigned=none),xar=weblogic.jdbc.wrapper.JTSXAResourceImpl@1304e60),SCInfo[mydomain+myserver]=(state=active),properties=({weblogic.transaction.name=[EJB testpool.EJBPoolBean.isLogin(java.lang.String,java.lang.String)], weblogic.jdbc=t3://192.168.1.98:7001}),OwnerTransactionManager=ServerTM[ServerCoordinatorDescriptor=(CoordinatorURL=myserver+192.168.1.98:7001+mydomain+t3+, XAResources={},NonXAResources={})],CoordinatorURL=myserver+192.168.1.98:7001+mydomain+t3+)
	at weblogic.transaction.internal.ServerTransactionImpl.wakeUp(ServerTransactionImpl.java:1492)
	at weblogic.transaction.internal.ServerTransactionManagerImpl.processTimedOutTransactions(ServerTransactionManagerImpl.java:1071)
	at weblogic.transaction.internal.TransactionManagerImpl.wakeUp(TransactionManagerImpl.java:1805)
	at weblogic.transaction.internal.ServerTransactionManagerImpl.wakeUp(ServerTransactionManagerImpl.java:988)
	at weblogic.transaction.internal.WLSTimer.trigger(WLSTimer.java:31)
	at weblogic.time.common.internal.ScheduledTrigger.run(ScheduledTrigger.java:243)
	at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:317)
	at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:118)
	at weblogic.time.common.internal.ScheduledTrigger.executeLocally(ScheduledTrigger.java:229)
	at weblogic.time.common.internal.ScheduledTrigger.execute(ScheduledTrigger.java:223)
	... 2 more
在程序中运行都没有出错。这个TimedOutException:是执行时间超时的原理。要在哪里设置这个值?
问题的解决是在配置连接池的地方有一个高级设置:Click Hide展开后把连接持续时间设长一此。就可以了。
posted @ 2005-12-23 14:51 rodney 阅读(2186) | 评论 (0)编辑 收藏
 

java.sql.SQLException: 调用中无效的参数这个错误是在结果集循环取出是抛出的。我不明白的是,用连接池才会抛出这个错,用其它的连接就不会?在Weblogic中测试连接池也没有问题。请问这是为什么?代码在下面:
public boolean isLogin(String uid, String pwd) {
    boolean isLogin = false;
    Connection conn = this.getConnection();
    if (conn != null) {
      String sql =
          "select username,pwd from wasuserinfor where userName=? and pwd=?";
      try {
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setString(1, uid);
        ps.setString(2, pwd);
        ResultSet rs = ps.getResultSet();
        while (rs.next()) {
          String userNaem = rs.getString("USERNAME");
          String password = rs.getString("PWD");
          isLogin = true;
        }
      }
      catch (SQLException ex) {
        ex.printStackTrace();
      }
      finally {
        if (conn != null) {
          try {
            conn.close();
          }
          catch (SQLException ex1) {
            ex1.printStackTrace();
          }
        }
      }
    }
    return isLogin;
  }

  private Connection getConnection() {
    Object obj = null;
    try {
      Context ctx = new InitialContext();
      DataSource ds = (DataSource) ctx.lookup("jdbc/oracle");
      return ds.getConnection();
    }
    catch (SQLException ex) {
      return null;
    }
    catch (NamingException ex) {
      return null;
    }
  }
解决办法是看了代码:ResultSet rs = ps.getResultSet();
之前一个要先执行ps.executeQuery();这样就不会有错了。

posted @ 2005-12-23 14:31 rodney 阅读(426) | 评论 (0)编辑 收藏
 
现在大家都在学习JAVA,WEBLOGIC,IBM的WEBSPHERE 系列产品。如果上QQ方便的朋友可以加入18750476群,这是一个不错的学习交流群。特别是IBM的那一套WEBSPHERE在国内的群很少这方面的交流学习。
posted @ 2005-12-21 09:09 rodney 阅读(340) | 评论 (0)编辑 收藏
 
在java中要将一个字符串的中$符号去除。我是这样写的:
String tmp = "-$125402.00";
tmp.replaceAll("$","");
可是执行去来的结果并没有把$去除。后来找资料才发现要这样写
tmp.replaceAll("\\$","")才可以。
posted @ 2005-11-29 11:10 rodney 阅读(3176) | 评论 (0)编辑 收藏
 
把java中的Vector,Hashtable,List等数类型转换成javaScript的数组。在这里用到的是一个StringBuffer.具体的实现看下面的代码:
public String getArray(Vector v){
  if (v == null || v.size()==0){
   return "";
  }
  int i=0;
  Hashtable hash = null;
  StringBuffer sb = new StringBuffer("var arrmake = new Array(");
  try{
   for(i=0; i<v.size(); i++){
    hash = (Hashtable)v.elementAt(i);
    String tmp_make = hash.get("code").toString();    
    if(i=1){
     sb.append("'"+tmp_make+"'");     
    }else if(i>1){
     sb.append("'"+tmp_make+"',");
    }    
   }
   String test = sb.toString();
   if (i>1){
    test = test.substring(0,test.length()-1);
   }
   sb.append(test+");");
  }catch(Exception e){
   e.printStackTrace();
  }  
  return sb.toString();
 }
要注意这里一定要用try{}catch(){}因为在转换过程中可能会出错,所以用try{}catch(){}把异常抛出。
在javascript中怎么用这个数组呢?
String arrMake = getArray(vecMake);
<script language="javaScript">
 <%=arrMake%>
</script>
OK.
posted @ 2005-11-22 11:11 rodney 阅读(1345) | 评论 (0)编辑 收藏
 
我写了一个这样的SQL语句 "select column1,column2 into vara, varb from tableName" ,可在PL/SQL执行时出现缺失关键字的错误。注意这里的关键字into。这个关键字是在写function & produce时把相应的字段值赋值变量。不可以单独拿出来执行。还要注意一点sql的解释是从后面开始执行的。
posted @ 2005-11-11 14:33 rodney 阅读(323) | 评论 (0)编辑 收藏
 
java.lang.NumberFormatException: For input string: ""
java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
java.lang.Integer.parseInt(Integer.java:489)
以上的错误是因为将一个空值要强制转换成int型。为什么会是一个空值呢?是因为在JSP中form的TEXT没有输入值传到servlet中。servlet是用Integer.parseInt(request.getParameter("vehFrom"))来取JSP中的值 的。要解决这个问题很简单,可是初学者常会遇到这样的问题。废话少说还是说怎么解决了的吧。
只要在servlet中将这个值做一个空值处理。
if((jcf.retuPara(request,"vehFrom")).length()<=0){
      vehFromNo = 0;
     }else{
      vehFromNo = Integer.parseInt(jcf.retuPara(request,"vehFrom"));
     }
要注意一点是JSP传到servlet中如果没有输入值是NULL值。我这里用了一个自己写的retuPara()方法是处理NULL的。把NULL处理成“”。
好了,搞定。
posted @ 2005-11-11 09:42 rodney 阅读(1183) | 评论 (0)编辑 收藏
 
&lt;P&gt;&lt;A href=&quot;http://www.8qu.net/register.asp?net=rodneyluo&quot;&gt;http://www.8qu.net/register.asp?net=rodneyluo&lt;/A&gt;&lt;BR&gt;我也是在论坛上看了别人的帖子才注册的!我已经实践过了,换了20个Q币,真的很好用,向大家推荐!!!! &lt;/P&gt; &lt;P&gt;以前你也可能看过这样的广告,这次你真的不要再错过了!! &lt;BR&gt;其实和很多人一样,我对网络赚钱由最初的抵触(因为大家都说那是骗人的)到半信半疑(因为有朋友说网赚&lt;/P&gt; &lt;P&gt;行的,但要看是什么样的网赚)再到确信(因为此时自己亲身赚到了,其他的不知道,但通宝确实是真的)。 &lt;/P&gt; &lt;P&gt;下面介绍一下方法:只要到 &lt;A href=&quot;http://www.8qu.net/register.asp?net=rodneyluo&quot;&gt;http://www.8qu.net/register.asp?net=rodneyluo&lt;/A&gt;(那里有更加详细的介绍)注&lt;/P&gt; &lt;P&gt;册后,免费下载一个软件:“通宝 ”(tongbao.exe) 。下载后打开,点击“登录”--“开始泡分”,这样就&lt;/P&gt; &lt;P&gt;开始赚Q币了 ,挂机就可以赚Q币了,跟挂QQ差不多。 &lt;BR&gt;每5分钟自动增加一积分 。 &lt;/P&gt; &lt;P&gt;别看到要写银行帐号就吓到了,其实你可以不填(建议填一下,因为当你达到支付的条件时就可以确确时时的&lt;/P&gt; &lt;P&gt;收到人民币),选择要Q币(只需要输入QQ号码) &lt;/P&gt; &lt;P&gt;注册地址:&lt;A href=&quot;http://www.8qu.net/register.asp?net=rodneyluo&quot;&gt;http://www.8qu.net/register.asp?net=rodneyluo&lt;/A&gt;&lt;/P&gt; &lt;P&gt;推荐使用八趣TongBao的理由: &lt;/P&gt; &lt;P&gt;一. 无需任何点击.泡时间积分,就像网易POPO一样.对工作没有任何影响.不象Newsbar(新闻时报)或SABar等&lt;/P&gt; &lt;P&gt;要及时保存积分. &lt;BR&gt;二.真正的无干扰.隐藏时只在任务栏中有一个小“铜钱”,只占1M内存,对于动辄256,512甚至上G内存的机来&lt;/P&gt; &lt;P&gt;说根本就九牛一毛,对你上网干其他事没有干扰。 &lt;BR&gt;三. 绿色小软件无需安装. &lt;BR&gt;四. 无需一分钱投入.免费注册使用,因而没有任何风险(要自己投资钱的话我是肯定不会去干的), 而且信誉&lt;/P&gt; &lt;P&gt;绝对没问题,要有问题也不可能存在这么多年。我的亲身经历就是 &lt;BR&gt;五.下线数与积分兑现金.TongBao支持五级下线:10%,5%,3%,3%,3%。 &lt;BR&gt;按每月推荐10名下线,你的下线每月又推荐10名下线,以公司承诺每1000个积分最低付费5元计算(实际会超过&lt;/P&gt; &lt;P&gt;5元),你的月收入分别为(按每人每月1000个积分计算): &lt;BR&gt;第1个月收入: 5元; &lt;BR&gt;第2个月收入: 5 +5 =10元 &lt;BR&gt;第3个月收入: 5 +5 +25 =35元; &lt;BR&gt;第4个月收入: 5 +5 +25 +150 =185元; &lt;BR&gt;第5个月收入: 5 +5 +25 +150 +1500 =1685元; &lt;BR&gt;第6个月收入:5 +5 +25 +150 +1500 +15000 =16685元; &lt;BR&gt;说实话,其实这是理想的算法,实际上是很难达到的,因为不能保证每个人都认真去泡分和发展下线 ,但是你&lt;/P&gt; &lt;P&gt;认真点去做的话,几个月以后每个月赚几百绝对没问题,而且这将稳定增长的,这已经相当不错了,至少我觉&lt;/P&gt; &lt;P&gt;得是这样!!! &lt;/P&gt; &lt;P&gt;当然,如果单独一个人只是挂机(一天只给挂四小时),一个月也就7元,但这个7元比Newsbar和SABar一个月的&lt;/P&gt; &lt;P&gt;7元容易赚多了,不需任何点击。如果有下线,收入见上面算式。要是三个一起挂就更加不用说了。 &lt;/P&gt; &lt;P&gt;八趣TongBao免费注册:(&lt;A href=&quot;http://www.8qu.net/register.asp?net=rodneyluo&quot;&gt;http://www.8qu.net/register.asp?net=rodneyluo&lt;/A&gt;强烈推荐) &lt;BR&gt;  &lt;BR&gt;我的使用心得。如果不是网虫,一定得想办法发展十来个下线,最简单的方法就是到论坛发贴,关键是这东西&lt;/P&gt; &lt;P&gt;可以赚QB,有很多人愿意挂的。我现在已经发展了131个下线了。还有一点,我们从下线那里提成,但下线自己&lt;/P&gt; &lt;P&gt;的点数是不会变的。所以越多人加进来,你会越多的收益,并不会影响他们。到以后,自己上网时记得就挂,&lt;/P&gt; &lt;P&gt;不记得就算了。如果下线多,有一天可能收到100元或1000元,也可以补贴一下上网费,不能太浪费宽带吧,有&lt;/P&gt; &lt;P&gt;收获当做一种意外不是很好吗?! &lt;/P&gt; &lt;P&gt;关键的关键,没事多来发发贴,多拉点人成你的下线,就靠自己泡效果不明显,一个月才10来个QB。如果下线&lt;/P&gt; &lt;P&gt;多了,自己都不用挂,吃提成都够了。大家一起来挂吧,就跟挂QQ似的,全民一起挂,我靠,最后加入的也有1&lt;/P&gt; &lt;P&gt;0块一个月,那些下线多的真得会发死哎~~呵呵。注册八趣&lt;A href=&quot;http://www.8qu.net/register.asp?net=iamcacy&quot;&gt;http://www.8qu.net/register.asp?net=iamcacy&lt;/A&gt;你&lt;/P&gt; &lt;P&gt;赚钱,我受益!挂在网上不费事,月入一千也是你,还等什么快快成为第一批注册者,让更多的人成为你的下&lt;/P&gt; &lt;P&gt;线!具体介绍请访问&lt;A href=&quot;http://www.8qu.net/register.asp?net=iamcacy&quot;&gt;http://www.8qu.net/register.asp?net=iamcacy&lt;/A&gt;如有疑问请加379588056听我在线询问!&lt;/P&gt; &lt;P&gt;决不骗你! &lt;/P&gt; &lt;P&gt;还有就是尽量去发BT种子发展下线,象我一样,为他人服务的同时进行宣传,效果很好!!! &lt;BR&gt;双管齐下还愁发展不了下线,哈哈,到时就坐着等钱拉, &lt;/P&gt; &lt;P&gt;持之以恒,相信收获的一天很快到来!!(对没有恒心,急功近利的不推荐使用,因为至少要几个月才能看到&lt;/P&gt; &lt;P&gt;非常明显的效果) &lt;BR&gt;我建有一个群,交流使用心得和解答疑难:1653115,想加的在验证的时候写上:通宝用户 &lt;BR&gt;有疑惑的也可以加进来再详细咨询。&lt;/P&gt;
posted @ 2005-11-04 21:15 rodney 阅读(791) | 评论 (1)编辑 收藏
 
The checkBox 在html的form中要把值传递到servlet中进行处理。这时如果checkbox的属性checked = false时,在servlet取checkbox的value是一个NULL值.只有checked = true时才能取到value.
还因该注意一点如果有value是NULL时做String.equalsIgnoreCase("") or String.equals("")都会抛出空指异常。页面上显示500号错误。请小心使用。
posted @ 2005-11-03 17:10 rodney 阅读(1754) | 评论 (0)编辑 收藏
 
快到公司了,要过一个红绿灯,我等绿灯一亮,我刚要过马路,这时一个男子骑着自己车把我的自行车前轮撞得不成样子。这时我们也没有说什么,同时找一个家修理店,要把自行车修好。这个修车的老板一看是被撞的车子说不能修了。只能换一个轮子,那男子问要多少钱,老板血口大开说25元不能少。我一听就知道这个老板要”杀人“。那男子说他出15元,因为他身上只有这么多钱。那还要10元怎么办要我自己出不成我说。于是两人在这家店门口小炒,说什么他不知道我要过马路,我自行是旧的,换一个新的被我占便宜了。我很生气说:“你换不换是你家的事,总之你一定对你今天所做的事情负责。”后来他把自行车上锁就走了。我追上去,看来他的公司是这附近。我们走近一家小院子他的几个同事走过了,问我想做什么?我气了。把事情说了一遍。后来看到他是同事都在搬东西。想过去是一个做苦力的,挣钱也不容易。还是他出15,我出10。开始就这么解决就不会有那么多的口头争吵了。
posted @ 2005-10-20 09:55 rodney 阅读(359) | 评论 (0)编辑 收藏
 
Calendar lCal = Calendar.getInstance(); 
String year = tod.substring(6);  //tod 是DD/MM/YYYY的格式的日期。
String month = tod.substring(3,5);
 lCal.set(FormatFunctions.s2i(year), FormatFunctions.s2i(month), 1); 调用一个共用方法将字符串转换成整型。
     lCal.add(Calendar.MONTH, 0);
     lCal.add(Calendar.DATE, -1);
      SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
      tod = formatter.format(lCal.getTime();
posted @ 2005-10-14 14:56 rodney 阅读(2250) | 评论 (0)编辑 收藏
 
中文机的日期如果是1月2005 SELECT TO_CHAR(SYSDATE,'MONYYYY') FROM DUAL
英文机的日期如果是1月2005会显示成JAN2005.
从上面可以看出oracle在格式转换中用MON的格式是取某个月的单词的前三个字符。但是在中文机上有从SQL中取出来是1?空格2005一共是占七个字符。而英文机上也是占七个字符。只是在显示时的效果不一样。中:1?空格2005,英文机上:JAN2005.
posted @ 2005-10-14 14:43 rodney 阅读(360) | 评论 (0)编辑 收藏
 

如果有一个程序是这样:(PB的源代码)
IF NOT IsNull(ld_from_date) AND NOT IsNull(ld_date) THEN
 ls_sql_where = ls_sql_where + &
 " Trunc(~"CITYNET_INTERFACE~".~"REQUESTED_PICKUP_DTM~") between TO_DATE('" + &
 String(ld_from_date, 'dd/mm/yyyy') + &
 "', 'dd/mm/yyyy') and TO_DATE('" + &
 String(ld_date, 'dd/mm/yyyy') + "', 'dd/mm/yyyy')" + " AND "
 ls_query_criteria = ls_query_criteria + " Trip Date between " + String(ld_from_date,'DD/MM/YYYY') + &
  " AND " + String(ld_date,'DD/MM/YYYY')
END IF

IF NOT IsNull(ld_from_date) AND IsNull(ld_date) THEN
 ls_sql_where = ls_sql_where + &
 " Trunc(~"CITYNET_INTERFACE~".~"REQUESTED_PICKUP_DTM~") >= TO_DATE('" + &
 String(ld_from_date, 'dd/mm/yyyy') + "', 'dd/mm/yyyy')" + " AND "
 ls_query_criteria = ls_query_criteria + " Trip Date >= " + String(ld_from_date,'DD/MM/YYYY')
END IF

IF IsNull(ld_from_date) AND NOT IsNull(ld_date) THEN
 ls_sql_where = ls_sql_where + &
 " Trunc(~"CITYNET_INTERFACE~".~"REQUESTED_PICKUP_DTM~") <= TO_DATE('" + &
 String(ld_date, 'dd/mm/yyyy') + "', 'dd/mm/yyyy')" + " AND "
 ls_query_criteria = ls_query_criteria + " Trip Date <= " + String(ld_date,'DD/MM/YYYY')
END IF
把上面的代码用SQL的查询语句来实行。
这时我用到了一个between运算符,这个运算符会包括它后的两个入参:
如:select table.A from table where table.A between 5 and 10.也就是说这时的条件A>=5 and A<= 10的记录。

posted @ 2005-10-11 13:52 rodney 阅读(781) | 评论 (0)编辑 收藏
 
我的report server是IBM产品,我通过URL传递参数时http://work-5:80/reports/rwservlet?mykeys2&desType=cache&desFormat=PDF&report=/data1/ifms/xmlreports/IF3050R.xml&printid=SANCP2&pgmID=IF3050R
但在&变量名之后加了空格,结果report不能打印。然后我把URL中的每个空格都去除。可以了。当我不知道URL为什么不能有空格,HTTP协议是怎么处理空格的。希望有哪位高手能给一个指点。
posted @ 2005-10-11 10:45 rodney 阅读(3413) | 评论 (3)编辑 收藏
 
1. 配置系统管理(Admin Web Application)
大多数商业化的J2EE服务器都提供一个功能强大的管理界面,且大都采用易于理解的Web应用界面。Tomcat按照自己的方式,同样提供一个成熟的管理工具,并且丝毫不逊于那些商业化的竞争对手。Tomcat的Admin Web Application最初在4.1版本时出现,当时的功能包括管理context、data source、user和group等。当然也可以管理像初始化参数,user、group、role的多种数据库管理等。在后续的版本中,这些功能将得到很大的扩展,但现有的功能已经非常实用了。

Admin Web Application被定义在自动部署文件:CATALINA_BASE/webapps/admin.xml 。
(译者注:CATALINA_BASE即tomcat安装目录下的server目录)

你必须编辑这个文件,以确定Context中的docBase参数是绝对路径。也就是说,CATALINA_BASE/webapps/admin.xml 的路径是绝对路径。作为另外一种选择,你也可以删除这个自动部署文件,而在server.xml文件中建立一个Admin Web Application的context,效果是一样的。你不能管理Admin Web Application这个应用,换而言之,除了删除CATALINA_BASE/webapps/admin.xml ,你可能什么都做不了。

如果你使用UserDatabaseRealm(默认),你将需要添加一个user以及一个role到CATALINA_BASE/conf/tomcat-users.xml 文件中。你编辑这个文件,添加一个名叫“admin”的role 到该文件中,如下:

<role name="admin"/>

你同样需要有一个用户,并且这个用户的角色是“admin”。象存在的用户那样,添加一个用户(改变密码使其更加安全):

<user name="admin" password="deep_dark_secret" roles="admin"/>

当你完成这些步骤后,请重新启动Tomcat,访问http://localhost:8080/admin,你将看到一个登录界面。Admin Web Application采用基于容器管理的安全机制,并采用了Jakarta Struts框架。一旦你作为“admin”角色的用户登录管理界面,你将能够使用这个管理界面配置Tomcat。

2.配置应用管理(Manager Web Application)
Manager Web Application让你通过一个比Admin Web Application更为简单的用户界面,执行一些简单的Web应用任务。

Manager Web Application被被定义在一个自动部署文件中:

CATALINA_BASE/webapps/manager.xml 。

你必须编辑这个文件,以确保context的docBase参数是绝对路径,也就是说CATALINA_HOME/server/webapps/manager的绝对路径。
(译者注:CATALINA_HOME即tomcat安装目录)

如果你使用的是UserDatabaseRealm,那么你需要添加一个角色和一个用户到CATALINA_BASE/conf/tomcat-users.xml文件中。接下来,编辑这个文件,添加一个名为“manager”的角色到该文件中:

<role name=”manager”>

你同样需要有一个角色为“manager”的用户。像已经存在的用户那样,添加一个新用户(改变密码使其更加安全):

<user name="manager" password="deep_dark_secret" roles="manager"/>

然后重新启动Tomcat,访问http://localhost/manager/list,将看到一个很朴素的文本型管理界面,或者访问http://localhost/manager/html/list,将看到一个HMTL的管理界面。不管是哪种方式都说明你的Manager Web Application现在已经启动了。

Manager application让你可以在没有系统管理特权的基础上,安装新的Web应用,以用于测试。如果我们有一个新的web应用位于/home/user/hello下在,并且想把它安装到 /hello下,为了测试这个应用,我们可以这么做,在第一个文件框中输入“/hello”(作为访问时的path),在第二个文本框中输入“file:/home/user/hello”(作为Config URL)。

Manager application还允许你停止、重新启动、移除以及重新部署一个web应用。停止一个应用使其无法被访问,当有用户尝试访问这个被停止的应用时,将看到一个503的错误——“503 - This application is not currently available”。

移除一个web应用,只是指从Tomcat的运行拷贝中删除了该应用,如果你重新启动Tomcat,被删除的应用将再次出现(也就是说,移除并不是指从硬盘上删除)。

3.部署一个web应用
有两个办法可以在系统中部署web服务。
1> 拷贝你的WAR文件或者你的web应用文件夹(包括该web的所有内容)到$CATALINA_BASE/webapps目录下。
2> 为你的web服务建立一个只包括context内容的XML片断文件,并把该文件放到$CATALINA_BASE/webapps目录下。这个web应用本身可以存储在硬盘上的任何地方。

如果你有一个WAR文件,你若想部署它,则只需要把该文件简单的拷贝到CATALINA_BASE/webapps目录下即可,文件必须以“.war”作为扩展名。一旦Tomcat监听到这个文件,它将(缺省的)解开该文件包作为一个子目录,并以WAR文件的文件名作为子目录的名字。接下来,Tomcat将在内存中建立一个context,就好象你在server.xml文件里建立一样。当然,其他必需的内容,将从server.xml中的DefaultContext获得。

部署web应用的另一种方式是写一个Context XML片断文件,然后把该文件拷贝到CATALINA_BASE/webapps目录下。一个Context片断并非一个完整的XML文件,而只是一个context元素,以及对该应用的相应描述。这种片断文件就像是从server.xml中切取出来的context元素一样,所以这种片断被命名为“context片断”。

举个例子,如果我们想部署一个名叫MyWebApp.war的应用,该应用使用realm作为访问控制方式,我们可以使用下面这个片断:

<!--  
 Context fragment for deploying MyWebApp.war  
-->
<Context path="/demo" docBase="webapps/MyWebApp.war"
        debug="0" privileged="true">
 <Realm className="org.apache.catalina.realm.UserDatabaseRealm"                
        resourceName="UserDatabase"/>
</Context>

把该片断命名为“MyWebApp.xml”,然后拷贝到CATALINA_BASE/webapps目录下。

这种context片断提供了一种便利的方法来部署web应用,你不需要编辑server.xml,除非你想改变缺省的部署特性,安装一个新的web应用时不需要重启动Tomcat。


4.配置虚拟主机(Virtual Hosts)
关于server.xml中“Host”这个元素,只有在你设置虚拟主机的才需要修改。虚拟主机是一种在一个web服务器上服务多个域名的机制,对每个域名而言,都好象独享了整个主机。实际上,大多数的小型商务网站都是采用虚拟主机实现的,这主要是因为虚拟主机能直接连接到Internet并提供相应的带宽,以保障合理的访问响应速度,另外虚拟主机还能提供一个稳定的固定IP。

基于名字的虚拟主机可以被建立在任何web服务器上,建立的方法就是通过在域名服务器(DNS)上建立IP地址的别名,并且告诉web服务器把去往不同域名的请求分发到相应的网页目录。因为这篇文章主要是讲Tomcat,我们不准备介绍在各种操作系统上设置DNS的方法,如果你在这方面需要帮助,请参考《DNS and Bind》一书,作者是Paul Albitz and Cricket Liu (O'Reilly)。为了示范方便,我将使用一个静态的主机文件,因为这是测试别名最简单的方法。
在Tomcat中使用虚拟主机,你需要设置DNS或主机数据。为了测试,为本地IP设置一个IP别名就足够了,接下来,你需要在server.xml中添加几行内容,如下:

<Server port="8005" shutdown="SHUTDOWN" debug="0">
 <Service name="Tomcat-Standalone">
   <Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8080" minProcessors="5" maxProcessors="75"
enableLookups="true" redirectPort="8443"/>
   <Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8443" minProcessors="5" maxProcessors="75"
acceptCount="10" debug="0" scheme="https" secure="true"/>
     <Factory className="org.apache.coyote.tomcat4.CoyoteServerSocketFactory"
clientAuth="false" protocol="TLS" />
   </Connector>
   <Engine name="Standalone" defaultHost="localhost" debug="0">
     <!-- This Host is the default Host -->
     <Host name="localhost" debug="0" appBase="webapps"
     unpackWARs="true" autoDeploy="true">
       <Context path="" docBase="ROOT" debug="0"/>
       <Context path="/orders" docBase="/home/ian/orders" debug="0"
                      reloadable="true" crossContext="true">
       </Context>
     </Host>

     <!-- This Host is the first "Virtual Host": www.example.com -->
     <Host name="www.example.com" appBase="/home/example/webapp">
       <Context path="" docBase="."/>
     </Host>

   </Engine>
 </Service>
</Server>

Tomcat的server.xml文件,在初始状态下,只包括一个虚拟主机,但是它容易被扩充到支持多个虚拟主机。在前面的例子中展示的是一个简单的server.xml版本,其中粗体部分就是用于添加一个虚拟主机。每一个Host元素必须包括一个或多个context元素,所包含的context元素中必须有一个是默认的context,这个默认的context的显示路径应该为空(例如,path=””)。

5.配置基础验证(Basic Authentication)
容器管理验证方法控制着当用户访问受保护的web应用资源时,如何进行用户的身份鉴别。当一个web应用使用了Basic Authentication(BASIC参数在web.xml文件中auto-method元素中设置),而有用户访问受保护的web应用时,Tomcat将通过HTTP Basic Authentication方式,弹出一个对话框,要求用户输入用户名和密码。在这种验证方法中,所有密码将被以64位的编码方式在网络上传输。

注意:使用Basic Authentication通过被认为是不安全的,因为它没有强健的加密方法,除非在客户端和服务器端都使用HTTPS或者其他密码加密码方式(比如,在一个虚拟私人网络中)。若没有额外的加密方法,网络管理员将能够截获(或滥用)用户的密码。但是,如果你是刚开始使用Tomcat,或者你想在你的web应用中测试一下基于容器的安全管理,Basic Authentication还是非常易于设置和使用的。只需要添加<security-constraint>和<login-config>两个元素到你的web应用的web.xml文件中,并且在CATALINA_BASE/conf/tomcat-users.xml 文件中添加适当的<role>和<user>即可,然后重新启动Tomcat。

下面例子中的web.xml摘自一个俱乐部会员网站系统,该系统中只有member目录被保护起来,并使用Basic Authentication进行身份验证。请注意,这种方式将有效的代替Apache web服务器中的.htaccess文件。

<!--
 Define the Members-only area, by defining
 a "Security Constraint" on this Application, and
 mapping it to the subdirectory (URL) that we want
 to restrict.
-->
<security-constraint>
 <web-resource-collection>
   <web-resource-name>
     Entire Application
   </web-resource-name>
   <url-pattern>/members/*</url-pattern>
 </web-resource-collection>
 <auth-constraint>
     <role-name>member</role-name>
 </auth-constraint>
</security-constraint>
<!-- Define the Login Configuration for this Application -->
<login-config>
 <auth-method>BASIC</auth-method>
 <realm-name>My Club Members-only Area</realm-name>
</login-config>

6.配置单点登录(Single Sign-On)
一旦你设置了realm和验证的方法,你就需要进行实际的用户登录处理。一般说来,对用户而言登录系统是一件很麻烦的事情,你必须尽量减少用户登录验证的次数。作为缺省的情况,当用户第一次请求受保护的资源时,每一个web应用都会要求用户登录。如果你运行了多个web应用,并且每个应用都需要进行单独的用户验证,那这看起来就有点像你在与你的用户搏斗。用户们不知道怎样才能把多个分离的应用整合成一个单独的系统,所有他们也就不知道他们需要访问多少个不同的应用,只是很迷惑,为什么总要不停的登录。

Tomcat 4的“single sign-on”特性允许用户在访问同一虚拟主机下所有web应用时,只需登录一次。为了使用这个功能,你只需要在Host上添加一个SingleSignOn Valve元素即可,如下所示:

<Valve className="org.apache.catalina.authenticator.SingleSignOn"
      debug="0"/>

在Tomcat初始安装后,server.xml的注释里面包括SingleSignOn Valve配置的例子,你只需要去掉注释,即可使用。那么,任何用户只要登录过一个应用,则对于同一虚拟主机下的所有应用同样有效。

使用single sign-on valve有一些重要的限制:
1> value必须被配置和嵌套在相同的Host元素里,并且所有需要进行单点验证的web应用(必须通过context元素定义)都位于该Host下。
2> 包括共享用户信息的realm必须被设置在同一级Host中或者嵌套之外。
3> 不能被context中的realm覆盖。
4> 使用单点登录的web应用最好使用一个Tomcat的内置的验证方式(被定义在web.xml中的<auth-method>中),这比自定义的验证方式强,Tomcat内置的的验证方式包括basic、digest、form和client-cert。
5> 如果你使用单点登录,还希望集成一个第三方的web应用到你的网站中来,并且这个新的web应用使用它自己的验证方式,而不使用容器管理安全,那你基本上就没招了。你的用户每次登录原来所有应用时需要登录一次,并且在请求新的第三方应用时还得再登录一次。当然,如果你拥有这个第三方web应用的源码,而你又是一个程序员,你可以修改它,但那恐怕也不容易做。
6> 单点登录需要使用cookies。

7.配置用户定制目录(Customized User Directores)
一些站点允许个别用户在服务器上发布网页。例如,一所大学的学院可能想给每一位学生一个公共区域,或者是一个ISP希望给一些web空间给他的客户,但这又不是虚拟主机。在这种情况下,一个典型的方法就是在用户名前面加一个特殊字符(~),作为每位用户的网站,比如:

http://www.cs.myuniversity.edu/~username
http://members.mybigisp.com/~username

Tomcat提供两种方法在主机上映射这些个人网站,主要使用一对特殊的Listener元素。Listener的className属性应该是org.apache.catalina.startup.UserConfig,userClass属性应该是几个映射类之一。如果你的系统是Unix,它将有一个标准的/etc/passwd文件,该文件中的帐号能够被运行中的Tomcat很容易的读取,该文件指定了用户的主目录,使用PasswdUserDatabase 映射类。

<Listener className="org.apache.catalina.startup.UserConfig"
directoryName="public_html"
userClass="org.apache.catalina.startup.PasswdUserDatabase"/>

web文件需要放置在像/home/users/ian/public_html 或者 /users/jbrittain/public_html一样的目录下面。当然你也可以改变public_html 到其他任何子目录下。

实际上,这个用户目录根本不一定需要位于用户主目录下里面。如果你没有一个密码文件,但你又想把一个用户名映射到公共的像/home一样目录的子目录里面,则可以使用HomesUserDatabase类。

<Listener className="org.apache.catalina.startup.UserConfig"
directoryName="public_html" homeBase="/home"
userClass="org.apache.catalina.startup.HomesUserDatabase"/>

这样一来,web文件就可以位于像/home/ian/public_html 或者 /home/jasonb/public_html一样的目录下。这种形式对Windows而言更加有利,你可以使用一个像c:\home这样的目录。

这些Listener元素,如果出现,则必须在Host元素里面,而不能在context元素里面,因为它们都用应用于Host本身。


8.在Tomcat中使用CGI脚本
Tomcat主要是作为Servlet/JSP容器,但它也有许多传统web服务器的性能。支持通用网关接口(Common Gateway Interface,即CGI)就是其中之一,CGI提供一组方法在响应浏览器请求时运行一些扩展程序。CGI之所以被称为通用,是因为它能在大多数程序或脚本中被调用,包括:Perl,Python,awk,Unix shell scripting等,甚至包括Java。当然,你大概不会把一个Java应用程序当作CGI来运行,毕竟这样太过原始。一般而言,开发Servlet总要比CGI具有更好的效率,因为当用户点击一个链接或一个按钮时,你不需要从操作系统层开始进行处理。

Tomcat包括一个可选的CGI Servlet,允许你运行遗留下来的CGI脚本。

为了使Tomcat能够运行CGI,你必须做如下几件事:
1. 把servlets-cgi.renametojar (在CATALINA_HOME/server/lib/目录下)改名为servlets-cgi.jar。处理CGI的servlet应该位于Tomcat的CLASSPATH下。
2. 在Tomcat的CATALINA_BASE/conf/web.xml 文件中,把关于<servlet-name> CGI的那段的注释去掉(默认情况下,该段位于第241行)。
3. 同样,在Tomcat的CATALINA_BASE/conf/web.xml文件中,把关于对CGI进行映射的那段的注释去掉(默认情况下,该段位于第299行)。注意,这段内容指定了HTML链接到CGI脚本的访问方式。
4. 你可以把CGI脚本放置在WEB-INF/cgi 目录下(注意,WEB-INF是一个安全的地方,你可以把一些不想被用户看见或基于安全考虑不想暴露的文件放在此处),或者你也可以把CGI脚本放置在context下的其他目录下,并为CGI Servlet调整cgiPathPrefix初始化参数。这就指定的CGI Servlet的实际位置,且不能与上一步指定的URL重名。
5. 重新启动Tomcat,你的CGI就可以运行了。

在Tomcat中,CGI程序缺省放置在WEB-INF/cgi目录下,正如前面所提示的那样,WEB-INF目录受保护的,通过客户端的浏览器无法窥探到其中内容,所以对于放置含有密码或其他敏感信息的CGI脚本而言,这是一个非常好的地方。为了兼容其他服务器,尽管你也可以把CGI脚本保存在传统的/cgi-bin目录,但要知道,在这些目录中的文件有可能被网上好奇的冲浪者看到。另外,在Unix中,请确定运行Tomcat的用户有执行CGI脚本的权限。

9.改变Tomcat中的JSP编译器(JSP Compiler)
在Tomcat 4.1(或更高版本,大概),JSP的编译由包含在Tomcat里面的Ant程序控制器直接执行。这听起来有一点点奇怪,但这正是Ant有意为之的一部分,有一个API文档指导开发者在没有启动一个新的JVM的情况下,使用Ant。这是使用Ant进行Java开发的一大优势。另外,这也意味着你现在能够在Ant中使用任何javac支持的编译方式,这里有一个关于Apache Ant使用手册的javac page列表。使用起来是容易的,因为你只需要在<init-param> 元素中定义一个名字叫“compiler”,并且在value中有一个支持编译的编译器名字,示例如下:

<servlet>
   <servlet-name>jsp</servlet-name>
   <servlet-class>
     org.apache.jasper.servlet.JspServlet
   </servlet-class>
   <init-param>
     <param-name>logVerbosityLevel</param-name>
     <param-value>WARNING</param-value>
   </init-param>
   <init-param>
     <param-name>compiler</param-name>
     <param-value>jikes</param-value>
   </init-param>
   <load-on-startup>3</load-on-startup>
</servlet>

当然,给出的编译器必须已经安装在你的系统中,并且CLASSPATH可能需要设置,那处决于你选择的是何种编译器。

10.限制特定主机访问(Restricting Access to Specific Hosts)
有时,你可能想限制对Tomcat web应用的访问,比如,你希望只有你指定的主机或IP地址可以访问你的应用。这样一来,就只有那些指定的的客户端可以访问服务的内容了。为了实现这种效果,Tomcat提供了两个参数供你配置:RemoteHostValve 和RemoteAddrValve。

通过配置这两个参数,可以让你过滤来自请求的主机或IP地址,并允许或拒绝哪些主机/IP。与之类似的,在Apache的httpd文件里有对每个目录的允许/拒绝指定。
例如你可以把Admin Web application设置成只允许本地访问,设置如下:

<Context path="/path/to/secret_files" ...>
 <Valve className="org.apache.catalina.valves.RemoteAddrValve"
        allow="127.0.0.1" deny=""/>
</Context>

如果没有给出允许主机的指定,那么与拒绝主机匹配的主机就会被拒绝,除此之外的都是允许的。与之类似,如果没有给出拒绝主机的指定,那么与允许主机匹配的主机就会被允许,除此之外的都是拒绝的。
posted @ 2005-10-10 12:19 rodney 阅读(247) | 评论 (0)编辑 收藏
 

今天上网不管输入任何一个网址都没有办法显示内容,提示找不该网页。
用ping www.google.com提示Unknow host www.google.com
用nslookup www.google.com 提示有:服务器名,IP地址都有显示出来。
用tracert IP地址也可以。
后来我在服务中把DNS Client的服务重启一下就OK了。

posted @ 2005-09-23 10:17 rodney 阅读(384) | 评论 (0)编辑 收藏
 
insertBefore()--在参考子节点之前插入一个新的子节点.如果参考的子节点为null,则新的子节点将作为调用节点的最后一个子节点插入。

replaceChild()--在childNodes集合种使用指定的newChild来代替oldChild;如果代替成功,则返回oldChild;如果newChild是null,则只需删除oldChild即可。

removeChild()--从节点的ChildNodes集合中删除removeChild指定的节点,如果删除成功,则返回删除的子节点。

appendChild()--添加一个新节点到childNodes集合的末尾,如果成功,则返回新节点。

cloneNode()--创建一个新的、复制的节点,并且如果传入的参数是true时,还将复制子节点,如果节点是一个元素,那么还将复制相应属性,返回新的节点。

为了在一棵文档树中访问或者建立一个新的节点,可以用下面这些方法:
getElementById()
getElementsByTagName()
createElement()
createAttribute()
createTextNode()
注意:在一个页面中只有一个文档对象,除了getElementsByTagName()外,其它方法均只能通过document.methodName()调用。
再看一下下面这个例子:
<html>
<head>
<title></title>
</head>
<body>
<p>This is a sample paragraph.</p>
<SCRIPT LANGUAGE="JavaScript">
<!--
alert(document.documentElement.lastChild.firstChild.tagName);
//-->
</SCRIPT>
</body>
</html>
结果将会显示"P",下面是一些解释
document.documentElement - gives the page's HTML tag.
lastChild - gives the BODY tag.
firstChild - gives the first element in the BODY.
tagName - gives that element's tag name, "P" in this case.
另一个:
<html>
<head>
<title></title>
</head>
<body>

<p>This is a sample paragraph.</p>
<SCRIPT LANGUAGE="JavaScript">
<!--
alert(document.documentElement.lastChild.firstChild.tagName);
//-->
</SCRIPT>
</body>
</html>
这个例子和上面并没有什么大的区别,仅仅是多了一个空行,但是在NS中,会自动为空行加上一个节点所以返回值是"undefined",而在IE中将跳过空行仍然指向P标签。

更常用的方法:
<p id="myParagraph">This is a sample paragraph.</p>
...
alert(document.getElementById("myParagraph").tagName);
这种方法你不用关心节点在文档树的哪一个地方,而只要保证在页面中它的ID号是唯一的就可以了。

接下来一种访问元素节点的方法是document.getElementsByTagName(),它的返回值是一个数组,例如你可以通过下面的例子改变整个页面的连接:
var nodeList = document.getElementsByTagName("A");
for (var i = 0; i < nodeList.length; i++)
nodeList[i].style.color = "#ff0000";

attribute和attributes
attribute对象和元素相关,但是却没有被认为是文档树的一部分,因此属性不能作为子节点集合的一部分来使用。
有三种方法可以为元素建立新的属性
1.
var attr = document.createAttribute("myAttribute");
attr.value = "myValue";
var el = document.getElementById("myParagraph");
el.setAttributeNode(attr);
2.
var el = document.getElementById("myParagraph");
el.setAttribute("myAttribute", "myValue");
3.
var el = document.getElementById("myParagraph");
el.myAttribute = "myValue";
你可以在html标签种定义自己的属性:
<p id="myParagraph" myAttribute="myValue">This is a sample paragraph.</p>
...
alert(document.getElementById("myParagraph").getAttribute("myAttribute"));
返回值将是"myValue".但是请注意这里必须使用getAttribute,而不是AttributeName,因为有一些浏览器并不支持自定义属性。

attributes也可以被轻易的从一个元素中删除,你可以使用removeAttribute()或者将element.attributeName指向一个null值。
通过attributes我们就可以产生一些动态效果:
<p id="sample1" align="left">Text in a paragraph element.</p>
... code for the links ...
document.getElementById('sample1').setAttribute('align', 'left');
document.getElementById('sample1').setAttribute('align', 'right');
另一种:
<p id="sample2" style="text-align:left;">Text in a paragraph
element.</p>
... code for the links ...
document.getElementById('sample2').style.textAlign = 'left';
document.getElementById('sample2').style.textAlign = 'right';
跟上面的例子一样,展示了可用通过元素修改style中的属性,甚至是class中的.唯一要提到的是textAlign是从style中的text-align中演变而来的,有一条基本规律,就是style中的属性如果出现-则在dom中将会被去掉并且随后的一个字母将改为大写,还有一点就是如果即使元素中没有style属性,上述例子同样可以使用。

text nodes:
先看一下例子:
<p id="sample1">This is the initial text.</p>
... code for the links ...
document.getElementById('sample1').firstChild.nodeValue =
'Once upon a time...';
document.getElementById('sample1').firstChild.nodeValue =
'...in a galaxy far, far away';
首先text nodes并没有像elements那样具有id属性,所有它并不能直接通过document.getElementById()或者document.getElementsByTagName()访问
看一下下面的结构也许会更明白一些:
click for full size
可以看出通过document.getElementById('sample1').firstChild.nodeValue就可以读取或者设置text nodes的值了。

另一个更加复杂一点的例子:
<p id="sample2">This is the <b>initial</b> text.</p>
它的文档结构
click for full size
在这里通过document.getElementById('sample1').firstChild.nodeValue讲仅仅改变"This is the"
initial text.将不会改变.在这里大家应该看到了它和innerHTML的不同了.当然你也可以这样用:
document.getElementById('sample3').firstChild.nodeValue =
'<b>Once</b> upon a time...';
document.getElementById('sample3').firstChild.nodeValue =
'...in a galaxy <i>far, far</i> away';
其中的html代码将不会被解释,浏览器将把他们当成普通的文本来显示。

创建和删除text nodes:
var myTextNode = document.createTextNode("my text");
通过上面的代码你可以创建一个新的text node,但是它并不是文档树的一部分,要让它显示在页面上就必须让它成为文档树中某一个节点的child,因为
text nodes不能有儿子,所以你不能将它加入到一个text nodes中,attribute也不属于文档树的一部分,这条路也不行,现在只剩下elements nodes
了,以下的例子展示了如何添加和删除一个text node:
<p id="sample1">Initial text within a paragraph element.</p>
... code to add a text node ...
var text = document.createTextNode(" new text " + (++counter1));
var el = document.getElementById("sample1");
el.appendChild(text);
... code to remove the last child node ...
var el = document.getElementById("sample1");
if (el.hasChildNodes())
el.removeChild(el.lastChild);
增加文本是很容易的,上面的代码建立了一个新的text node并且通过appendChild()方法将其加入到childNodes数组的末尾,并设置了一个counter1的全局变量,利于观察
hasChildNodes()的返回值是true or false;用来判断当前节点是否还有child,以阻止当其没有child的时候调用removeChild()产生的错误。

创建element nodes
有了上面的基础,应该更容易理解了,先看一下下面的代码
<div id="sample1">This text is in a DIV element.</div>
... code for the link ...
var paraEl, boldEl;
paraEl = document.createElement("p");
boldEl = document.createElement("b");
paraEl.appendChild(document.createTextNode("This is a new paragraph with "));
boldEl.appendChild(document.createTextNode("bold"));
paraEl.appendChild(boldEl);
paraEl.appendChild(document.createTextNode(" text added to the DIV"));
document.getElementById("sample1").appendChild(paraEl);
你还可以直接为新加的element nodes设置attribute,以下两种都可以:
boldEl.style.color = "#ffff00";
paraEl.appendChild(boldEl);
或者:
paraEl.appendChild(boldEl);
boldEl.style.color = "#ffff00";

注:此文主要来自于一些英文资料和身边的一些参考书,如果有错误大家请指出,一起讨论,DOM我一点也不熟。
posted @ 2005-09-19 13:28 rodney 阅读(594) | 评论 (0)编辑 收藏
 
有JDBC编程的人都会知道这是一个什么样的异常。做为刚出道的菜鸟我可因为这个异常把我整一下。
我希望这小段随笔能给阅读都带来帮助,也希望大家多多指教。
我在EJB中写了一个方法:public Vector searchCase(String dataSource,BlacksmokeEnqDataobject inputObj,String sql,int maxAllowSize){
  Connection con = null;
  Vector VqueryData = null;
  PreparedStatement ps = null;
  ResultSet rs = null;
  FormatFunctions ff = new FormatFunctions();
  BlacksmokeEnqReportDataobject blsObj = null;
  SqlFunctions sf = new SqlFunctions();
  try{
   con = getConnection(dataSource);
   String drv_ic_n = inputObj.getDrv_ic_n();
   String caseType = inputObj.getCaseType();
   String vehicleNo = inputObj.getVehNo();
   String fleetType = inputObj.getFleetType();
   String make = inputObj.getMake();
   String model = inputObj.getModel();
   String payFrom = inputObj.getPayDateFrom();
   String payTo = inputObj.getPayDateTo();
   String offFrom = inputObj.getOffeDateFrom();
   String offTo = inputObj.getOffeDateTo();
   String entryFrom = inputObj.getEntryDateFrom();
   String entryTo = inputObj.getEntryDateTo();
   int smokeFrom = inputObj.getSmokeFrom();
   int smokeTo = inputObj.getSmokeTo();
   if (drv_ic_n.equals("")){
    drv_ic_n = null;
   }
   if (caseType.equals("")){
    caseType = null;
   }
   if (vehicleNo.equals("")){
    vehicleNo = null;
   }
   if (fleetType.equals("")){
    fleetType = null;
   }
   if (make.equals("")){
    make = null;
   }
   if (model.equals("")){
    model = null;
   }
   if (payFrom.length()>0 && payFrom.equalsIgnoreCase("00/00/0000")){
    payFrom = null;
   }
   if (payTo.length()>0 && payTo.equalsIgnoreCase("00/00/0000")){
    payTo = null;
   }
   if (offFrom.length()>0 && offFrom.equalsIgnoreCase("00/00/0000")){
    offFrom = null;
   }
   if (offTo.length()>0 && offTo.equalsIgnoreCase("00/00/0000")){
    offTo = null;
   }
   if (entryFrom.length()>0 && entryFrom.equalsIgnoreCase("00/00/0000")){
    entryFrom = null;
   }
   if (entryTo.length()>0 && entryTo.equalsIgnoreCase("00/00/0000")){
    entryTo = null;
   }   
   String tmpSql = sf.retuSqlS(sql);
   tmpSql = sf.linkSql(tmpSql,":LS_CO_FINE_PAID_D_FROM",payFrom);
   tmpSql = sf.linkSql(tmpSql,":LS_CO_FINE_PAID_D_TO",payTo);
   tmpSql = sf.linkSql(tmpSql,":LS_BLS_OFFENCE_D_FROM",offFrom);
   tmpSql = sf.linkSql(tmpSql,":LS_BLS_OFFENCE_D_TO",offTo);
   tmpSql = sf.linkSql(tmpSql,":LS_ENTRY_D_FROM",entryFrom);
   tmpSql =  sf.linkSql(tmpSql,":LS_ENTRY_D_TO",entryTo);
   ps = con.prepareStatement(tmpSql);
//   System.out.println(tmpSql);
   int idx = 0;
   ps.setString(++idx,drv_ic_n);
   ps.setString(++idx,drv_ic_n);
   ps.setString(++idx,caseType);
   ps.setString(++idx,caseType);
   ps.setString(++idx,vehicleNo);
   ps.setString(++idx,vehicleNo);
   ps.setString(++idx,fleetType);
   ps.setString(++idx,fleetType);
   ps.setString(++idx,make);
   ps.setString(++idx,make);
   ps.setString(++idx,model);
   ps.setString(++idx,model);
   ps.setInt(++idx,smokeFrom);
   ps.setInt(++idx,smokeFrom);
   ps.setInt(++idx,smokeTo);
//   ps.setInt(++idx,smokeTo);  
   ps.executeQuery();
   rs = ps.getResultSet();
   VqueryData = new Vector();
   idx = 0;
   while(rs.next() && idx <= maxAllowSize){
    blsObj = new BlacksmokeEnqReportDataobject();
    blsObj.setDRV_IC_N(rs.getString("DRV_IC_N"));
    blsObj.setDRV_NM(rs.getString("DRV_NM"));
    blsObj.setBLS_CASE_N(rs.getString("BLS_CASE_N"));
    blsObj.setBLS_CASE_T(rs.getString("BLS_CASE_T"));
    blsObj.setVEH_REGN_N(rs.getString("VEH_REGN_N"));
    blsObj.setBLS_FLT_T(rs.getString("BLS_FLT_T"));
    blsObj.setBLS_MAKE_C(rs.getString("BLS_MAKE_C"));
    blsObj.setBLS_MODEL_C(rs.getString("BLS_MODEL_C"));
    blsObj.setBLS_OFFENCE_D(ff.dateFormat(rs.getDate("BLS_OFFENCE_D")));
    blsObj.setENTRY_D(ff.dateFormat(rs.getDate("ENTRY_D")));
    blsObj.setSMOKE_LEV_READ(rs.getInt("SMOKE_LEV_READ"));
    blsObj.setCO_FINE_PAID_D(ff.dateFormat(rs.getDate("CO_FINE_PAID_D")));
    VqueryData.addElement(blsObj);
    idx++;
   }
   }catch(Exception e){
    blsObj.setErrStatus(sf.ckException(e));
    VqueryData.addElement(blsObj);
    e.printStackTrace();
   }finally{
    SqlFunctions.cleanup(ps, rs);
    SqlFunctions.cleanup(con);
   }
  return VqueryData;
 }这是一个通过XML文件来传SQL语。把查询语句写在XML文件中,在Servlet中调用XML文件。
上面那个错误是因为没有对XML中的查询变量进行绑定,或者是多写,或少写变量,或者变量名写错了。后来我重新认真的做了一遍,发生我没有写错。我把JDeveloper关了,重新打开,可以了。我的没有想这是怎么一回,如果有同样问题的好友知道这是怎么一回事,请联系我rodney_luo@163.com. QQ:86322591
posted @ 2005-09-15 16:19 rodney 阅读(15705) | 评论 (1)编辑 收藏
 

在JPS中用request.Session().setAttribute("别名",对象),如果对对象是一个Value类型,在JSP中取这个对象时一定要用Value类型来接收。不然的的话会出现java.io.ClasscateExection的异常。

posted @ 2005-09-15 14:46 rodney 阅读(1124) | 评论 (1)编辑 收藏
 
Ping
Ping是个使用频率极高的实用程序,用于确定本地主机是否能与另一台主机交换(发送与接收)数据报。根据返回的信息,你就可以推断TCP/IP参数是否设置得正确以及运行是否正常。需要注意的是:成功地与另一台主机进行一次或两次数据报交换并不表示TCP/IP配置就是正确的,你必须执行大量的本地主机与远程主机的数据报交换,才能确信TCP/IP的正确性。
简单的说,Ping就是一个测试程序,如果Ping运行正确,你大体上就可以排除网络访问层、网卡、MODEM的输入输出线路、电缆和路由器等存在的故障,从而减小了问题的范围。但由于可以自定义所发数据报的大小及无休止的高速发送,Ping也被某些别有用心的人作为DDOS(拒绝服务攻击)的工具,前段时间Yahoo就是被人利用数百台可以高速接入互联网的电脑连续发送大量Ping数据包而瘫痪的。
按照缺省设置,Windows上运行的Ping命令发送4个ICMP(网间控制报文协议)回送请求,每个32字节数据,如果一切正常,你应能得到4个回送应答。
Ping能够以毫秒为单位显示发送回送请求到返回回送应答之间的时间量。如果应答时间短,表示数据报不必通过太多的路由器或网络连接速度比较快。Ping还能显示TTL(Time To Live存在时间)值,你可以通过TTL值推算一下数据包已经通过了多少个路由器:源地点TTL起始值(就是比返回TTL略大的一个2的乘方数)-返回时TTL值。例如,返回TTL值为119,那么可以推算数据报离开源地址的TTL起始值为128,而源地点到目标地点要通过9个路由器网段(128-119);如果返回TTL值为246,TTL起始值就是256,源地点到目标地点要通过9个路由器网段。
通过Ping检测网络故障的典型次序
正常情况下,当你使用Ping命令来查找问题所在或检验网络运行情况时,你需要使用许多Ping命令,如果所有都运行正确,你就可以相信基本的连通性和配置参数没有问题;如果某些Ping命令出现运行故障,它也可以指明到何处去查找问题。下面就给出一个典型的检测次序及对应的可能故障:
ping 127.0.0.1——这个Ping命令被送到本地计算机的IP软件,该命令永不退出该计算机。如果没有做到这一点,就表示TCP/IP的安装或运行存在某些最基本的问题。
ping 本机IP——这个命令被送到你计算机所配置的IP地址,你的计算机始终都应该对该Ping命令作出应答,如果没有,则表示本地配置或安装存在问题。出现此问题时,局域网用户请断开网络电缆,然后重新发送该命令。如果网线断开后本命令正确,则表示另一台计算机可能配置了相同的IP地址。
ping 局域网内其他IP——这个命令应该离开你的计算机,经过网卡及网络电缆到达其他计算机,再返回。收到回送应答表明本地网络中的网卡和载体运行正确。但如果收到0个回送应答,那么表示子网掩码(进行子网分割时,将IP地址的网络部分与主机部分分开的代码)不正确或网卡配置错误或电缆系统有问题。
ping 网关IP——这个命令如果应答正确,表示局域网中的网关路由器正在运行并能够作出应答。
ping 远程IP——如果收到4个应答,表示成功的使用了缺省网关。对于拨号上网用户则表示能够成功的访问Internet(但不排除ISP的DNS会有问题)。
ping localhost——localhost是个作系统的网络保留名,它是127.0.0.1的别名,每太计算机都应该能够将该名字转换成该地址。如果没有做到这一带内,则表示主机文件(/Windows/host)中存在问题。
ping www.yahoo.com——对这个域名执行Ping命令,你的计算机必须先将域名转换成IP地址,通常是通过DNS服务器 如果这里出现故障,则表示DNS服务器的IP地址配置不正确或DNS服务器有故障(对于拨号上网用户,某些ISP已经不需要设置DNS服务器了)。顺便说一句:你也可以利用该命令实现域名对IP地址的转换功能。
如果上面所列出的所有Ping命令都能正常运行,那么你对你的计算机进行本地和远程通信的功能基本上就可以放心了。但是,这些命令的成功并不表示你所有的网络配置都没有问题,例如,某些子网掩码错误就可能无法用这些方法检测到。
Ping命令的常用参数选项
ping IP -t——连续对IP地址执行Ping命令,直到被用户以Ctrl+C中断。
ping IP -l 2000——指定Ping命令中的数据长度为2000字节,而不是缺省的32字节。
ping IP -n——执行特定次数的Ping命令。
Netstat
Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。
如果你的计算机有时候接受到的数据报会导致出错数据删除或故障,你不必感到奇怪,TCP/IP可以容许这些类型的错误,并能够自动重发数据报。但如果累计的出错情况数目占到所接收的IP数据报相当大的百分比,或者它的数目正迅速增加,那么你就应该使用Netstat查一查为什么会出现这些情况了。
Netstat的一些常用选项:
netstat -s——本选项能够按照各个协议分别显示其统计数据。如果你的应用程序(如Web浏览器)运行速度比较慢,或者不能显示Web页之类的数据,那么你就可以用本选项来查看一下所显示的信息。你需要仔细查看统计数据的各行,找到出错的关键字,进而确定问题所在。
netstat -e——本选项用于显示关于以太网的统计数据。它列出的项目包括传送的数据报的总字节数、错误数、删除数、数据报的数量和广播的数量。这些统计数据既有发送的数据报数量,也有接收的数据报数量。这个选项可以用来统计一些基本的网络流量)。
netstat -r——本选项可以显示关于路由表的信息,类似于后面所讲使用route print命令时看到的 信息。除了显示有效路由外,还显示当前有效的连接。
netstat -a——本选项显示一个所有的有效连接信息列表,包括已建立的连接(ESTABLISHED),也包括监听连接请求(LISTENING)的那些连接。
netstat -n——显示所有已建立的有效连接。
Netstat的妙用
经常上网的人一般都使用ICQ的,不知道你有没有被一些讨厌的人骚扰得不敢上线,想投诉却又不知从和下手?其实,你只要知道对方的IP,就可以向他所属的ISP投诉了。但怎样才能通过ICQ知道对方的IP呢?如果对方在设置ICQ时选择了不显示IP地址,那你是无法在信息栏中看到的。其实,你只需要通过Netstat就可以很方便的做到这一点:当他通过ICQ或其他的工具与你相连时(例如你给他发一条ICQ信息或他给你发一条信息),你立刻在DOS Prompt下输入netstat -n或netstat -a就可以看到对方上网时所用的IP或ISP域名了。甚至连所用Port都完全暴露了,如果你想给他一些教训,这些信息已经足够……
IPConfig
IPConfig实用程序和它的等价图形用户界面——Windows 95/98中的WinIPCfg可用于显示当前的TCP/IP配置的设置值。这些信息一般用来检验人工配置的TCP/IP设置是否正确。但是,如果你的计算机和所在的局域网使用了动态主机配置协议(Dynamic Host Configuration Protocol,DHCP——Windows NT下的一种把较少的IP地址分配给较多主机使用的协议,类似于拨号上网的动态IP分配),这个程序所显示的信息也许更加实用。这时,IPConfig可以让你了解你的计算机是否成功的租用到一个IP地址,如果租用到则可以了解它目前分配到的是什么地址。了解计算机当前的IP地址、子网掩码和缺省网关实际上是进行测试和故障分析的必要项目。
最常用的选项:
ipconfig——当使用IPConfig时不带任何参数选项,那么它为每个已经配置了的接口显示IP地址、子网掩码和缺省网关值
ipconfig /all——当使用all选项时,IPConfig能为DNS和WINS服务器显示它已配置且所要使用的附加信息(如IP地址等),并且显示内置于本地网卡中的物理地址(MAC)。如果IP地址是从DHCP服务器租用的,IPConfig将显示DHCP服务器的IP地址和租用地址预计失效的日期(有关DHCP服务器的相关内容请详见其他有关NT服务器的书籍或询问你的网管),其输出信息见图6的下半部分。
ipconfig /release和ipconfig /renew——这是两个附加选项,只能在向DHCP服务器租用其IP地址的计算机上起作用。如果你输入ipconfig /release,那么所有接口的租用IP地址便重新交付给DHCP服务器(归还IP地址)。如果你输入ipconfig /renew,那么本地计算机便设法与DHCP服务器取得联系,并租用一个IP地址。请注意,大多数情况下网卡将被重新赋予和以前所赋予的相同的IP地址。
如果你使用的是Windows 95/98,那么你应该更习惯使用winipcfg而不是ipconfig,因为它是一个图形用户界面,而且所显示的信息与ipconfig相同,并且也提供发布和更新动态IP地址的选项 如果你购买了Windows NT Resource Kit(NT资源包),那么Windows NT也包含了一个图形替代界面,该实用程序的名字是wntipcfg,和Windows 95/98的winipcfg类似。
ARP(地址转换协议)
ARP是一个重要的TCP/IP协议,并且用于确定对应IP地址的网卡物理地址。实用arp命令,你能够查看本地计算机或另一台计算机的ARP高速缓存中的当前内容。此外,使用arp命令,也可以用人工方式输入静态的网卡物理/IP地址对,你可能会使用这种方式为缺省网关和本地服务器等常用主机进行这项作,有助于减少网络上的信息量。
按照缺省设置,ARP高速缓存中的项目是动态的,每当发送一个指定地点的数据报且高速缓存中不存在当前项目时,ARP便会自动添加该项目。一旦高速缓存的项目被输入,它们就已经开始走向失效状态。例如,在Windows NT网络中,如果输入项目后不进一步使用,物理/IP地址对就会在2至10分钟内失效。因此,如果ARP高速缓存中项目很少或根本没有时,请不要奇怪,通过另一台计算机或路由器的ping命令即可添加。所以,需要通过arp命令查看高速缓存中的内容时,请最好先ping 此台计算机(不能是本机发送ping命令)。
常用命令选项:
arp -a或arp -g——用于查看高速缓存中的所有项目。-a和-g参数的结果是一样的,多年来-g一直是UNIX平台上用来显示ARP高速缓存中所有项目的选项,而Windows用的是arp -a(-a可被视为all,即全部的意思),但它也可以接受比较传统的-g选项。
arp -a IP——如果你有多个网卡,那么使用arp -a加上接口的IP地址,就可以只显示与该接口相关的ARP缓存项目。
arp -s IP 物理地址——你可以向ARP高速缓存中人工输入一个静态项目。该项目在计算机引导过程中将保持有效状态,或者在出现错误时,人工配置的物理地址将自动更新该项目。
arp -d IP——使用本命令能够人工删除一个静态项目。

看到这里,你也许已经有些累了……其实对于一般用户来说也已经足够——你可以用ipconfig和ping命令来查看自己的网络配置并判断是否正确、可以用netstat查看别人与你所建立的连接并找出ICQ使用者所隐藏的IP信息、可以用arp查看网卡的MAC地址——这些已足已让你丢掉菜鸟的头衔。如果你并不满足,那就“硬着头皮”(下面的内容可能有些枯燥)继续Follow me……
Tracert
当数据报从你的计算机经过多个网关传送到目的地时,Tracert命令可以用来跟踪数据报使用的路由(路径)。该实用程序跟踪的路径是源计算机到目的地的一条路径,不能保证或认为数据报总遵循这个路径。如果你的配置使用DNS,那么你常常会从所产生的应答中得到城市、地址和常见通信公司的名字。Tracert是一个运行得比较慢的命令(如果你指定的目标地址比较远),每个路由器你大约需要给它15秒钟
Tracert的使用很简单,只需要在tracert后面跟一个IP地址或URL,Tracert会进行相应的域名转换的。Tracert一般用来检测故障的位置,你可以用tracert IP在哪个环节上出了问题,虽然还是没有确定是什么问题,但它已经告诉了我们问题所在的地方,你也就可以很有把握的告诉别人——某某出了问题。
Route
大多数主机一般都是驻留在只连接一台路由器的网段上。由于只有一台路由器,因此不存在使用哪一台路由器将数据报发表到远程计算机上去的问题,该路由器的IP地址可作为该网段上所有计算机的缺省网关来输入。
但是,当网络上拥有两个或多个路由器时,你就不一定想只依赖缺省网关了。实际上你可能想让你的某些远程IP地址通过某个特定的路由器来传递,而其他的远程IP则通过另一个路由器来传递。
在这种情况下,你需要相应的路由信息,这些信息储存在路由表中,每个主机和每个路由器都配有自己独一无二的路由表。大多数路由器使用专门的路由协议来交换和动态更新路由器之间的路由表。但在有些情况下,必须人工将项目添加到路由器和主机上的路由表中。Route就是用来显示、人工添加和修改路由表项目的。
一般使用选项:
route print——本命令用于显示路由表中的当前项目,在单路由器网段上的输出结果如图12,由于用IP地址配置了网卡,因此所有的这些项目都是自动添加的。
route add——使用本命令,可以将信路由项目添加给路由表。例如,如果要设定一个到目的网络209.98.32.33的路由,其间要经过5个路由器网段,首先要经过本地网络上的一个路由器,器IP为202.96.123.5,子网掩码为255.255.255.224,那么你应该输入以下命令:
route add 209.98.32.33 mask 255.255.255.224 202.96.123.5 metric 5
route change——你可以使用本命令来修改数据的传输路由,不过,你不能使用本命令来改变数据的目的地。下面这个例子可以将数据的路由改到另一个路由器,它采用一条包含3个网段的更直的路径:
route add 209.98.32.33 mask 255.255.255.224 202.96.123.250 metric 3
route delete——使用本命令可以从路由表中删除路由。例如:route delete 209.98.32.33
NBTStat
NBTStat(TCP/IP上的NetBIOS统计数据)实用程序用于提供关于关于NetBIOS的统计数据。运用NetBIOS,你可以查看本地计算机或远程计算机上的NetBIOS名字表格。
常用选项:
nbtstat -n——显示寄存在本地的名字和服务程序
nbtstat -c——本命令用于显示NetBIOS名字高速缓存的内容。NetBIOS名字高速缓存用于寸放与本计算机最近进行通信的其他计算机的NetBIOS名字和IP地址对。
nbtstat -r——本命令用于清除和重新加载NetBIOS名字高速缓存。
nbtstat -a IP——通过IP显示另一台计算机的物理地址和名字列表,你所显示的内容就像对方计算机自己运行nbtstat -n一样
nbtstat -s IP——显示实用其IP地址的另一台计算机的NetBIOS连接表。
Net
Net命令有很多函数用于实用和核查计算机之间的NetBIOS连接。这里我只介绍最常用的两个:net view和net use。
net view UNC——运用此命令,你可以查看目标服务器上的共享点名字。任何局域网里的人都可以发出此命令,而且不需要提供用户ID或口令。UNC名字总是以\\开头,后面跟随目标计算机的名字。例如,net view \\lx就是查看主机名为lx的计算机的共享点(见图15)。
net use 本地盘符 目标计算机共享点——本命令用于建立或取消到达特定共享点的映像驱动器的连接(如果需要,你必须提供用户ID或口令)。例如,你输入net use f: \\lx\mp3就是将映像驱动器F:连接到\\lx\mp3共享点上,今后你直接访问F:就可以访问\\lx\mp3共享点,这和你右击“我的电脑”选择映射网络驱动器类似。
Ping
Ping是个使用频率极高的实用程序,用于确定本地主机是否能与另一台主机交换(发送与接收)数据报。根据返回的信息,你就可以推断TCP/IP参数是否设置得正确以及运行是否正常。需要注意的是:成功地与另一台主机进行一次或两次数据报交换并不表示TCP/IP配置就是正确的,你必须执行大量的本地主机与远程主机的数据报交换,才能确信TCP/IP的正确性。
简单的说,Ping就是一个测试程序,如果Ping运行正确,你大体上就可以排除网络访问层、网卡、MODEM的输入输出线路、电缆和路由器等存在的故障,从而减小了问题的范围。但由于可以自定义所发数据报的大小及无休止的高速发送,Ping也被某些别有用心的人作为DDOS(拒绝服务攻击)的工具,前段时间Yahoo就是被人利用数百台可以高速接入互联网的电脑连续发送大量Ping数据包而瘫痪的。
按照缺省设置,Windows上运行的Ping命令发送4个ICMP(网间控制报文协议)回送请求,每个32字节数据,如果一切正常,你应能得到4个回送应答。
Ping能够以毫秒为单位显示发送回送请求到返回回送应答之间的时间量。如果应答时间短,表示数据报不必通过太多的路由器或网络连接速度比较快。Ping还能显示TTL(Time To Live存在时间)值,你可以通过TTL值推算一下数据包已经通过了多少个路由器:源地点TTL起始值(就是比返回TTL略大的一个2的乘方数)-返回时TTL值。例如,返回TTL值为119,那么可以推算数据报离开源地址的TTL起始值为128,而源地点到目标地点要通过9个路由器网段(128-119);如果返回TTL值为246,TTL起始值就是256,源地点到目标地点要通过9个路由器网段。
通过Ping检测网络故障的典型次序
正常情况下,当你使用Ping命令来查找问题所在或检验网络运行情况时,你需要使用许多Ping命令,如果所有都运行正确,你就可以相信基本的连通性和配置参数没有问题;如果某些Ping命令出现运行故障,它也可以指明到何处去查找问题。下面就给出一个典型的检测次序及对应的可能故障:
ping 127.0.0.1——这个Ping命令被送到本地计算机的IP软件,该命令永不退出该计算机。如果没有做到这一点,就表示TCP/IP的安装或运行存在某些最基本的问题。
ping 本机IP——这个命令被送到你计算机所配置的IP地址,你的计算机始终都应该对该Ping命令作出应答,如果没有,则表示本地配置或安装存在问题。出现此问题时,局域网用户请断开网络电缆,然后重新发送该命令。如果网线断开后本命令正确,则表示另一台计算机可能配置了相同的IP地址。
ping 局域网内其他IP——这个命令应该离开你的计算机,经过网卡及网络电缆到达其他计算机,再返回。收到回送应答表明本地网络中的网卡和载体运行正确。但如果收到0个回送应答,那么表示子网掩码(进行子网分割时,将IP地址的网络部分与主机部分分开的代码)不正确或网卡配置错误或电缆系统有问题。
ping 网关IP——这个命令如果应答正确,表示局域网中的网关路由器正在运行并能够作出应答。
ping 远程IP——如果收到4个应答,表示成功的使用了缺省网关。对于拨号上网用户则表示能够成功的访问Internet(但不排除ISP的DNS会有问题)。
ping localhost——localhost是个作系统的网络保留名,它是127.0.0.1的别名,每太计算机都应该能够将该名字转换成该地址。如果没有做到这一带内,则表示主机文件(/Windows/host)中存在问题。
ping www.yahoo.com——对这个域名执行Ping命令,你的计算机必须先将域名转换成IP地址,通常是通过DNS服务器 如果这里出现故障,则表示DNS服务器的IP地址配置不正确或DNS服务器有故障(对于拨号上网用户,某些ISP已经不需要设置DNS服务器了)。顺便说一句:你也可以利用该命令实现域名对IP地址的转换功能。
如果上面所列出的所有Ping命令都能正常运行,那么你对你的计算机进行本地和远程通信的功能基本上就可以放心了。但是,这些命令的成功并不表示你所有的网络配置都没有问题,例如,某些子网掩码错误就可能无法用这些方法检测到。
Ping命令的常用参数选项
ping IP -t——连续对IP地址执行Ping命令,直到被用户以Ctrl+C中断。
ping IP -l 2000——指定Ping命令中的数据长度为2000字节,而不是缺省的32字节。
ping IP -n——执行特定次数的Ping命令。
Netstat
Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。
如果你的计算机有时候接受到的数据报会导致出错数据删除或故障,你不必感到奇怪,TCP/IP可以容许这些类型的错误,并能够自动重发数据报。但如果累计的出错情况数目占到所接收的IP数据报相当大的百分比,或者它的数目正迅速增加,那么你就应该使用Netstat查一查为什么会出现这些情况了。
Netstat的一些常用选项:
netstat -s——本选项能够按照各个协议分别显示其统计数据。如果你的应用程序(如Web浏览器)运行速度比较慢,或者不能显示Web页之类的数据,那么你就可以用本选项来查看一下所显示的信息。你需要仔细查看统计数据的各行,找到出错的关键字,进而确定问题所在。
netstat -e——本选项用于显示关于以太网的统计数据。它列出的项目包括传送的数据报的总字节数、错误数、删除数、数据报的数量和广播的数量。这些统计数据既有发送的数据报数量,也有接收的数据报数量。这个选项可以用来统计一些基本的网络流量)。
netstat -r——本选项可以显示关于路由表的信息,类似于后面所讲使用route print命令时看到的 信息。除了显示有效路由外,还显示当前有效的连接。
netstat -a——本选项显示一个所有的有效连接信息列表,包括已建立的连接(ESTABLISHED),也包括监听连接请求(LISTENING)的那些连接。
netstat -n——显示所有已建立的有效连接。
Netstat的妙用
经常上网的人一般都使用ICQ的,不知道你有没有被一些讨厌的人骚扰得不敢上线,想投诉却又不知从和下手?其实,你只要知道对方的IP,就可以向他所属的ISP投诉了。但怎样才能通过ICQ知道对方的IP呢?如果对方在设置ICQ时选择了不显示IP地址,那你是无法在信息栏中看到的。其实,你只需要通过Netstat就可以很方便的做到这一点:当他通过ICQ或其他的工具与你相连时(例如你给他发一条ICQ信息或他给你发一条信息),你立刻在DOS Prompt下输入netstat -n或netstat -a就可以看到对方上网时所用的IP或ISP域名了。甚至连所用Port都完全暴露了,如果你想给他一些教训,这些信息已经足够……
IPConfig
IPConfig实用程序和它的等价图形用户界面——Windows 95/98中的WinIPCfg可用于显示当前的TCP/IP配置的设置值。这些信息一般用来检验人工配置的TCP/IP设置是否正确。但是,如果你的计算机和所在的局域网使用了动态主机配置协议(Dynamic Host Configuration Protocol,DHCP——Windows NT下的一种把较少的IP地址分配给较多主机使用的协议,类似于拨号上网的动态IP分配),这个程序所显示的信息也许更加实用。这时,IPConfig可以让你了解你的计算机是否成功的租用到一个IP地址,如果租用到则可以了解它目前分配到的是什么地址。了解计算机当前的IP地址、子网掩码和缺省网关实际上是进行测试和故障分析的必要项目。
最常用的选项:
ipconfig——当使用IPConfig时不带任何参数选项,那么它为每个已经配置了的接口显示IP地址、子网掩码和缺省网关值
ipconfig /all——当使用all选项时,IPConfig能为DNS和WINS服务器显示它已配置且所要使用的附加信息(如IP地址等),并且显示内置于本地网卡中的物理地址(MAC)。如果IP地址是从DHCP服务器租用的,IPConfig将显示DHCP服务器的IP地址和租用地址预计失效的日期(有关DHCP服务器的相关内容请详见其他有关NT服务器的书籍或询问你的网管),其输出信息见图6的下半部分。
ipconfig /release和ipconfig /renew——这是两个附加选项,只能在向DHCP服务器租用其IP地址的计算机上起作用。如果你输入ipconfig /release,那么所有接口的租用IP地址便重新交付给DHCP服务器(归还IP地址)。如果你输入ipconfig /renew,那么本地计算机便设法与DHCP服务器取得联系,并租用一个IP地址。请注意,大多数情况下网卡将被重新赋予和以前所赋予的相同的IP地址。
如果你使用的是Windows 95/98,那么你应该更习惯使用winipcfg而不是ipconfig,因为它是一个图形用户界面,而且所显示的信息与ipconfig相同,并且也提供发布和更新动态IP地址的选项 如果你购买了Windows NT Resource Kit(NT资源包),那么Windows NT也包含了一个图形替代界面,该实用程序的名字是wntipcfg,和Windows 95/98的winipcfg类似。
ARP(地址转换协议)
ARP是一个重要的TCP/IP协议,并且用于确定对应IP地址的网卡物理地址。实用arp命令,你能够查看本地计算机或另一台计算机的ARP高速缓存中的当前内容。此外,使用arp命令,也可以用人工方式输入静态的网卡物理/IP地址对,你可能会使用这种方式为缺省网关和本地服务器等常用主机进行这项作,有助于减少网络上的信息量。
按照缺省设置,ARP高速缓存中的项目是动态的,每当发送一个指定地点的数据报且高速缓存中不存在当前项目时,ARP便会自动添加该项目。一旦高速缓存的项目被输入,它们就已经开始走向失效状态。例如,在Windows NT网络中,如果输入项目后不进一步使用,物理/IP地址对就会在2至10分钟内失效。因此,如果ARP高速缓存中项目很少或根本没有时,请不要奇怪,通过另一台计算机或路由器的ping命令即可添加。所以,需要通过arp命令查看高速缓存中的内容时,请最好先ping 此台计算机(不能是本机发送ping命令)。
常用命令选项:
arp -a或arp -g——用于查看高速缓存中的所有项目。-a和-g参数的结果是一样的,多年来-g一直是UNIX平台上用来显示ARP高速缓存中所有项目的选项,而Windows用的是arp -a(-a可被视为all,即全部的意思),但它也可以接受比较传统的-g选项。
arp -a IP——如果你有多个网卡,那么使用arp -a加上接口的IP地址,就可以只显示与该接口相关的ARP缓存项目。
arp -s IP 物理地址——你可以向ARP高速缓存中人工输入一个静态项目。该项目在计算机引导过程中将保持有效状态,或者在出现错误时,人工配置的物理地址将自动更新该项目。
arp -d IP——使用本命令能够人工删除一个静态项目。

看到这里,你也许已经有些累了……其实对于一般用户来说也已经足够——你可以用ipconfig和ping命令来查看自己的网络配置并判断是否正确、可以用netstat查看别人与你所建立的连接并找出ICQ使用者所隐藏的IP信息、可以用arp查看网卡的MAC地址——这些已足已让你丢掉菜鸟的头衔。如果你并不满足,那就“硬着头皮”(下面的内容可能有些枯燥)继续Follow me……
Tracert
当数据报从你的计算机经过多个网关传送到目的地时,Tracert命令可以用来跟踪数据报使用的路由(路径)。该实用程序跟踪的路径是源计算机到目的地的一条路径,不能保证或认为数据报总遵循这个路径。如果你的配置使用DNS,那么你常常会从所产生的应答中得到城市、地址和常见通信公司的名字。Tracert是一个运行得比较慢的命令(如果你指定的目标地址比较远),每个路由器你大约需要给它15秒钟
Tracert的使用很简单,只需要在tracert后面跟一个IP地址或URL,Tracert会进行相应的域名转换的。Tracert一般用来检测故障的位置,你可以用tracert IP在哪个环节上出了问题,虽然还是没有确定是什么问题,但它已经告诉了我们问题所在的地方,你也就可以很有把握的告诉别人——某某出了问题。
Route
大多数主机一般都是驻留在只连接一台路由器的网段上。由于只有一台路由器,因此不存在使用哪一台路由器将数据报发表到远程计算机上去的问题,该路由器的IP地址可作为该网段上所有计算机的缺省网关来输入。
但是,当网络上拥有两个或多个路由器时,你就不一定想只依赖缺省网关了。实际上你可能想让你的某些远程IP地址通过某个特定的路由器来传递,而其他的远程IP则通过另一个路由器来传递。
在这种情况下,你需要相应的路由信息,这些信息储存在路由表中,每个主机和每个路由器都配有自己独一无二的路由表。大多数路由器使用专门的路由协议来交换和动态更新路由器之间的路由表。但在有些情况下,必须人工将项目添加到路由器和主机上的路由表中。Route就是用来显示、人工添加和修改路由表项目的。
一般使用选项:
route print——本命令用于显示路由表中的当前项目,在单路由器网段上的输出结果如图12,由于用IP地址配置了网卡,因此所有的这些项目都是自动添加的。
route add——使用本命令,可以将信路由项目添加给路由表。例如,如果要设定一个到目的网络209.98.32.33的路由,其间要经过5个路由器网段,首先要经过本地网络上的一个路由器,器IP为202.96.123.5,子网掩码为255.255.255.224,那么你应该输入以下命令:
route add 209.98.32.33 mask 255.255.255.224 202.96.123.5 metric 5
route change——你可以使用本命令来修改数据的传输路由,不过,你不能使用本命令来改变数据的目的地。下面这个例子可以将数据的路由改到另一个路由器,它采用一条包含3个网段的更直的路径:
route add 209.98.32.33 mask 255.255.255.224 202.96.123.250 metric 3
route delete——使用本命令可以从路由表中删除路由。例如:route delete 209.98.32.33
NBTStat
NBTStat(TCP/IP上的NetBIOS统计数据)实用程序用于提供关于关于NetBIOS的统计数据。运用NetBIOS,你可以查看本地计算机或远程计算机上的NetBIOS名字表格。
常用选项:
nbtstat -n——显示寄存在本地的名字和服务程序
nbtstat -c——本命令用于显示NetBIOS名字高速缓存的内容。NetBIOS名字高速缓存用于寸放与本计算机最近进行通信的其他计算机的NetBIOS名字和IP地址对。
nbtstat -r——本命令用于清除和重新加载NetBIOS名字高速缓存。
nbtstat -a IP——通过IP显示另一台计算机的物理地址和名字列表,你所显示的内容就像对方计算机自己运行nbtstat -n一样
nbtstat -s IP——显示实用其IP地址的另一台计算机的NetBIOS连接表。
Net
Net命令有很多函数用于实用和核查计算机之间的NetBIOS连接。这里我只介绍最常用的两个:net view和net use。
net view UNC——运用此命令,你可以查看目标服务器上的共享点名字。任何局域网里的人都可以发出此命令,而且不需要提供用户ID或口令。UNC名字总是以\\开头,后面跟随目标计算机的名字。例如,net view \\lx就是查看主机名为lx的计算机的共享点(见图15)。
net use 本地盘符 目标计算机共享点——本命令用于建立或取消到达特定共享点的映像驱动器的连接(如果需要,你必须提供用户ID或口令)。例如,你输入net use f: \\lx\mp3就是将映像驱动器F:连接到\\lx\mp3共享点上,今后你直接访问F:就可以访问\\lx\mp3共享点,这和你右击“我的电脑”选择映射网络驱动器类似。
ping命令的详解:
-a
    将目标的机器标识转换为ip地址。
-t
    若使用者不人为中断会不断的ping下去。
-c
    count要求ping命令连续发送数据包,直到发出并接收到count个请求。
-d
    为使用的套接字打开调试状态。
-f
    是一种快速方式ping。使得ping输出数据包的速度和数据包从远程主机返回一样快,或者更快,达到每秒100次。在这种方式下,每个请求用一个句点表示。对于每一个响应打印一个空格键。
-i
    seconds 在两次数据包发送之间间隔一定的秒数。不能同-f一起使用。
-n
    只使用数字方式。在一般情况下ping会试图把IP地址转换成主机名。这个选项要求ping打印IP地址而不去查找用符号表示的名字。如果由于某种原因无法使用本地DNS服务器这个选项就很重要了。
-p
    pattern 拥护可以通过这个选项标识16 pad字节,把这些字节加入数据包中。当在网络中诊断与数据有关的错误时这个选项就非常有用。
-q
    使ping只在开始和结束时打印一些概要信息。
-R
    把ICMP RECORD-ROUTE选项加入到ECHO_REQUEST数据包中,要求在数据包中记录路由,这样当数据返回时ping就可以把路由信息打印出来。每个数据包只能记录9个路由节点。许多主机忽略或者放弃这个选项。
-r
    使ping命令旁路掉用于发送数据包的正常路由表。
-s
    packetsize使用户能够标识出要发送数据的字节数。缺省是56个字符,再加上8个字节的ICMP数据头,共64个ICMP数据字节。
-v
    使ping处于verbose方式。它要ping命令除了打印ECHO-RESPONSE数据包之外,还打印其它所有返回的ICMP数据包。

net命令详解:
 这篇文章综合了WINDOWS 98,WINDOWS WORKSTATION和WINDOWS SERVER 三个操作系统关于NET命令的解释,希望可以全面一些。
    说明:
    NET命令是一个命令行命令。用途:管理网络环境、服务、用户、登陆。。。。等本地信息。WIN 98、WIN WORKSTATION和WIN NT都内置了NET命令。但WIN 98的NET命令和WORKSTATION、NT的NET命令不同。WORKSTATION和SERVER中的NET命令基本相同。
    获得HELP:
    在NT下可以用图形的方式,开始-》帮助-》索引-》输入NET;
    在COMMAND下可以用字符方式,NET /?或NET或NET HELP得到一些方法,相应的方法的帮助NET COMMAND /HELP或NET HELP COMMAND或NET COMMAND /? 另对于错误NET HELPMSG MESSAGE#是4位数。
    注意事项:
    所有net命令接受选项/yes和/no(可缩写为/y和/n)。[简单的说就是预先给系统的提问一个答案]。
    有一些命令是马上产生作用并永久保存的,使用的时候要慎重。
    对于NET命令的功能都可以找到相应的图形工具的解决方案。
    命令的组成:命令 参数 选项 | 参数 选项 | 参数 选项 |......
   NET命令的不同参数的基本用法:
(1)NET VIEW
作 用:显示域列表、计算机列表或指定计算机的共享资源列表。
命令格式:net view [computername | /domain[:domainname]]
参数介绍:(1)键入不带参数的net view显示当前域的计算机列表。
(2)computername 指定要查看其共享资源的计算机。
(3)/domain[:domainname]指定要查看其可用计算机的域。
简单事例:(1)net view YFANG查看YFANG的共享资源列表。
(2)net view /domain:LOVE查看LOVE域中的机器列表。


(2)NET USER
作用:添加或更改用户帐号或显示用户帐号信息。该命令也可以写为 net users。
命令格式:net user [username [password | *] [options]] [/domain]
参数介绍:(1)键入不带参数的net user查看计算机上的用户帐号列表。
(2)username添加、删除、更改或查看用户帐号名。
(3)password为用户帐号分配或更改密码。
(4)*提示输入密码。
(5)/domain在计算机主域的主域控制器中执行操作。
简单事例:(1)net user yfang查看用户YFANG的信息

(3)NET USE
作用:连接计算机或断开计算机与共享资源的连接,或显示计算机的连接信息。
命令格式:net use [devicename | *] [computernamesharename[volume]] [password | *]] [/user:[domainname]username] [[/delete] | [/persistent:{yes | no}]]
参数介绍:
键入不带参数的net use列出网络连接。
devicename指定要连接到的资源名称或要断开的设备名称。
computernamesharename服务器及共享资源的名称。
password访问共享资源的密码。
*提示键入密码。
/user指定进行连接的另外一个用户。
domainname指定另一个域。
username指定登录的用户名。
/home将用户连接到其宿主目录。
/delete取消指定网络连接。
/persistent控制永久网络连接的使用。
简单事例:

(1)net use e: YFANGTEMP将YFANGTEMP目录建立为E盘
(2)net use e: YFANGTEMP /delete断开连接

(4)NET TIME
作 用:使计算机的时钟与另一台计算机或域的时间同步。
命令格式:net time [computername | /domain[:name]] [/set]
参数介绍:

(1)computername要检查或同步的服务器名。
(2)/domain[:name]指定要与其时间同步的域。
(3)/set使本计算机时钟与指定计算机或域的时钟同步。
下面的这4个参数是相关的,所以一起介绍

(5)Net Start
作 用:启动服务,或显示已启动服务的列表。
命令格式:net start service

(6)Net Pause
作 用:暂停正在运行的服务。
命令格式:net pause service

(7)Net Continue
作 用:重新激活挂起的服务。
命令格式:net continue service

(8)NET STOP
作 用:停止 Windows NT 网络服务。
命令格式:net stop service

参数介绍:我们来看看这些服务都是什么
(1)alerter(警报)
(2)client service for netware(Netware 客户端服务)
(3)clipbook server(剪贴簿服务器)
(4)computer browser(计算机浏览器)
(5)directory replicator(目录复制器)
(6)ftp publishing service (ftp )(ftp 发行服务)
(7)lpdsvc
(8)net logon(网络登录)
(9)network dde(网络 dde)
(10)network dde dsdm(网络 dde dsdm)
(11)network monitor agent(网络监控代理)
(12)nt lm security support provider(NT LM 安全性支持提供)
(13)ole(对象链接与嵌入)
(14)remote access connection manager(远程访问连接管理器)
(15)remote access isnsap service(远程访问 isnsap 服务)
(16)remote access server(远程访问服务器)
(17)remote procedure call (rpc) locator(远程过程调用定位器)
(18)remote procedure call (rpc) service(远程过程调用服务)
(19)schedule(调度)
(20)server(服务器)
(21)simple tcp/ip services(简单 TCP/IP 服务)
(22)snmp
(23)spooler(后台打印程序)
(24)tcp/ip netbios helper(TCP/IP NETBIOS 辅助工具)
(25)ups
(26)workstation(工作站)
(27)messenger(信使)
(28)dhcp client
(29)eventlog

以下这些SERVICE只能在NT SERVER上使用
(1)file server for macintosh
(2)gateway service for netware
(3)microsoft dhcp server
(4)print server for macintosh
(5)remoteboot
(6)windows internet name service

(9)Net Statistics
作 用:显示本地工作站或服务器服务的统计记录。
命令格式:net statistics [workstation | server]
参数介绍:(1)键入不带参数的net
statistics列出其统计信息可用的运行服务。
(2)workstation显示本地工作站服务的统计信息。
(3)server显示本地服务器服务的统计信息。
简单事例:(1)net statistics server | more显示服务器服务的统计信息

(10)Net Share
作 用:创建、删除或显示共享资源。
命令格式:net share sharename=drive:path [/users:number | /unlimited] [/remark:"text"]
参数介绍:(1)键入不带参数的net
share显示本地计算机上所有共享资源的信息。
(2)sharename是共享资源的网络名称。
(3)drive:path指定共享目录的绝对路径。
(4)/users:number设置可同时访问共享资源的最大用户数。
(5)/unlimited不限制同时访问共享资源的用户数。
(6)/remark:"text "添加关于资源的注释,注释文字用引号引住。
简单事例:(1)net share mylove=c:temp /remark:"my first
share"以mylove为共享名共享C:temp
(2)net share mylove /delete停止共享mylove目录
(11)Net Session
作 用:列出或断开本地计算机和与之连接的客户端的会话,也可以写为net sessions或net sess。
命令格式:net session [computername] [/delete]
参数介绍:(1)键入不带参数的net
session显示所有与本地计算机的会话的信息。
(2)computername标识要列出或断开会话的计算机。

(3)/delete结束与computername计算机会话并关闭本次会话期间计算机的所有进程。
简单事例:(1)net session YFANG要显示计算机名为YFANG的客户端会话信息列表。
(12)Net Send
作 用:向网络的其他用户、计算机或通信名发送消息。
命令格式:net send {name | * | /domain[:name] | /users} message
参数介绍:(1)name要接收发送消息的用户名、计算机名或通信名。
(2)*将消息发送到组中所有名称。
(3)/domain[:name]将消息发送到计算机域中的所有名称。
(4)/users将消息发送到与服务器连接的所有用户。
(5)message作为消息发送的文本。
简单事例:(1)net send /users server will shutdown in 5 minutes.给所有连接到服务器的用户发送消息
(13)Net Print
作 用:显示或控制打印作业及打印队列。
命令格式:net print [computername ] job# [/hold | /release | /delete]
参数介绍:(1)computername共享打印机队列的计算机名。
(2)sharename打印队列名称。
(3)job#在打印机队列中分配给打印作业的标识号。
(4)/hold使用 job# 时,在打印机队列中使打印作业等待。
(5)/release释放保留的打印作业。
(6)/delete从打印机队列中删除打印作业。
简单事例:(1)net print YFANGSEEME列出YFANG计算机上SEEME打印机队列的目录
(14)Net Name
作 用:添加或删除消息名(有时也称别名),或显示计算机接收消息的名称列表。
命令格式:net name [name [/add | /delete]]
参数介绍:(1)键入不带参数的net name列出当前使用的名称。
(2)name指定接收消息的名称。
(3)/add将名称添加到计算机中。
(4)/delete从计算机中删除名称。
(15)Net Localgroup
作 用:添加、显示或更改本地组。
命令格式:net localgroup groupname {/add [/comment:"text "] | /delete} [/domain]
参数介绍:(1)键入不带参数的net
localgroup显示服务器名称和计算机的本地组名称。
(2)groupname要添加、扩充或删除的本地组名称。
(3)/comment: "text "为新建或现有组添加注释。
(4)/domain在当前域的主域控制器中执行操作,否则仅在本地计算机上执行操作?
(5)name [ ...]列出要添加到本地组或从本地组中删除的一个或多个用户名或组名。
(6)/add将全局组名或用户名添加到本地组中。
(7)/delete从本地组中删除组名或用户名。
简单事例:(1)net localgroup love /add将名为love的本地组添加到本地用户帐号数据库
(2)net localgroup love显示love本地组中的用户

(16)Net Group
作 用:在 Windows NT Server 域中添加、显示或更改全局组。
命令格式:net group groupname {/add [/comment:"text "] | /delete} [/domain]
参数介绍:(1)键入不带参数的net group显示服务器名称及服务器的组名称。
(2)groupname要添加、扩展或删除的组。
(3)/comment:"text "为新建组或现有组添加注释。

(4)/domain在当前域的主域控制器中执行该操作,否则在本地计算机上执行操作? ?
(5)username[ ...]列表显示要添加到组或从组中删除的一个或多个用户。
(6)/add添加组或在组中添加用户名。
(7)/delete删除组或从组中删除用户名。
简单事例:(1)net group love yfang1 yfang2 /add将现有用户帐号yfang1和yfang2添加到本地计算机的love组

(17)Net File
作 用:显示某服务器上所有打开的共享文件名及锁定文件数。
命令格式:net file [id [/close]]
参数介绍:(1)键入不带参数的net file获得服务器上打开文件的列表。
(2)id文件标识号。
(3)/close关闭打开的文件并释放锁定记录。

(18)Net Config
作 用:显示当前运行的可配置服务,或显示并更改某项服务的设置。
命令格式:net config [service [options]]
参数介绍:(1)键入不带参数的net config显示可配置服务的列表。
(2)service通过net config命令进行配置的服务(server或workstation)
(3)options服务的特定选项。

(19)Net Computer
作 用:从域数据库中添加或删除计算机。
命令格式:net computer computername {/add | /del}
参数介绍:(1)computername指定要添加到域或从域中删除的计算机。
(2)/add将指定计算机添加到域。
(3)/del将指定计算机从域中删除。

简单事例:(1)net computer cc /add将计算机 cc 添加到登录域

(20)Net Accounts
作 用:更新用户帐号数据库、更改密码及所有帐号的登录要求。
命令格式:net accounts [/forcelogoff:{minutes | no}] [/minpwlen:length] [/maxpwage:{days | unlimited}] [/minpwage:days] [/uniquepw:number] [/domain]
参数介绍:(1)键入不带参数的net
accounts显示当前密码设置、登录时限及域信息。
(2)/forcelogoff:{minutes | no}设置当用户帐号或有效登录时间过期时
(3)/minpwlen:length设置用户帐号密码的最少字符数。
(4)/maxpwage:{days | unlimited}设置用户帐号密码有效的最大天数。
(5)/minpwage:days设置用户必须保持原密码的最小天数。
(6)/uniquepw:number要求用户更改密码时,必须在经过number次后才能重复使用 与之相同的密码。
(7)/domain在当前域的主域控制器上执行该操作。
(8)/sync当用于主域控制器时,该命令使域中所有备份域控制器同步
简单事例:(1)net accounts /minpwlen:7将用户帐号密码的最少字符数设置为7

----------------------上面介绍的是NET命令在WINNT下的基本用法
----------------------下面我们看看NET命令在WIN98下的基本用法

在WIN98中NET命令也有一些参数

其中有一些参数的名字和功能及简单的使用方法和WINNT下的相应的参数的用法相? ?
其中有(1)NET TIME命令
(1)NET PRINT命令
(1)NET USE命令
(1)NET VIEW命令

在WIN98中NET命令有一些参数
其中有一些参数的名字和WINNT下的相应的参数的名字相同但其用法却有些不同
其中有

(1)NET START
作 用:启动相应的服务。(不能在DOS-WIN中用)
命令格式:NET START [BASIC | NWREDIR | WORKSTATION | NETBIND | NETBEUI | NWLINK] [/LIST] [/YES] [/VERBOSE]


(2)NET STOP
作 用:停止相应的服务.(不能在DOS-WIN中用)
命令格式:NET STOP [BASIC | NWREDIR | WORKSTATION | NETBEUI | NWLINK] [/YES]

在WIN98中NET命令还有一些参数是在98下才有的
其中有

(1)NET DIAG
作 用:运行MS的DIAGNOSTICS程序显示网络的DIAGNOSTIC信息
命令格式:NET DIAGNOSTICS [/NAMES | /STATUS]


(2)NET INIT
作 用:不通过绑定来加载协议或网卡驱动(不能在DOS-WIN中用)
命令格式:NET INITIALIZE [/DYNAMIC]

(3)NET LOGOFF
作 用:断开连接的共享资源(不能在DOS-WIN中用)

(4)NET LOGON
作 用:在WORKGROUP中登陆(不能在DOS-WIN中用)
命令格式:NET LOGON [user [password | ?]] [/DOMAIN:name] [/YES] [/SAVEPW:NO]

(5)NET PASSWORD
作 用:更改你的网络登陆口令(不能在DOS-WIN中用)
命令格式:NET PASSWORD computer | /DOMAIN:name [user [oldpassword [newpassword]]]

posted @ 2005-09-13 10:47 rodney 阅读(301) | 评论 (0)编辑 收藏