<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    常用鏈接

    統(tǒng)計(jì)

    最新評(píng)論

    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 九寶 閱讀(399) | 評(píng)論 (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 九寶 閱讀(360) | 評(píng)論 (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 九寶 閱讀(645) | 評(píng)論 (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 九寶 閱讀(255) | 評(píng)論 (0)編輯 收藏

    2011年2月18日 #

    ContentProvider分析

         摘要: ContentProvider何時(shí)創(chuàng)建呢?這是一個(gè)值得深思的問(wèn)題?  據(jù)我這兩天的了解是在你要用到的時(shí)候才會(huì)調(diào)用ContentProvider的onCreate函數(shù)進(jìn)行創(chuàng)建。你就會(huì)什么時(shí)候叫要用到的時(shí)候呢?比如你要查詢或刪除修改數(shù)據(jù)庫(kù)的時(shí)候通過(guò)ContentResolver的quire或delete來(lái)操縱數(shù)據(jù)時(shí)就會(huì)調(diào)用ContentProvider的onCreate函數(shù),若已經(jīng)創(chuàng)建了數(shù)...  閱讀全文

    posted @ 2011-02-18 14:51 九寶 閱讀(1862) | 評(píng)論 (0)編輯 收藏

    2011年2月16日 #

    GestureDetector手勢(shì)識(shí)別類 (轉(zhuǎn))

    View是在onTouchEvent(MotionEvent event)里對(duì)用戶的動(dòng)作做了一定的分析,從而通知我們是發(fā)生了點(diǎn)擊還是長(zhǎng)按等事件。

    我們需要?jiǎng)?chuàng)建一個(gè)GestureDetector的對(duì)象,傳入listener對(duì)象,view接收到的onTouchEvent中將event傳給GestureDetector進(jìn)行分析listener會(huì)回調(diào)給我們相應(yīng)的動(dòng)作。其中GestureDetector.SimpleOnGestureListenerFramework幫我們簡(jiǎn)化了)是實(shí)現(xiàn)了上面提到的OnGestureListenerOnDoubleTapListener兩個(gè)接口的類,我們只需要繼承它并重寫其中我們關(guān)心的回調(diào)即可。

    ,那么,這個(gè)類如何使用呢?以下是使用該類的一個(gè)范例:

    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); 

    /*  有關(guān)上面的 onTouchEvent方法,我們可以直接判斷MotionEvent的類型,

        對(duì)于手勢(shì)移動(dòng)僅僅捕獲ACTION_MOVE即可,

        我們通過(guò)參數(shù)MotionEvent e1, MotionEvent e2,float distanceX, float distanceY可以獲取操作變化。

       比如 distanceX > 0 向右邊移動(dòng),distanceX < 0 則向左邊,distanceY > 0 向上滾動(dòng), distanceY < 0 向下滾動(dòng)。

    */

    }


    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());

      }

    }

     


    更多的回調(diào)消息,方便的對(duì)用戶的動(dòng)作進(jìn)行響應(yīng)

    public interface OnGestureListener {

                    // Touch down時(shí)觸發(fā), edown時(shí)的MotionEvent

                    boolean onDown(MotionEvent e);

                    // Touch down之后一定時(shí)間(115ms)觸發(fā),edown時(shí)的MotionEvent

                    void onShowPress(MotionEvent e);

                    // Touch up時(shí)觸發(fā),eup時(shí)的MotionEvent

                    boolean onSingleTapUp(MotionEvent e);

                    // 滑動(dòng)時(shí)觸發(fā),e1down時(shí)的MotionEvente2move時(shí)的MotionEvent

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

                    // Touch down之后一定時(shí)間(500ms)觸發(fā),edown時(shí)的MotionEvent

                    void onLongPress(MotionEvent e);

                    // 滑動(dòng)一段距離,up時(shí)觸發(fā),e1down時(shí)的MotionEvente2up時(shí)的MotionEvent

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

    } 

    public interface OnDoubleTapListener {

                    // 完成一次單擊,并確定沒(méi)有二擊事件后觸發(fā)(300ms),edown時(shí)的MotionEvent

                    boolean onSingleTapConfirmed(MotionEvent e);

                    // 第二次單擊down時(shí)觸發(fā),e為第一次down時(shí)的MotionEvent

                    boolean onDoubleTap(MotionEvent e);

                    // 第二次單擊down,moveup時(shí)都觸發(fā),e為不同時(shí)機(jī)下的MotionEvent

                    boolean onDoubleTapEvent(MotionEvent e);

    }

    boolean  onDoubleTap(MotionEvent e)
    解釋:雙擊的第二下Touch down時(shí)觸發(fā)
    boolean  onDoubleTapEvent(MotionEvent e)
    解釋:雙擊的第二下Touch down和up都會(huì)觸發(fā),可用e.getAction()區(qū)分。
    boolean  onDown(MotionEvent e)
    解釋:Touch down時(shí)觸發(fā)
    boolean  onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
    解釋:Touch了滑動(dòng)一點(diǎn)距離后,up時(shí)觸發(fā)。
    void  onLongPress(MotionEvent e)
    解釋:Touch了不移動(dòng)一直Touch down時(shí)觸發(fā)
    boolean  onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
    解釋:Touch了滑動(dòng)時(shí)觸發(fā)。
    void  onShowPress(MotionEvent e)
    解釋:Touch了還沒(méi)有滑動(dòng)時(shí)觸發(fā)
    (與onDown,onLongPress比較,onDown只要Touch down一定立刻觸發(fā)。而Touchdown后過(guò)一會(huì)沒(méi)有滑動(dòng)先觸發(fā)onShowPress再是onLongPress。
    所以Touchdown后一直不滑動(dòng),onDown->onShowPress->onLongPress這個(gè)順序觸發(fā)。
    boolean  onSingleTapConfirmed(MotionEvent e)
    boolean  onSingleTapUp(MotionEvent e)
    解釋:上面這兩個(gè)函數(shù)都是在touch down后又沒(méi)有滑動(dòng)(onScroll),又沒(méi)有長(zhǎng)按(onLongPress),然后Touchup時(shí)觸發(fā)。
    點(diǎn)擊一下非常快的(不滑動(dòng))Touchup:
    onDown->onSingleTapUp->onSingleTapConfirmed
    點(diǎn)擊一下稍微慢點(diǎn)的(不滑動(dòng))Touchup:
    onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed


    posted @ 2011-02-16 15:03 九寶 閱讀(540) | 評(píng)論 (0)編輯 收藏

    2011年2月14日 #

    onNewIntent 什么時(shí)候調(diào)用

    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
    一、其他應(yīng)用發(fā)Intent,執(zhí)行下列方法:
    I/@@@philn(12410): onCreate
    I/@@@philn(12410): onStart
    I/@@@philn(12410): onResume

    發(fā)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處于任務(wù)棧的頂端,也就是說(shuō)之前打開過(guò)的Activity,現(xiàn)在處于
    I/@@@philn(12410): onPause
    I/@@@philn(12410): onStop 狀態(tài)的話
    其他應(yīng)用再發(fā)送Intent的話,執(zhí)行順序?yàn)椋?br style="line-height: 22px; " /> I/@@@philn(12410): onNewIntent
    I/@@@philn(12410): onRestart
    I/@@@philn(12410): onStart
    I/@@@philn(12410): onResume

    posted @ 2011-02-14 11:18 九寶 閱讀(6204) | 評(píng)論 (1)編輯 收藏

    2011年2月13日 #

    Observer模式在J2EE中的實(shí)現(xiàn) [http://35java.com/zhibo/forum.php?mod=viewthread&tid=108&extra=page%3D3]

    引言:
                設(shè)計(jì)模式是經(jīng)驗(yàn)的文檔化。它是對(duì)被用來(lái)在特定場(chǎng)景下解決一般設(shè)計(jì)問(wèn)題的類和相互通信的對(duì)象的描述。更通俗的來(lái)說(shuō),它是一個(gè)問(wèn)題/解決方案對(duì)。一旦我們掌握了設(shè)計(jì)模式,就等于擁有了一支強(qiáng)有力的專家隊(duì)伍。它甚至能夠使面向?qū)ο蟮男率掷们叭说慕?jīng)驗(yàn)找出職責(zé)明確的類和對(duì)象,從而獲得優(yōu)雅的解決方案。由于設(shè)計(jì)模式也是重構(gòu)的目標(biāo),如果在設(shè)計(jì)的初期適當(dāng)?shù)匾朐O(shè)計(jì)模式,可以減少重構(gòu)的工作量。
          但是,我們也不能陷入模式的陷阱,為了使用模式而去套模式,那樣會(huì)陷入形式主義。我們?cè)谑褂媚J降臅r(shí)候,一定要注意模式的意圖(intent),而不要過(guò)多的去關(guān)注模式的實(shí)現(xiàn)細(xì)節(jié),因?yàn)檫@些實(shí)現(xiàn)細(xì)節(jié)在特定情況下,可能會(huì)發(fā)生一些改變。不要頑固地認(rèn)為設(shè)計(jì)模式一書中的類圖或?qū)崿F(xiàn)代碼就代表了模式本身。
          下面,我們來(lái)討論一下為什么要在分布式、多層系統(tǒng)中使用Observer模式。
          

    多層體系結(jié)構(gòu)(multi-tier architecture):
                三層體系結(jié)構(gòu)是多層體系結(jié)構(gòu)中最簡(jiǎn)單的一種,它一般包括:
          
    • 表示層(presentation)-窗口、報(bào)表-
    • 業(yè)務(wù)邏輯層(business logic)-管理業(yè)務(wù)過(guò)程的任務(wù)和規(guī)則。它又可以細(xì)分為領(lǐng)域?qū)ο髮樱ù眍I(lǐng)域概念)和服務(wù)層(提供數(shù)據(jù)庫(kù)交互、安全性、打印報(bào)表)。
    • 存儲(chǔ)層(storage)-持久化存儲(chǔ)機(jī)制。如數(shù)據(jù)庫(kù)服務(wù)器等。
                  
    圖一:三層體系結(jié)構(gòu)
                  
          而Java 2平臺(tái)企業(yè)版(J2EE)是一種利用Java 2平臺(tái)來(lái)簡(jiǎn)化諸多與多級(jí)企業(yè)解決方案的開發(fā)、部署和管理相關(guān)的復(fù)雜問(wèn)題的體系結(jié)構(gòu)。它是開放的、基于標(biāo)準(zhǔn)的平臺(tái),用以開發(fā)、部署和管理N層結(jié)構(gòu)、面向Web的,以服務(wù)器為中心的企業(yè)級(jí)應(yīng)用。
          為了支持領(lǐng)域?qū)ο蟮膹?fù)用,并且使領(lǐng)域?qū)ο蟮慕涌谧兏鶐?lái)的影響最小化。我們將領(lǐng)域?qū)樱P停┖捅硎緦樱ㄒ晥D)相分離。
          采用模型-視圖模式的意義在于:
          
    • 支持聚合度更高的模型定義,使模型的定義可以集中在領(lǐng)域過(guò)程的定義,而不是圖形界面上。
    • 允許將模型和用戶界面并行開發(fā)。
    • 使用戶界面的需求變化對(duì)領(lǐng)域?qū)铀斐傻挠绊懽钚』?/li>
    • 允許建立與一個(gè)現(xiàn)有的領(lǐng)域?qū)訉?duì)象相連接的新視圖,同時(shí)不影響領(lǐng)域?qū)印?/li>
    • 允許一個(gè)模型同時(shí)有多個(gè)視圖,例如使用SVG和表格。
    • 允許模型層獨(dú)立于用戶界面層執(zhí)行。
          而這恰恰與Observer模式的意圖相吻合。因此我們有必要跨層來(lái)實(shí)現(xiàn)Observer模式。
          其實(shí),在應(yīng)用中更多的是采用MVC框架來(lái)架構(gòu)整個(gè)企業(yè)應(yīng)用的。在MVC框架中,Model和View之間存在著依賴關(guān)系,是Observer模式的典型應(yīng)用。當(dāng)然MVC框架還包括其它模式如Composite模式和Strategy模式。在J2EE平臺(tái)中,我們可以把Web Tier(包括Jsp和servelet和JavaBean)看作是表示層,EJB Tier看作是領(lǐng)域?qū)印6鴆ontroller可能跨距Web Tier和 EJB Tier。
          在Java類庫(kù)中采用Java.util.Observable類和Java.util.Observer接口來(lái)實(shí)現(xiàn)Observer模式,它們?cè)趩蝹€(gè)的Java VM.中運(yùn)行的很好,但如果想在EJB中使用它們就會(huì)有一些問(wèn)題。這正如我們引言中提到的,模式的具體實(shí)現(xiàn)在特定情況下,可能會(huì)發(fā)生一些改變。
          

    值傳遞還是遠(yuǎn)程引用傳遞?
                        值傳遞:        
    在Java RMI中要求所有的參數(shù)和返回類型是JAVA的基本類型或?qū)崿F(xiàn)Java.io.Serilizable的對(duì)象。串行化對(duì)象通過(guò)值傳遞(又名拷貝傳遞),而不是引用傳遞,這意味著在某一層中串行化對(duì)象的更并不自動(dòng)影響到其它的對(duì)象。      
                  遠(yuǎn)程引用傳遞:        
    對(duì)于EJB對(duì)象而言,它由兩個(gè)接口(home接口和remote接口)和一個(gè)類組成。容器會(huì)根據(jù)ejb規(guī)范來(lái)生成實(shí)現(xiàn)上面兩個(gè)接口的類(我們分別稱為xxxEJBHome對(duì)象和xxxEjbObject對(duì)象)。在較多的容器的實(shí)現(xiàn)方案中,xxxEJBHome對(duì)象使用了factory模式來(lái)創(chuàng)建xxxEjbObject對(duì)象;xxxEjbObject對(duì)象則采用proxy模式,作為xxxBean的代理類。在生成以上兩個(gè)對(duì)象的同時(shí),容器會(huì)從部署文件中讀取關(guān)于安全、事務(wù)、持久性等服務(wù)并在xxxEjbObject對(duì)象和xxxEJBHome對(duì)象中添加以上服務(wù)的代碼。而且xxxEJBHome對(duì)象和xxxEjbObject對(duì)象都是分布式對(duì)象,我們?cè)诖酥挥懻搙xxEjbObject對(duì)象。所謂分布式對(duì)象,從本質(zhì)上來(lái)講,分為3個(gè)部分:object server、skeleton、stub。其中object server和skeleton位于服務(wù)器端,而stub位于客戶端。Object server負(fù)責(zé)實(shí)現(xiàn)業(yè)務(wù)邏輯,skeleton負(fù)責(zé)marshal和unmarshal方法簽名。      
                  
    圖二:分布式對(duì)象
                  
          顯然,EJB的客戶(調(diào)用EJB的對(duì)象)可以是任何對(duì)象,包括EJB和一般的Java類甚至是用任何語(yǔ)言寫的corba客戶端。
          從EJB的客戶視角來(lái)看的話,我們只能看到一個(gè)home接口、一個(gè)remote接口(對(duì)于實(shí)體bean的話,還可以看見一個(gè)主鍵類,而bean類對(duì)客戶是不可見的)。但我們從上面的論述,我們可以知道,對(duì)于remote接口中地方法調(diào)用,實(shí)際上是多態(tài)地調(diào)用XXX_Stub類。即XXX_Stub對(duì)象對(duì)客戶具有可見性(但這種可見性是透明的,即客戶不知道這種可見性的存在)。由于,XXX_Stub對(duì)象和Object Server實(shí)現(xiàn)了相同的接口,并且Object server真正實(shí)現(xiàn)了業(yè)務(wù)邏輯。所以,當(dāng)在客戶端調(diào)用XXX_Stub對(duì)象的方法時(shí)候,XXX_Stub對(duì)象通過(guò)socket通信機(jī)制將方法簽名傳給XXX_Skeleton對(duì)象,XXX_Skeleton對(duì)象在去委托Object Server完成業(yè)務(wù)處理邏輯。因此,Object Server本身發(fā)生了改變。我們稱XXX_Stub對(duì)象是Object Server對(duì)象的遠(yuǎn)程引用,并認(rèn)為當(dāng)分布式對(duì)象作為參數(shù)傳遞的時(shí)候,是通過(guò)引用傳遞的(會(huì)產(chǎn)生副作用

    posted @ 2011-02-13 19:24 九寶 閱讀(422) | 評(píng)論 (0)編輯 收藏

    RMI的定義(轉(zhuǎn))http://blog.csdn.net/ocean181/archive/2010/09/02/5857273.aspx

    RMI的定義

    Java RMI (Remote Method Invocation 遠(yuǎn)程方法調(diào)用)是用Java在JDK1.1中實(shí)現(xiàn)的,它大大增強(qiáng)了Java開發(fā)分布式應(yīng)用的能力。Java作為一種風(fēng)靡一時(shí)的網(wǎng)絡(luò)開發(fā)語(yǔ)言,其巨大的威力就體現(xiàn)在它強(qiáng)大的開發(fā)分布式網(wǎng)絡(luò)應(yīng)用的能力上,而RMI就是開發(fā)百分之百純Java的網(wǎng)絡(luò)分布式應(yīng)用系統(tǒng)的核心解決方案之一。其實(shí)它可以被看作是RPC的Java版本。但是傳統(tǒng)RPC并不能很好地應(yīng)用于分布式對(duì)象系統(tǒng)。而Java RMI 則支持存儲(chǔ)于不同地址空間的程序級(jí)對(duì)象之間彼此進(jìn)行通信,實(shí)現(xiàn)遠(yuǎn)程對(duì)象之間的無(wú)縫遠(yuǎn)程調(diào)用。

    RMI目前使用Java遠(yuǎn)程消息交換協(xié)議JRMP(Java Remote Messaging Protocol)進(jìn)行通信。JRMP是專為Java的遠(yuǎn)程對(duì)象制定的協(xié)議。因此,Java RMI具有Java的“Write Once,Run Anywhere”的優(yōu)點(diǎn),是分布式應(yīng)用系統(tǒng)的百分之百純Java解決方案。用Java RMI開發(fā)的應(yīng)用系統(tǒng)可以部署在任何支持JRE(Java Run Environment Java,運(yùn)行環(huán)境)的平臺(tái)上。但由于JRMP是專為Java對(duì)象制定的,因此,RMI對(duì)于用非Java語(yǔ)言開發(fā)的應(yīng)用系統(tǒng)的支持不足。不能與用非Java語(yǔ)言書寫的對(duì)象進(jìn)行通信。

    RMI與CORBA的關(guān)系

    RMI 和CORBA常被視為相互競(jìng)爭(zhēng)技術(shù),因?yàn)閮烧叨继峁?duì)遠(yuǎn)程分布式對(duì)象的透明訪問(wèn)。但這兩種技術(shù)實(shí)際上是相互補(bǔ)充的,一者的長(zhǎng)處正好可以彌補(bǔ)另一者的短處。RMI 和 CORBA 的結(jié)合產(chǎn)生了 RMI-IIOP,RMI-IIOP 是企業(yè)服務(wù)器端 Java 開發(fā)的基礎(chǔ)

    1997 年,IBM 和 Sun Microsystems啟動(dòng)了一項(xiàng)旨在促進(jìn) Java 作為企業(yè)開發(fā)技術(shù)的發(fā)展的合作計(jì)劃。兩家公司特別著力于如何將 Java 用作服務(wù)器端語(yǔ)言,生成可以結(jié)合進(jìn)現(xiàn)有體系結(jié)構(gòu)的企業(yè)級(jí)代碼。所需要的就是一種遠(yuǎn)程傳輸技術(shù),它兼有 Java 的 RMI(Remote Method Invocation,遠(yuǎn)程方法調(diào)用)較少的資源占用量和更成熟的 CORBA(Common Object Request Broker Architecture,公共對(duì)象請(qǐng)求代理體系結(jié)構(gòu))技術(shù)的健壯性。出于這一需要,RMI-IIOP問(wèn)世了,它幫助將 Java 語(yǔ)言推向了目前服務(wù)器端企業(yè)開發(fā)的主流語(yǔ)言的領(lǐng)先地位。

    RMI的組成

    一個(gè)正常工作的RMI系統(tǒng)由下面幾個(gè)部分組成:

    1、遠(yuǎn)程服務(wù)的接口定義

    2、遠(yuǎn)程服務(wù)接口的具體實(shí)現(xiàn)

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

    4、一個(gè)運(yùn)行遠(yuǎn)程服務(wù)的服務(wù)器

    5、一個(gè)RMI命名服務(wù),它允許客戶端去發(fā)現(xiàn)這個(gè)遠(yuǎn)程服務(wù)

    6、類文件的提供者(一個(gè)HTTP或者FTP服務(wù)器)

    7、一個(gè)需要這個(gè)遠(yuǎn)程服務(wù)的客戶端程序

    RMI的實(shí)現(xiàn)

    下面我們一步一步建立一個(gè)簡(jiǎn)單的RMI系統(tǒng)。首先在你的機(jī)器里建立一個(gè)新的文件夾,以便放置我們創(chuàng)建的文件,為了簡(jiǎn)單起見,我們只使用一個(gè)文件夾存放客戶端和服務(wù)端代碼,并且在同一個(gè)目錄下運(yùn)行服務(wù)端和客戶端。

    如果所有的RMI文件都已經(jīng)設(shè)計(jì)好了,那么你需要下面的幾個(gè)步驟去生成你的系統(tǒng):

    1、   編寫并且編譯接口的Java代碼
    2、   編寫并且編譯接口實(shí)現(xiàn)的Java代碼
    3、   從接口實(shí)現(xiàn)類中生成 Stub 和 Skeleton 類文件
    4、   編寫遠(yuǎn)程服務(wù)的主運(yùn)行程序
    5、   編寫RMI的客戶端程序
    6、   安裝并且運(yùn)行RMI系統(tǒng)

    1、接口

    第一步就是建立和編譯服務(wù)接口的Java代碼。這個(gè)接口定義了所有的提供遠(yuǎn)程服務(wù)的功能,下面是源程序:

       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. }


    注意,這個(gè)接口繼承自Remote,每一個(gè)定義的方法都必須拋出一個(gè)RemoteException異常對(duì)象。

    建立這個(gè)文件,把它存放在剛才的目錄下,并且編譯。

    >javac Calculator.java

    2、接口的具體實(shí)現(xiàn)

    下一步,我們就要寫遠(yuǎn)程服務(wù)的具體實(shí)現(xiàn),這是一個(gè)CalculatorImpl類文件:

       1. //CalculatorImpl.java
       2. //Implementation
       3. import java.rmi.server.UnicastRemoteObject;
       4.
       5. public class CalculatorImpl extends UnicastRemoteObject implements Calculator
       6. {
       7.
       8.     // 這個(gè)實(shí)現(xiàn)必須有一個(gè)顯式的構(gòu)造函數(shù),并且要拋出一個(gè)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. }


    同樣的,把這個(gè)文件保存在你的目錄里然后編譯他。

    這個(gè)實(shí)現(xiàn)類使用了UnicastRemoteObject去聯(lián)接RMI系統(tǒng)。在我們的例子中,我們是直接的從UnicastRemoteObject 這個(gè)類上繼承的,事實(shí)上并不一定要這樣做,如果一個(gè)類不是從UnicastRmeoteObject上繼承,那必須使用它的exportObject() 方法去聯(lián)接到RMI。

    如果一個(gè)類繼承自UnicastRemoteObject,那么它必須提供一個(gè)構(gòu)造函數(shù)并且聲明拋出一個(gè)RemoteException對(duì)象。當(dāng)這個(gè)構(gòu)造函數(shù)調(diào)用了super(),它久激活UnicastRemoteObject中的代碼完成RMI的連接和遠(yuǎn)程對(duì)象的初始化。

    3、Stubs 和Skeletons

    下一步就是要使用RMI編譯器rmic來(lái)生成樁和框架文件,這個(gè)編譯運(yùn)行在遠(yuǎn)程服務(wù)實(shí)現(xiàn)類文件上。

    >rmic CalculatorImpl

    在你的目錄下運(yùn)行上面的命令,成功執(zhí)行完上面的命令你可以發(fā)現(xiàn)一個(gè)Calculator_stub.class文件,如果你是使用的Java2SDK,那么你還可以發(fā)現(xiàn)Calculator_Skel.class文件。

    4、主機(jī)服務(wù)器

    遠(yuǎn)程RMI服務(wù)必須是在一個(gè)服務(wù)器中運(yùn)行的。CalculatorServer類是一個(gè)非常簡(jiǎn)單的服務(wù)器。

       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. }


    建立這個(gè)服務(wù)器程序,然后保存到你的目錄下,并且編譯它。

    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);
                }
           }
       }

    保存這個(gè)客戶端程序到你的目錄下(注意這個(gè)目錄是一開始建立那個(gè),所有的我們的文件都在那個(gè)目錄下),并且編譯他。

    6、運(yùn)行RMI系統(tǒng)

    現(xiàn)在我們建立了所有運(yùn)行這個(gè)簡(jiǎn)單RMI系統(tǒng)所需的文件,現(xiàn)在我們終于可以運(yùn)行這個(gè)RMI系統(tǒng)啦!來(lái)享受吧。

    我們是在命令控制臺(tái)下運(yùn)行這個(gè)系統(tǒng)的,你必須開啟三個(gè)控制臺(tái)窗口,一個(gè)運(yùn)行服務(wù)器,一個(gè)運(yùn)行客戶端,還有一個(gè)運(yùn)行RMIRegistry。

    首先運(yùn)行注冊(cè)程序RMIRegistry,你必須在包含你剛寫的類的那么目錄下運(yùn)行這個(gè)注冊(cè)程序。

    >rmiregistry

    好,這個(gè)命令成功的話,注冊(cè)程序已經(jīng)開始運(yùn)行了,不要管他,現(xiàn)在切換到另外一個(gè)控制臺(tái),在第二個(gè)控制臺(tái)里,我們運(yùn)行服務(wù)器CalculatorService,因?yàn)镽MI的安全機(jī)制將在服務(wù)端發(fā)生作用,所以你必須增加一條安全策略。以下是對(duì)應(yīng)安全策略的例子
    grant {
    permission java.security.AllPermission "", "";
    };

    注意:這是一條最簡(jiǎn)單的安全策略,它允許任何人做任何事,對(duì)于你的更加關(guān)鍵性的應(yīng)用,你必須指定更加詳細(xì)安全策略。

    現(xiàn)在為了運(yùn)行服務(wù)端,你需要除客戶類(CalculatorClient.class)之外的所有的類文件。確認(rèn)安全策略在policy.txt文件之后,使用如下命令來(lái)運(yùn)行服務(wù)器。

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

    這個(gè)服務(wù)器就開始工作了,把接口的實(shí)現(xiàn)加載到內(nèi)存等待客戶端的聯(lián)接。好現(xiàn)在切換到第三個(gè)控制臺(tái),啟動(dòng)我們的客戶端。

    為了在其他的機(jī)器運(yùn)行客戶端程序你需要一個(gè)遠(yuǎn)程接口(Calculator.class) 和一個(gè)stub(CalculatorImpl_Stub.class)。 使用如下命令運(yùn)行客戶端

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

    如果所有的這些都成功運(yùn)行,你應(yīng)該看到下面的輸出:
    1
    9
    18
    3

    如果你看到了上面的輸出,恭喜你,你成功了,你已經(jīng)成功的創(chuàng)建了一個(gè)RMI系統(tǒng),并且使他正確工作了。即使你運(yùn)行在同一個(gè)計(jì)算機(jī)上,RMI還是使用了你的網(wǎng)絡(luò)堆棧和TCP/IP去進(jìn)行通訊,并且是運(yùn)行在三個(gè)不同的Java虛擬機(jī)上。這已經(jīng)是一個(gè)完整的RMI系統(tǒng)。

    posted @ 2011-02-13 18:46 九寶 閱讀(258) | 評(píng)論 (0)編輯 收藏

    JavaBean PropertyChange 之設(shè)計(jì)模式Observer(轉(zhuǎn))

         摘要: java語(yǔ)言里包含了許多對(duì)設(shè)計(jì)模式的直接支持,如command模式,agent模式,observer模式等。雖然java提供的對(duì)這些模式的支持很簡(jiǎn)單,不能滿足比較復(fù)雜的應(yīng)用。但在簡(jiǎn)單的場(chǎng)景下,使用這些類往往能夠得到立桿見影的效果。所以,如果沒(méi)有什么特殊需求,還是最好利用java的這些類。         Observ...  閱讀全文

    posted @ 2011-02-13 18:26 九寶 閱讀(941) | 評(píng)論 (0)編輯 收藏

    僅列出標(biāo)題  下一頁(yè)
    主站蜘蛛池模板: 国产偷国产偷亚洲高清人| 国产又大又黑又粗免费视频| 亚洲色图视频在线观看| 你懂的免费在线观看网站| 亚洲精品无码高潮喷水在线| 99久久成人国产精品免费| 亚洲韩国精品无码一区二区三区| 精品久久久久久无码免费| 亚洲精品乱码久久久久久自慰| 中国一级特黄高清免费的大片中国一级黄色片 | 久久综合九色综合97免费下载| 亚洲va国产va天堂va久久| 久久er国产精品免费观看2| 国产成A人亚洲精V品无码性色| 久久精品国产免费一区| 亚洲四虎永久在线播放| 69免费视频大片| 亚洲一区中文字幕在线观看| 一二三四免费观看在线电影 | 精品久久8x国产免费观看| 亚洲国产精品专区| 妞干网在线免费视频| 色天使亚洲综合一区二区| 亚洲成av人片天堂网老年人| 一级做a免费视频观看网站| 亚洲精品国精品久久99热一| 免费日本一区二区| 亚洲激情电影在线| 久久久久国色AV免费看图片| 亚洲国产成人久久综合| 免费播放特黄特色毛片| selaoban在线视频免费精品| 无码乱人伦一区二区亚洲一| 日本h在线精品免费观看| 亚洲欧美日韩中文无线码| 大胆亚洲人体视频| 国产免费区在线观看十分钟| 亚洲电影一区二区| 一二三四影视在线看片免费 | 亚洲av永久无码精品国产精品| 91精品免费国产高清在线|