常用链接

统计

最新评论

2012年4月21日 #

Create Struts 2 Application in Eclipse : HTTP Status 500

http://viralpatel.net/blogs/2009/12/tutorial-create-struts-2-application-eclipse-example.html 

problem:

HTTP Status 500 

java.lang.NullPointerException 	
org.apache.struts2.impl.StrutsActionProxy.getErrorMessage(StrutsActionProxy.java:69)
com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:185)
resolve problem:
1. struts.xml should under src
2. in struts.xml:  
<action name="login" method="excute"
class="net.viralpatel.struts2.LoginAction">

posted @ 2012-04-21 02:41 九宝 阅读(393) | 评论 (0)编辑 收藏

2011年12月7日 #

How to check file properties through WMI command line (fw)

How to check file properties through WMI command line

24.Sep.2009 | by Gusac | Filed in: Articles, Tutorials

With the lack of Graphical Interface on Windows 2008 Core server there comes a need of performing a lot of task through command line. One of which is checking file properties like file version, path, product verision etc. Luckily we have a command that makes this task simple. On a side note, We can also run the same command on other operating systems like Windows Xp, 2003, vista.

Here is the command:
wmic datafile where name='c:\\windows\\system32\\notepad.exe'

Click here to view the enlarged screenshot

Notice that we have used two backslashes \\ in the file path. Also, notice that the path is enclosed in the single quotes.
The output will be confusing to read in command prompt window. To read and understand it better, we can take the output in text format and read it in notepad.

While doing so, please do NOT wrap the text.
wmic datafile where name='c:\\windows\\system32\\notepad.exe' > out.txt

Click here to view the enlarged screenshot

The output will reveal the file properties like Hidden, Path, Drive, Version Caption, Access rights etc.

To get one particular property of a file we need to modify the command a little bit. We need to use the GET Alias injunction to the command mentioned above. Let's say we want to check the version for the file notepad.exe. The command that is used for this is:
wmic datafile where name='c:\\windows\\system32\\notepad.exe' get version

Similarily, there is a list of properties that can be fetched through this command line. They are:

Access Rights
Caption
Class Name
Compressed
Compression Method
Computer System Class Name
Computer System Name
Creation Date
Current File Open Count
Description
Drive
Eight Dot Three File Name
Encrypted
Encryption Method
File Extension
File Name
File System Class Name
File System Name
File Type
Hidden
Install Date
Last Accessed
Last Modified
Manufacturer
Name
Path
Readable
Should Be Archived
Size
Status
System File
Version
Writeable

posted @ 2011-12-07 22:29 九宝 阅读(348) | 评论 (0)编辑 收藏

2011年9月16日 #

Windows Authentication

from http://www.iis.net/ConfigReference/system.webServer/security/authentication/windowsAuthentication

Overview

The <windowsAuthentication> element defines configuration settings for the Internet Information Services (IIS) 7 Windows authentication module. You can use Windows authentication when your IIS 7 server runs on a corporate network that is using Microsoft Active Directory service domain identities or other Windows accounts to identify users. Because of this, you can use Windows authentication whether or not your server is a member of an Active Directory domain.

Windows authentication (formerly named NTLM, and also referred to as Windows NT Challenge/Response authentication) is a secure form of authentication because the user name and password are hashed before being sent across the network. When you enable Windows authentication, the client browser sends a strongly hashed version of the password in a cryptographic exchange with your Web server.

Windows authentication supports two authentication protocols, Kerberos and NTLM, which are defined in the <providers> element. When you install and enable Windows authentication on IIS 7, the default protocol is Kerberos. The <windowsAuthentication> element can also contain a useKernelMode attribute that configures whether to use the kernel mode authentication feature that is new to Windows Server 2008.

Windows authentication is best suited for an intranet environment for the following reasons:

  • Client computers and Web servers are in the same domain.
  • Administrators can make sure that every client browser is Internet Explorer 2.0 or later.
  • HTTP proxy connections, which are not supported by NTLM, are not required.
  • Kerberos version 5 requires a connection to Active Directory, which is not feasible in an Internet environment.

New in IIS 7.5

The <extendedProtection> element was introduced in IIS 7.5, which allows you to configure the settings for the new extended protection features that have been integrated into Windows authentication.

Compatibility

Version Notes
IIS 7.5 The <extendedProtection> element was added in IIS 7.5.
IIS 7.0 The <windowsAuthentication> element was introduced in IIS 7.0.
IIS 6.0 The <windowsAuthentication> element replaces portions of the IIS 6.0 AuthType and AuthFlags metabase properties.

Setup

The default installation of IIS 7 does not include the Windows authentication role service. To use Windows authentication on IIS, you must install the role service, disable Anonymous authentication for your Web site or application, and then enable Windows authentication for the site or application.

Note: After you install the role service, IIS 7 commits the following configuration settings to the ApplicationHost.config file.

<windowsAuthentication enabled="false" />

Windows Server 2008 or Windows Server 2008 R2

  1. On the taskbar, click Start, point to Administrative Tools, and then click Server Manager.
  2. In the Server Manager hierarchy pane, expand Roles, and then click Web Server (IIS).
  3. In the Web Server (IIS) pane, scroll to the Role Services section, and then click Add Role Services.
  4. On the Select Role Services page of the Add Role Services Wizard, select Windows Authentication, and then click Next.
  5. On the Confirm Installation Selections page, click Install.
  6. On the Results page, click Close.

Windows Vista or Windows 7

  1. On the taskbar, click Start, and then click Control Panel.
  2. In Control Panel, click Programs and Features, and then click Turn Windows Features on or off.
  3. Expand Internet Information Services, then World Wide Web Services, then Security.
  4. Select Windows Authentication, and then click OK.

How To

How to enable Windows authentication for a Web site, Web application, or Web service

  1. Open Internet Information Services (IIS) Manager:
    • If you are using Windows Server 2008 or Windows Server 2008 R2:
      • On the taskbar, click Start, point to Administrative Tools, and then click Internet Information Services (IIS) Manager.
    • If you are using Windows Vista or Windows 7:
      • On the taskbar, click Start, and then click Control Panel.
      • Double-click Administrative Tools, and then double-click Internet Information Services (IIS) Manager.
  2. In the Connections pane, expand the server name, expand Sites, and then the site, application, or Web service for which you want to enable Windows authentication.
  3. Scroll to the Security section in the Home pane, and then double-click Authentication.
  4. In the Authentication pane, select Windows Authentication, and then click Enable in the Actions pane.

How to enable Extended Protection for Windows authentication

  1. Open Internet Information Services (IIS) Manager:
    • If you are using Windows Server 2008 or Windows Server 2008 R2:
      • On the taskbar, click Start, point to Administrative Tools, and then click Internet Information Services (IIS) Manager.
    • If you are using Windows Vista or Windows 7:
      • On the taskbar, click Start, and then click Control Panel.
      • Double-click Administrative Tools, and then double-click Internet Information Services (IIS) Manager.
  2. In the Connections pane, expand the server name, expand Sites, and then the site, application, or Web service for which you want to enable Extended Protection for Windows authentication.
  3. Scroll to the Security section in the Home pane, and then double-click Authentication.
  4. In the Authentication pane, select Windows Authentication.
  5. Click Enable in the Actions pane.
  6. Click Advanced Settings in the Actions pane.
  7. When the Advanced Settings dialog box appears, select one of the following options in the Extended Protection drop-down menu:
    • Select Accept if you want to enable extended protection while providing down-level support for clients that do not support extended protection.
    • Select Required if you want to enable extended protection without providing down-level support.
  8. Click OK to close the Advanced Settings dialog box.

Configuration

The <windowsAuthentication> element is configurable at the site, application, or virtual directory level in the ApplicationHost.config file.

Attributes

Attribute Description
authPersistNonNTLM Optional Boolean attribute.

Specifies whether IIS automatically reauthenticates every non-NTLM (for example, Kerberos) request, even those on the same connection. False enables multiple authentications for the same connections.

Note: A setting of true means that the client will be authenticated only once on the same connection. IIS will cache a token or ticket on the server for a TCP session that stays established.

The default is false.
authPersistSingleRequest Optional Boolean attribute.

Setting this flag to true specifies that authentication persists only for a single request on a connection. IIS resets the authentication at the end of each request, and forces reauthentication on the next request of the session.

The default value is false.
enabled Required Boolean attribute.

Specifies whether Windows authentication is enabled.

The default value is false.
useKernelMode Optional Boolean attribute.

Specifies whether Windows authentication is done in kernel mode. True specifies that Windows authentication uses kernel mode.

Kernel-mode authentication may improve authentication performance and prevent authentication problems with application pools that are configured to use a custom identity.

As a best practice, do not disable this setting if you use Kerberos authentication and have a custom identity on the application pool.

The default is true.

Child Elements

Element Description
extendedProtection Optional element.

Specifies extended protection options for Windows authentication.

Note: This element was added in IIS 7.5.
providers Optional element.

Specifies security support providers used for Windows authentication.

Configuration Sample

The following default <windowsAuthentication> element is configured at the root ApplicationHost.config file in IIS 7.0, and disables Windows authentication by default. It also defines the two Windows authentication providers for IIS 7.0.

<windowsAuthentication enabled="false">
   <providers>
      <add value="Negotiate" />
      <add value="NTLM" />
   </providers>
</windowsAuthentication>

The following example enables Windows authentication and disables Anonymous authentication for a Web site named Contoso.

<location path="Contoso">
   <system.webServer>
      <security>
         <authentication>
            <anonymousAuthentication enabled="false" />
            <windowsAuthentication enabled="true" />
         </authentication>
      </security>
   </system.webServer>
</location>

Sample Code

The following examples disable Anonymous authentication for a site named Contoso, then enable Windows authentication for the site.

AppCmd.exe

appcmd.exe set config "Contoso" -section:system.webServer/security/authentication/anonymousAuthentication /enabled:"False" /commit:apphost

appcmd.exe set config "Contoso" -section:system.webServer/security/authentication/windowsAuthentication /enabled:"True" /commit:apphost

Note: You must be sure to set the commit parameter to apphost when you use AppCmd.exe to configure these settings. This commits the configuration settings to the appropriate location section in the ApplicationHost.config file.

C#

using System;
using System.Text;
using Microsoft.Web.Administration;

internal static class Sample {

   private static void Main() {

      using(ServerManager serverManager = new ServerManager()) { 
         Configuration config = serverManager.GetApplicationHostConfiguration();

         ConfigurationSection anonymousAuthenticationSection = config.GetSection("system.webServer/security/authentication/anonymousAuthentication", "Contoso");
         anonymousAuthenticationSection["enabled"] = false;

         ConfigurationSection windowsAuthenticationSection = config.GetSection("system.webServer/security/authentication/windowsAuthentication", "Contoso");
         windowsAuthenticationSection["enabled"] = true;

         serverManager.CommitChanges();
      }
   }
}

VB.NET

Imports System
Imports System.Text
Imports Microsoft.Web.Administration

Module Sample
   Sub Main()
      Dim serverManager As ServerManager = New ServerManager
      Dim config As Configuration = serverManager.GetApplicationHostConfiguration

      Dim anonymousAuthenticationSection As ConfigurationSection = config.GetSection("system.webServer/security/authentication/anonymousAuthentication", "Contoso")
      anonymousAuthenticationSection("enabled") = False

      Dim windowsAuthenticationSection As ConfigurationSection = config.GetSection("system.webServer/security/authentication/windowsAuthentication", "Contoso")
      windowsAuthenticationSection("enabled") = True

      serverManager.CommitChanges()
   End Sub
End Module

JavaScript

var adminManager = new ActiveXObject('Microsoft.ApplicationHost.WritableAdminManager');
adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST";

var anonymousAuthenticationSection = adminManager.GetAdminSection("system.webServer/security/authentication/anonymousAuthentication", "MACHINE/WEBROOT/APPHOST/Contoso");
anonymousAuthenticationSection.Properties.Item("enabled").Value = false;

var windowsAuthenticationSection = adminManager.GetAdminSection("system.webServer/security/authentication/windowsAuthentication", "MACHINE/WEBROOT/APPHOST/Contoso");
windowsAuthenticationSection.Properties.Item("enabled").Value = true;

adminManager.CommitChanges();

VBScript

Set adminManager = CreateObject("Microsoft.ApplicationHost.WritableAdminManager")
adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST"

Set anonymousAuthenticationSection = adminManager.GetAdminSection("system.webServer/security/authentication/anonymousAuthentication", "MACHINE/WEBROOT/APPHOST/Contoso")
anonymousAuthenticationSection.Properties.Item("enabled").Value = False

Set windowsAuthenticationSection = adminManager.GetAdminSection("system.webServer/security/authentication/windowsAuthentication", "MACHINE/WEBROOT/APPHOST/Contoso")
windowsAuthenticationSection.Properties.Item("enabled").Value = True

adminManager.CommitChanges()

posted @ 2011-09-16 21:46 九宝 阅读(640) | 评论 (0)编辑 收藏

How To Determine if Your Computer Is 32-Bit or 64-Bit(forward)

how to check window version

run: Winver


Here's How:
  1. Open the System Information

    Open the Start menu, and click on Programs -> Accessories -> System Tools -> System Information

     

  2. Look in the System Summary

    The System Information tool will display detailed information about your Windows operating system. Once opened it will show the "System Summary" – it’s an overview of your computer and operating system.

  3. Look for the System Type Item

    On the right hand side of the window you will see a list of items. Look for the item called "System Type".

    The value of this item will tell you whether your computer is 32-bit or 64-bit:

    • x86-based PC: It’s a 32-bit computer.
    • x64-based PC: It’s a 64-bit computer.

     

posted @ 2011-09-16 03:34 九宝 阅读(249) | 评论 (0)编辑 收藏

2011年2月18日 #

ContentProvider分析

     摘要: ContentProvider何时创建呢?这是一个值得深思的问题?  据我这两天的了解是在你要用到的时候才会调用ContentProvider的onCreate函数进行创建。你就会什么时候叫要用到的时候呢?比如你要查询或删除修改数据库的时候通过ContentResolver的quire或delete来操纵数据时就会调用ContentProvider的onCreate函数,若已经创建了数...  阅读全文

posted @ 2011-02-18 14:51 九宝 阅读(1856) | 评论 (0)编辑 收藏

2011年2月16日 #

GestureDetector手势识别类 (转)

View是在onTouchEvent(MotionEvent event)里对用户的动作做了一定的分析,从而通知我们是发生了点击还是长按等事件。

我们需要创建一个GestureDetector的对象,传入listener对象,view接收到的onTouchEvent中将event传给GestureDetector进行分析listener会回调给我们相应的动作。其中GestureDetector.SimpleOnGestureListenerFramework帮我们简化了)是实现了上面提到的OnGestureListenerOnDoubleTapListener两个接口的类,我们只需要继承它并重写其中我们关心的回调即可。

,那么,这个类如何使用呢?以下是使用该类的一个范例:

private GestureDetector mGestureDetector;

@Override

public void onCreate(Bundle savedInstanceState) {


  super.onCreate(savedInstanceState);


  mGestureDetector = new GestureDetector(this, new MyGestureListener());


}


@Override

public boolean onTouchEvent(MotionEvent event) {

 return mGestureDetector.onTouchEvent(event); 

/*  有关上面的 onTouchEvent方法,我们可以直接判断MotionEvent的类型,

    对于手势移动仅仅捕获ACTION_MOVE即可,

    我们通过参数MotionEvent e1, MotionEvent e2,float distanceX, float distanceY可以获取操作变化。

   比如 distanceX > 0 向右边移动,distanceX < 0 则向左边,distanceY > 0 向上滚动, distanceY < 0 向下滚动。

*/

}


class MyGestureListener extends GestureDetector.SimpleOnGestureListener{

  @Override

  public boolean onSingleTapUp(MotionEvent ev) {

    Log.d("onSingleTapUp",ev.toString());

    return true;

  }


  @Override

  public void onShowPress(MotionEvent ev) {

    Log.d("onShowPress",ev.toString());

  }


  @Override

  public void onLongPress(MotionEvent ev) {

    Log.d("onLongPress",ev.toString());

  }

}

 


更多的回调消息,方便的对用户的动作进行响应

public interface OnGestureListener {

                // Touch down时触发, edown时的MotionEvent

                boolean onDown(MotionEvent e);

                // Touch down之后一定时间(115ms)触发,edown时的MotionEvent

                void onShowPress(MotionEvent e);

                // Touch up时触发,eup时的MotionEvent

                boolean onSingleTapUp(MotionEvent e);

                // 滑动时触发,e1down时的MotionEvente2move时的MotionEvent

                boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);

                // Touch down之后一定时间(500ms)触发,edown时的MotionEvent

                void onLongPress(MotionEvent e);

                // 滑动一段距离,up时触发,e1down时的MotionEvente2up时的MotionEvent

                boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);

} 

public interface OnDoubleTapListener {

                // 完成一次单击,并确定没有二击事件后触发(300ms),edown时的MotionEvent

                boolean onSingleTapConfirmed(MotionEvent e);

                // 第二次单击down时触发,e为第一次down时的MotionEvent

                boolean onDoubleTap(MotionEvent e);

                // 第二次单击down,moveup时都触发,e为不同时机下的MotionEvent

                boolean onDoubleTapEvent(MotionEvent e);

}

boolean  onDoubleTap(MotionEvent e)
解释:双击的第二下Touch down时触发
boolean  onDoubleTapEvent(MotionEvent e)
解释:双击的第二下Touch down和up都会触发,可用e.getAction()区分。
boolean  onDown(MotionEvent e)
解释:Touch down时触发
boolean  onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
解释:Touch了滑动一点距离后,up时触发。
void  onLongPress(MotionEvent e)
解释:Touch了不移动一直Touch down时触发
boolean  onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
解释:Touch了滑动时触发。
void  onShowPress(MotionEvent e)
解释:Touch了还没有滑动时触发
(与onDown,onLongPress比较,onDown只要Touch down一定立刻触发。而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。
所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。
boolean  onSingleTapConfirmed(MotionEvent e)
boolean  onSingleTapUp(MotionEvent e)
解释:上面这两个函数都是在touch down后又没有滑动(onScroll),又没有长按(onLongPress),然后Touchup时触发。
点击一下非常快的(不滑动)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
点击一下稍微慢点的(不滑动)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed


posted @ 2011-02-16 15:03 九宝 阅读(532) | 评论 (0)编辑 收藏

2011年2月14日 #

onNewIntent 什么时候调用

protected void onNewIntent (Intent intent)

Since: API Level 1

This is called for activities that set launchMode to "singleTop" in their package, or if a client used theFLAG_ACTIVITY_SINGLE_TOP flag when calling startActivity(Intent). In either case, when the activity is re-launched while at the top of the activity stack instead of a new instance of the activity being started, onNewIntent() will be called on the existing instance with the Intent that was used to re-launch it.

An activity will always be paused before receiving a new intent, so you can count on onResume() being called after this method.

Note that getIntent() still returns the original Intent. You can use setIntent(Intent) to update it to this new Intent.


在IntentActivity中重写下列方法:onCreate onStart onRestart  onResume  onPause onStop onDestroy  onNewIntent
一、其他应用发Intent,执行下列方法:
I/@@@philn(12410): onCreate
I/@@@philn(12410): onStart
I/@@@philn(12410): onResume

发Intent的方法:
Uri uri = Uri.parse("philn://blog.163.com");
Intent it = new Intent(Intent.ACTION_VIEW, uri);    
startActivity(it);

二、接收Intent声明:
 <activity android:name=".IntentActivity" android:launchMode="singleTask"
                  android:label="@string/testname">
             <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="philn"/>
            </intent-filter>
  </activity>

三、如果IntentActivity处于任务栈的顶端,也就是说之前打开过的Activity,现在处于
I/@@@philn(12410): onPause
I/@@@philn(12410): onStop 状态的话
其他应用再发送Intent的话,执行顺序为:
I/@@@philn(12410): onNewIntent
I/@@@philn(12410): onRestart
I/@@@philn(12410): onStart
I/@@@philn(12410): onResume

posted @ 2011-02-14 11:18 九宝 阅读(6200) | 评论 (1)编辑 收藏

2011年2月13日 #

Observer模式在J2EE中的实现 [http://35java.com/zhibo/forum.php?mod=viewthread&tid=108&extra=page%3D3]

引言:
            设计模式是经验的文档化。它是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述。更通俗的来说,它是一个问题/解决方案对。一旦我们掌握了设计模式,就等于拥有了一支强有力的专家队伍。它甚至能够使面向对象的新手利用前人的经验找出职责明确的类和对象,从而获得优雅的解决方案。由于设计模式也是重构的目标,如果在设计的初期适当地引入设计模式,可以减少重构的工作量。
      但是,我们也不能陷入模式的陷阱,为了使用模式而去套模式,那样会陷入形式主义。我们在使用模式的时候,一定要注意模式的意图(intent),而不要过多的去关注模式的实现细节,因为这些实现细节在特定情况下,可能会发生一些改变。不要顽固地认为设计模式一书中的类图或实现代码就代表了模式本身。
      下面,我们来讨论一下为什么要在分布式、多层系统中使用Observer模式。
      

多层体系结构(multi-tier architecture):
            三层体系结构是多层体系结构中最简单的一种,它一般包括:
      
  • 表示层(presentation)-窗口、报表-
  • 业务逻辑层(business logic)-管理业务过程的任务和规则。它又可以细分为领域对象层(代表领域概念)和服务层(提供数据库交互、安全性、打印报表)。
  • 存储层(storage)-持久化存储机制。如数据库服务器等。
              
图一:三层体系结构
              
      而Java 2平台企业版(J2EE)是一种利用Java 2平台来简化诸多与多级企业解决方案的开发、部署和管理相关的复杂问题的体系结构。它是开放的、基于标准的平台,用以开发、部署和管理N层结构、面向Web的,以服务器为中心的企业级应用。
      为了支持领域对象的复用,并且使领域对象的接口变更所带来的影响最小化。我们将领域层(模型)和表示层(视图)相分离。
      采用模型-视图模式的意义在于:
      
  • 支持聚合度更高的模型定义,使模型的定义可以集中在领域过程的定义,而不是图形界面上。
  • 允许将模型和用户界面并行开发。
  • 使用户界面的需求变化对领域层所造成的影响最小化。
  • 允许建立与一个现有的领域层对象相连接的新视图,同时不影响领域层。
  • 允许一个模型同时有多个视图,例如使用SVG和表格。
  • 允许模型层独立于用户界面层执行。
      而这恰恰与Observer模式的意图相吻合。因此我们有必要跨层来实现Observer模式。
      其实,在应用中更多的是采用MVC框架来架构整个企业应用的。在MVC框架中,Model和View之间存在着依赖关系,是Observer模式的典型应用。当然MVC框架还包括其它模式如Composite模式和Strategy模式。在J2EE平台中,我们可以把Web Tier(包括Jsp和servelet和JavaBean)看作是表示层,EJB Tier看作是领域层。而controller可能跨距Web Tier和 EJB Tier。
      在Java类库中采用Java.util.Observable类和Java.util.Observer接口来实现Observer模式,它们在单个的Java VM.中运行的很好,但如果想在EJB中使用它们就会有一些问题。这正如我们引言中提到的,模式的具体实现在特定情况下,可能会发生一些改变。
      

值传递还是远程引用传递?
                    值传递:        
在Java RMI中要求所有的参数和返回类型是JAVA的基本类型或实现Java.io.Serilizable的对象。串行化对象通过值传递(又名拷贝传递),而不是引用传递,这意味着在某一层中串行化对象的更并不自动影响到其它的对象。      
              远程引用传递:        
对于EJB对象而言,它由两个接口(home接口和remote接口)和一个类组成。容器会根据ejb规范来生成实现上面两个接口的类(我们分别称为xxxEJBHome对象和xxxEjbObject对象)。在较多的容器的实现方案中,xxxEJBHome对象使用了factory模式来创建xxxEjbObject对象;xxxEjbObject对象则采用proxy模式,作为xxxBean的代理类。在生成以上两个对象的同时,容器会从部署文件中读取关于安全、事务、持久性等服务并在xxxEjbObject对象和xxxEJBHome对象中添加以上服务的代码。而且xxxEJBHome对象和xxxEjbObject对象都是分布式对象,我们在此只讨论xxxEjbObject对象。所谓分布式对象,从本质上来讲,分为3个部分:object server、skeleton、stub。其中object server和skeleton位于服务器端,而stub位于客户端。Object server负责实现业务逻辑,skeleton负责marshal和unmarshal方法签名。      
              
图二:分布式对象
              
      显然,EJB的客户(调用EJB的对象)可以是任何对象,包括EJB和一般的Java类甚至是用任何语言写的corba客户端。
      从EJB的客户视角来看的话,我们只能看到一个home接口、一个remote接口(对于实体bean的话,还可以看见一个主键类,而bean类对客户是不可见的)。但我们从上面的论述,我们可以知道,对于remote接口中地方法调用,实际上是多态地调用XXX_Stub类。即XXX_Stub对象对客户具有可见性(但这种可见性是透明的,即客户不知道这种可见性的存在)。由于,XXX_Stub对象和Object Server实现了相同的接口,并且Object server真正实现了业务逻辑。所以,当在客户端调用XXX_Stub对象的方法时候,XXX_Stub对象通过socket通信机制将方法签名传给XXX_Skeleton对象,XXX_Skeleton对象在去委托Object Server完成业务处理逻辑。因此,Object Server本身发生了改变。我们称XXX_Stub对象是Object Server对象的远程引用,并认为当分布式对象作为参数传递的时候,是通过引用传递的(会产生副作用

posted @ 2011-02-13 19:24 九宝 阅读(413) | 评论 (0)编辑 收藏

RMI的定义(转)http://blog.csdn.net/ocean181/archive/2010/09/02/5857273.aspx

RMI的定义

Java RMI (Remote Method Invocation 远程方法调用)是用Java在JDK1.1中实现的,它大大增强了Java开发分布式应用的能力。Java作为一种风靡一时的网络开发语言,其巨大的威力就体现在它强大的开发分布式网络应用的能力上,而RMI就是开发百分之百纯Java的网络分布式应用系统的核心解决方案之一。其实它可以被看作是RPC的Java版本。但是传统RPC并不能很好地应用于分布式对象系统。而Java RMI 则支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。

RMI目前使用Java远程消息交换协议JRMP(Java Remote Messaging Protocol)进行通信。JRMP是专为Java的远程对象制定的协议。因此,Java RMI具有Java的“Write Once,Run Anywhere”的优点,是分布式应用系统的百分之百纯Java解决方案。用Java RMI开发的应用系统可以部署在任何支持JRE(Java Run Environment Java,运行环境)的平台上。但由于JRMP是专为Java对象制定的,因此,RMI对于用非Java语言开发的应用系统的支持不足。不能与用非Java语言书写的对象进行通信。

RMI与CORBA的关系

RMI 和CORBA常被视为相互竞争技术,因为两者都提供对远程分布式对象的透明访问。但这两种技术实际上是相互补充的,一者的长处正好可以弥补另一者的短处。RMI 和 CORBA 的结合产生了 RMI-IIOP,RMI-IIOP 是企业服务器端 Java 开发的基础

1997 年,IBM 和 Sun Microsystems启动了一项旨在促进 Java 作为企业开发技术的发展的合作计划。两家公司特别着力于如何将 Java 用作服务器端语言,生成可以结合进现有体系结构的企业级代码。所需要的就是一种远程传输技术,它兼有 Java 的 RMI(Remote Method Invocation,远程方法调用)较少的资源占用量和更成熟的 CORBA(Common Object Request Broker Architecture,公共对象请求代理体系结构)技术的健壮性。出于这一需要,RMI-IIOP问世了,它帮助将 Java 语言推向了目前服务器端企业开发的主流语言的领先地位。

RMI的组成

一个正常工作的RMI系统由下面几个部分组成:

1、远程服务的接口定义

2、远程服务接口的具体实现

3、桩(Stub)和框架(Skeleton)文件

4、一个运行远程服务的服务器

5、一个RMI命名服务,它允许客户端去发现这个远程服务

6、类文件的提供者(一个HTTP或者FTP服务器)

7、一个需要这个远程服务的客户端程序

RMI的实现

下面我们一步一步建立一个简单的RMI系统。首先在你的机器里建立一个新的文件夹,以便放置我们创建的文件,为了简单起见,我们只使用一个文件夹存放客户端和服务端代码,并且在同一个目录下运行服务端和客户端。

如果所有的RMI文件都已经设计好了,那么你需要下面的几个步骤去生成你的系统:

1、   编写并且编译接口的Java代码
2、   编写并且编译接口实现的Java代码
3、   从接口实现类中生成 Stub 和 Skeleton 类文件
4、   编写远程服务的主运行程序
5、   编写RMI的客户端程序
6、   安装并且运行RMI系统

1、接口

第一步就是建立和编译服务接口的Java代码。这个接口定义了所有的提供远程服务的功能,下面是源程序:

   1. //Calculator.java
   2. //define the interface
   3. import java.rmi.Remote;
   4.
   5. public interface Calculator extends Remote
   6. {
   7.     public long add(long a, long b)
   8.         throws java.rmi.RemoteException;
   9.
  10.     public long sub(long a, long b)
  11.         throws java.rmi.RemoteException;
  12.
  13.     public long mul(long a, long b)
  14.         throws java.rmi.RemoteException;
  15.
  16.     public long div(long a, long b)
  17.         throws java.rmi.RemoteException;
  18. }


注意,这个接口继承自Remote,每一个定义的方法都必须抛出一个RemoteException异常对象。

建立这个文件,把它存放在刚才的目录下,并且编译。

>javac Calculator.java

2、接口的具体实现

下一步,我们就要写远程服务的具体实现,这是一个CalculatorImpl类文件:

   1. //CalculatorImpl.java
   2. //Implementation
   3. import java.rmi.server.UnicastRemoteObject;
   4.
   5. public class CalculatorImpl extends UnicastRemoteObject implements Calculator
   6. {
   7.
   8.     // 这个实现必须有一个显式的构造函数,并且要抛出一个RemoteException异常
   9.     public CalculatorImpl()
  10.         throws java.rmi.RemoteException {
  11.         super();
  12.      }
  13.
  14.     public long add(long a, long b)
  15.         throws java.rmi.RemoteException {
  16.         return a + b;
  17.      }
  18.
  19.     public long sub(long a, long b)
  20.         throws java.rmi.RemoteException {
  21.         return a - b;
  22.      }
  23.
  24.     public long mul(long a, long b)
  25.         throws java.rmi.RemoteException {
  26.         return a * b;
  27.      }
  28.
  29.     public long div(long a, long b)
  30.         throws java.rmi.RemoteException {
  31.         return a / b;
  32.      }
  33. }


同样的,把这个文件保存在你的目录里然后编译他。

这个实现类使用了UnicastRemoteObject去联接RMI系统。在我们的例子中,我们是直接的从UnicastRemoteObject 这个类上继承的,事实上并不一定要这样做,如果一个类不是从UnicastRmeoteObject上继承,那必须使用它的exportObject() 方法去联接到RMI。

如果一个类继承自UnicastRemoteObject,那么它必须提供一个构造函数并且声明抛出一个RemoteException对象。当这个构造函数调用了super(),它久激活UnicastRemoteObject中的代码完成RMI的连接和远程对象的初始化。

3、Stubs 和Skeletons

下一步就是要使用RMI编译器rmic来生成桩和框架文件,这个编译运行在远程服务实现类文件上。

>rmic CalculatorImpl

在你的目录下运行上面的命令,成功执行完上面的命令你可以发现一个Calculator_stub.class文件,如果你是使用的Java2SDK,那么你还可以发现Calculator_Skel.class文件。

4、主机服务器

远程RMI服务必须是在一个服务器中运行的。CalculatorServer类是一个非常简单的服务器。

   1. //CalculatorServer.java
   2. import java.rmi.Naming;
   3.
   4. public class CalculatorServer {
   5.
   6.    public CalculatorServer() {
   7.      try {
   8.         Calculator c = new CalculatorImpl();
   9.        Naming.rebind("rmi://localhost:1099/CalculatorService", c);
  10.       } catch (Exception e) {
  11.        System.out.println("Trouble: " + e);
  12.       }
  13.     }
  14.
  15.    public static void main(String args[]) {
  16.      new CalculatorServer();
  17.     }
  18. }


建立这个服务器程序,然后保存到你的目录下,并且编译它。

5、客户端

客户端源代码如下:

   //CalculatorClient.java
   
    import java.rmi.Naming;
    import java.rmi.RemoteException;
    import java.net.MalformedURLException;
   import java.rmi.NotBoundException;
   
   public class CalculatorClient {
   
       public static void main(String[] args) {
         try {
             Calculator c = (Calculator)
                              Naming.lookup(
                    "rmi://localhost
                            /CalculatorService");
               System.out.println( c.sub(4, 3) );
            System.out.println( c.add(4, 5) );
               System.out.println( c.mul(3, 6) );
              System.out.println( c.div(9, 3) );
            }
           catch (MalformedURLException murle) {
               System.out.println();
              System.out.println(
                 "MalformedURLException");
               System.out.println(murle);
            }
           catch (RemoteException re) {
              System.out.println();
               System.out.println(
                          "RemoteException");
               System.out.println(re);
           }
          catch (NotBoundException nbe) {
              System.out.println();
               System.out.println(
                          "NotBoundException");
               System.out.println(nbe);
            }
           catch (
               java.lang.ArithmeticException
                                         ae) {
              System.out.println();
              System.out.println(
               "java.lang.ArithmeticException");
             System.out.println(ae);
            }
       }
   }

保存这个客户端程序到你的目录下(注意这个目录是一开始建立那个,所有的我们的文件都在那个目录下),并且编译他。

6、运行RMI系统

现在我们建立了所有运行这个简单RMI系统所需的文件,现在我们终于可以运行这个RMI系统啦!来享受吧。

我们是在命令控制台下运行这个系统的,你必须开启三个控制台窗口,一个运行服务器,一个运行客户端,还有一个运行RMIRegistry。

首先运行注册程序RMIRegistry,你必须在包含你刚写的类的那么目录下运行这个注册程序。

>rmiregistry

好,这个命令成功的话,注册程序已经开始运行了,不要管他,现在切换到另外一个控制台,在第二个控制台里,我们运行服务器CalculatorService,因为RMI的安全机制将在服务端发生作用,所以你必须增加一条安全策略。以下是对应安全策略的例子
grant {
permission java.security.AllPermission "", "";
};

注意:这是一条最简单的安全策略,它允许任何人做任何事,对于你的更加关键性的应用,你必须指定更加详细安全策略。

现在为了运行服务端,你需要除客户类(CalculatorClient.class)之外的所有的类文件。确认安全策略在policy.txt文件之后,使用如下命令来运行服务器。

> java -Djava.security.policy=policy.txt CalculatorServer

这个服务器就开始工作了,把接口的实现加载到内存等待客户端的联接。好现在切换到第三个控制台,启动我们的客户端。

为了在其他的机器运行客户端程序你需要一个远程接口(Calculator.class) 和一个stub(CalculatorImpl_Stub.class)。 使用如下命令运行客户端

> java -Djava.security.policy=policy.txt CalculatorClient

如果所有的这些都成功运行,你应该看到下面的输出:
1
9
18
3

如果你看到了上面的输出,恭喜你,你成功了,你已经成功的创建了一个RMI系统,并且使他正确工作了。即使你运行在同一个计算机上,RMI还是使用了你的网络堆栈和TCP/IP去进行通讯,并且是运行在三个不同的Java虚拟机上。这已经是一个完整的RMI系统。

posted @ 2011-02-13 18:46 九宝 阅读(252) | 评论 (0)编辑 收藏

JavaBean PropertyChange 之设计模式Observer(转)

     摘要: java语言里包含了许多对设计模式的直接支持,如command模式,agent模式,observer模式等。虽然java提供的对这些模式的支持很简单,不能满足比较复杂的应用。但在简单的场景下,使用这些类往往能够得到立杆见影的效果。所以,如果没有什么特殊需求,还是最好利用java的这些类。         Observ...  阅读全文

posted @ 2011-02-13 18:26 九宝 阅读(930) | 评论 (0)编辑 收藏

仅列出标题  下一页