企业网站 phpcmswordpress 插件权限
web/
2025/10/6 1:10:44/
文章来源:
企业网站 phpcms,wordpress 插件权限,网站公司架构,博物馆网站做的好的【0】README
1#xff09;本文文字描述转自 core java volume 2#xff0c; 旨在学习 java分布式对象——远程方法中的参数和返回值远程对象激活 的相关知识#xff1b;
【1】远程方法中的参数和返回值
1#xff09; 在开始进行远程方法调用时#xff0c;调用参数需要从…【0】README
1本文文字描述转自 core java volume 2 旨在学习 java分布式对象——远程方法中的参数和返回值远程对象激活 的相关知识
【1】远程方法中的参数和返回值
1 在开始进行远程方法调用时调用参数需要从客户端的虚拟机中移动到服务器的虚拟机中。 2 对于从一个虚拟机向另一个虚拟机传值我们将其区分成两种情况传递远程对象和传递非远程对象。 【1.1】传递远程对象
1当一个对远程对象的引用从一个虚拟机传递到另一个虚拟机时该远程对象的发送者和接收者都将持有一个对同一个实体的引用。这个引用并非是一个内存位置内存位置在单个虚拟机内才有意义而是由网络地址和该远程对象的唯一标识符构成的。这个信息给封装在存根对象中。
1.1 需要始终牢记的是 在远程引用上的方法调用明显比在本地引用上的方法调用执行得慢并且潜在地也更不可靠。 【1.2】传递非远程对象
Conclusion总结一下在虚拟机之间传递值有两种机制
c1实现了Remote接口 的类的对象将作为远程引用传递c2实现了Serializable接口 但是没有实现Remote接口的类的对象将使用序列化进行复制
Attention
A1这两种机制都是自动化的而且不需要任何程序员的干预。A2请记住序列化对于大型对象来说会比较慢而且远程方法不能改变被序列化的参数。A3当然你可以通过传递远程引用来避免这些问题。但是这么做代价太大 在远程引用上调用方法与调用本地方法相比代价高得多。A4意识到这些开销有助于在设计远程服务时进行选择。
1看个荔枝 我们的下一个示例程序将展示远程和可序列化对象的传递。我们将Warehouse接口修改为代码11-5的样子如果给定关键词列表这个仓库将返回最佳匹配的Product。 public interface Warehouse extends Remote { double getPrice(String description) throws RemoteException; Product getProduct(List keywords) throws RemoteException; } // getProduct方法的参数具有List类型。因此参数值必须属于实现了List接口的可序列化的类例如ArrayList。 Attention Product类是可序列化的服务器构建了一个Product对象而客户端获取了它的一个副本参见图11-7。 【1.3】动态类加载
1应用背景关键词列表发送到了服务器而且仓库也返回了Product类的一个实例。当然客户端程序在编译时需要Product.class类文件。但是只要我们的服务器程序无法找到关键词的匹配它就会返回一件肯定让每个人都很高兴的产品《Java核心技术》这本书。这个对象是Book类的实例而Book类是Product的子类。 2problemsolution
2.1problem 当客户端编译时它也许从未看到过Book类。但是在运行时它需要能够执行覆盖了Product方法的Book方法这说明客户端需要拥有在运行时加载额外类的能力。2.2solution 客户端使用了与RMI注册表相同的机制即类由web服务器提供服务RMI服务器类将URL传递给客户端客户端创建要求下载这些类的HTTP请求。
3problemsolution
3.1problem 只要一个程序从网络位置加载新的代码就会涉及安全问题。3.2solution正是由于这个原因我们需要在动态加载类的RMI应用中使用安全管理器。
4 安装安全管理器使用RMI的程序应该安装一个安全管理器去控制动态加载类的行为。可以用下面的指令安装 System.setSecurityManager(new SecurityManager()); 5problemsolution
5.1problem 默认情况下SecurityManager会限制程序中所有的代码去建立网络连接但是我们的程序需要建立到三个远程位置的网络连接connection c1加载远程类的Web服务器c2 RMI注册表c3远程对象5.2solution为了允许这些操作需要提供一个策略文件。5.3看个荔枝 下面的策略文件允许一个应用建立任何到端口号至少为1024的某个端口的网络连接。RMI端口默认为1099远程对象使用的端口也大于等于1024。我们使用8080端口来下载类。 grant { permission java.net.SocketPermission “*:1024-65535”, “connect”; }; 6需要通过将java.security.policy属性设置为这个策略文件名来指示安全管理器去读取该策略文件。
6.1可以使用下面这个调用 System.setProperty(“java.security.policy”, “rmi.policy”); 6.2或者可以在命令行指定系统属性设置 -Djava.security.policyrmi.policy
7为了运行示范程序请确保已经关闭了在前面的示范程序中启动的RMI注册表、Web服务器和服务器程序。打开四个控制台窗口然后执行下面的步骤
7.1 编译接口、实现、客户端和服务器类的源文件。 javac *.java7.2 创建三个目录client、server和download然后按下面这样组装它们 client/ WarehouseClient.class Warehouse.class Product.class client.policy server/ Warehouse.class Product.class Book.class WarehouseImpl.class WarehouseServer.class server.policy download/ Warehouse.class Product.class Book.class 7.3 在第一个控制台窗口中转到download目录下启动NanoHTTP7.4 在第二个控制台窗口中转到server目录下启动服务器 java -Djava.rmi.server.codebasehttp://localhost:8080/ WarehouseServer7.5 在第三个控制台窗口中转到client目录下运行客户端
8看个荔枝
远程对象传送全部源代码参见https://github.com/pacosonTang/core-java-volume/tree/master/coreJavaAdvanced/chapter11/rmi_transfer 【1.4】具有多重接口的远程引用远程类实现多个接口
1可以使用instanceof操作符来查看一个特定的远程对象是否实现了某个接口。假设我们通过一个类型为Warehouse的变量得到了一个远程对象 Warehouse location product.getLocation(); 2这个远程对象可能是一个服务中心但也可能不是。要确定到底是不是可以使用下面的测试 if (location instanceof ServiceCenter) 3如果测试通过就可以将location转型为ServiceCenter并调用getReturnAuthorization方法。 【1.5】远程对象与 equalshashCode 和 clone 方法
1 插入集中的对象必须覆写equals方法。如果是散列集或散列映射表则需定义hashCode方法。 2不能在远程接口中定义equals方法 和 hashCode 方法然而比较远程对象时有一个问题。如果要比较两个远程对象是否具有相同的内容调用equals则必须联系包含这些对象的服务器然后比较它们的内容。而该调用可能会失败。但是Object类中的equals方法并未声明会抛出RemoteException异常而远程接口中的所有方法都必须抛出该异常。因为子类的方法不能比它覆写的父类的方法抛出更多的异常所以不能在远程接口中定义equals方法。hashCode也是这样。 3存根对象的equals 方法 和 hashCode 方法 相反存根对象的equals和hashCode方法只是查看远程对象的位置。只要它们指向相同的远程对象equals方法就认为两个存根相同。 Conclusion总之可以使用集与散列表中的远程引用但是必须记住对它们进行等价测试以及散列计算并不会考虑远程对象的内容。你不能直接克隆远程引用。 【2】 远程对象激活延迟构造远程对象
1激活机制 激活机制activation允许延迟构造远程对象仅当至少有一个客户端调用远程对象上的远程方法时才真正去构造该远程对象。 干货——激活机制定义 2引用激活机制的client 和 server
2.1client要享用激活机制的好处客户端代码完全无需改动。客户端只是简单的请求一个远程引用然后通过它进行调用而已。2.2server然而服务器程序则需由一个激活程序来代替。该程序构造了对象的激活描述符activation descriptors这样的对象可以延迟构造并且该程序通过命名服务为远程方法调用绑定了接收者。第一次对这样的对象进行方法调用时激活描述符中的信息将会用来构造该对象。
3应用激活机制的远程对象 必须继承Activatable类而不是UnicastRemoteObject类当然还需实现一个或多个远程接口。例如 class WarehouseImpl extends Activatable implements Warehouse { … } 4因为对象的构造是延迟进行的所以它必须以标准方式实现。因此构造器必须包含以下两个参数params
p1一个激活ID只需传递给父类的构造器p2一个包含所有构造信息的对象包装为MarshalledObject4.1在构建激活描述符时需要像下面这样从构造信息中构造一个MarshalledObject MarshalledObject param new MarshalledObject(constructionInfo);4.2在实现对象的构造器中使用MarshalledObject类的get方法来获得反序列化之后的构造信息 T constructionInfo param.get();
5看个荔枝为了演示激活我们修改了WarehouseImpl类使得构造信息是一个由描述和价格构成的映射表。这个信息被包装到了MarshalledObject中并且在构造器中被拆包出来
public WarehouseImpl(ActivationID id, MarshalledObjectMapString, Double param)
throws RemoteException, ClassNotFoundException, IOException
{
super(id, 0);
prices param.get();
System.out.println(Warehouse implementation constructed.);
}
5.1将0作为父类构造器的第二个参数 代表RMI类库应该分配一个合适的端口号作为监听端口。构造器会打印一个信息这样就可以看到所需的产品对象已经被激活了。Attention 其实远程对象不是一定要继承Activatable类例如可以将下面的静态方法调用放在服务器类的构造器中。 Activatable.exportObject(this, id, 0) 6如何构建激活程序
step1需要定义一个激活组。一个激活组描述了启动远程对象所在的虚拟机所需的公共参数其中最重要的参数是安全策略。step2 然后如下构造一个激活组描述符 Properties props new Properties(); props.put(“java.security.policy”, “/server/server.policy”); ActivationGroupDesc group new ActivationGroupDesc(props, null); //第二个参数描述了一个特殊的命令选项在这个例子中不需要任何选项所以我们传递了一个null引用。 step3创建一个组ID ActivationGroupID id ActivationGroup.getSystem().registerGroup(groupstep4 构造一个激活描述符了。对于需要构造的每一个对象都应该包括以下内容contents c1激活组ID对象将在与其对应的虚拟机上被构造c2类的名字例如”ProductImpl”或”com.mycompany.MyClassImpl”c3 URL字符串由该URL加载类文件。这应该是基本URL不含包的路径c4编组后的构造信息。
7看个荔枝 MarshalledObject param new MarshalledObject(constructionInfo); ActivationDesc desc new ActivationDesc(id, “WarehouseImpl”, “http://myserver.com/download/“, param); 7.1将此描述符传递给静态的Activatable.register方法。它返回一个对象该对象实现了实现类的远程接口。可以使用命名服务绑定该对象 Warehouse centralWarehouse (Warehouse) Activatable.register(desc); namingContext.bind(“rmi:central_warehouse”, centralWarehouse); Attention 与前例的服务器程序不同激活程序在注册与绑定激活接收者之后就会退出。仅当远程方法调用第一次发生时才会构造远程对象。
8荔枝
8.1启动远程对象激活程序可按一下steps 进行 step1 编译所有文件step2发布类文件 client/ WarehouseClient.class Warehouse.class server/ WarehouseActivator.class Warehouse.class WarehouseImpl.class server.policy download/ Warehouse.class NanoHTTPD.java rmi/ rmid.policy step3启动RMI注册表 step4在rmi目录中启动 RMI激活守护程序 rmid -J-Djava.security.policyrmid.policy rmid程序监听激活请求并且激活另一个虚拟机中的对象。要启动一个虚拟机rmid 程序需要一定的权限。这些权限都在一个策略文件中说明了。使用-J 可以传递一个选项给运行激活守护程序的虚拟机 step5在download 目录中启动NanoHTTPD Web 服务器 step6 从server目录运行激活程序 java -Djava.rmi.server.codebasehttp://localhost:8080/ WarehouseActivator step7 从client目录运行客户端程序
Attention 上述结果是可以正确查找远程对象但是当调用Warehouse接口的实现类的getPrice 方法的时候却抛出了异常搞了一下午我确实无能为力了先留在这里以后有机会再来解决。。
相关命令行指令如下
rmid -J-Djava.security.policyrmid.policy
java com.corejava.chapter11.activation.download.NanoHTTPDMain
java -Djava.rmi.server.codebasehttp://localhost:8080/ com.corejava.chapter11.activation.server.WarehouseActivator for full source code, please visit https://github.com/pacosonTang/core-java-volume/tree/master/coreJavaAdvanced/chapter11/activation
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/87655.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!