`
alienj
  • 浏览: 77530 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论
阅读更多

25章. 远程

 


Seam 提供了一个从网页远程访问组件的方便的方法,使用AJAX (Asynchronous Javascript and XML)。 框架提供的这个功能几乎不需要前期的开发工作——你的组件只需简单地注释成通过AJAX访问就可以了。本章描述构建启用AJAX的网页的必要步骤,然后,继续详细解释Seam远程框架的功能。

 

25.1. 配置

 

为了使用远程, 首先必须在你的web.xml文件配置Seam资源servlet :

 

<servlet>

 

  <servlet-name>Seam Resource Servlet</servlet-name>

 

  <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>

 

</servlet>

 

 

<servlet-mapping>

 

  <servlet-name>Seam Resource Servlet</servlet-name>

 

  <url-pattern>/seam/resource/*</url-pattern>

 

</servlet-mapping>

 

下一步是导入必要的Javascript到你的网页。至少有两个脚本必须导入。第一个包含启用远程功能的所有客户边框架:

 

<script type="text/javascript" src="seam/resource/remoting/resource/remote.js"></script>

 

第二个脚本包含你希望调用的组件的存根和类型定义。它通常动态地建立在你的组件的本地接口上,包括所有可以被用来调用接口的远程方法的类的类型定义。脚本的名字引用你组件的名字。例如,你有一个用@Name("customerAction")注释的无状态会话bean,那么你的脚本标签应该是这样:

 

<script type="text/javascript" 

 

          src="seam/resource/remoting/interface.js?customerAction"></script>

 

如果你希望从同一个网页访问多个组件,那么包括它们所有都作为你脚本标签的参数:

 

<script type="text/javascript" 

 

        src="seam/resource/remoting/interface.js?customerAction&accountAction"></script>

 

另外,你可以使用s:remote 标签导入需要的Javascript。 用逗号分隔你希望导入的每个组件或类名:

 

  <s:remote include="customerAction,accountAction"/>    

 

25.2.  "Seam" 对象

 

客户边与你的组件交互完全通过Seam Javascript对象处理 。这个对象被定义在remote.js 中,你可以用它来与你组件做异步调用。它被分划成两个功能区; Seam.Component包含操纵组件的方法, Seam.Remoting包含执行远程请求的方法。 熟悉这个对象最容易的方法是从一个简单例子开始。

 

25.2.1. 一个 Hello World 例子

 

让我们浏览一个例子,了解Seam对象如何工作。首先,让我们创建一个名为helloAction的新Seam组件。

 

@Stateless

 

@Name("helloAction")

 

public class HelloAction implements HelloLocal {

 

    public String sayHello(String name) {

 

        return "Hello, " + name;

 

    }

 

}

你也需要为我们的新组件创建一个本地接口——特别要注意@WebRemote注释, 因为要使我们的方法成为通过远程可访的这是必需的:

@Local

 

public interface HelloLocal {

 

  @WebRemote

 

  public String sayHello(String name);

 

}

这就是所有我们需要编写的服务边代码。现在,对我们的网页——创建一个新的页面并导入helloAction组件:

 

<s:remote include="helloAction"/>

 

为使这成为一个完全互动的用户体验,让我们增加一个按钮到我们的页面:

 

<button onclick="javascript:sayHello()">Say Hello</button>

 

我们也需要增加一些脚本,在点击我们的按钮时,使它真正地能做某些事情:

 

<script type="text/javascript">

 

  //<![CDATA[

 

 

 

  function sayHello() {

 

    var name = prompt("What is your name?");

 

    Seam.Component.getInstance("helloAction").sayHello(name, sayHelloCallback);

 

  }

 

  function sayHelloCallback(result) {

 

    alert(result);

 

  }

 

   // ]]>

 

</script>

 

我们就大功告成了! 部署你的应用程序,浏览你的页面。点击按钮,在提示时输入一个名字。一个消息框将显示hello消息,确认调用成功。如果你想节约一些时间,你可以在Seam的 /examples/remoting/helloworld目录找到Hello World例子的源代码。

 

那么,我们脚本代码究竟做了什么?让我们将它分成小块。开始,你可以从Javascript代码清单看见我们已实现的两个方法——第一方法负责提示用户输入他们的名字,然后执行了一个远程请求。看一看下面的行:

 

Seam.Component.getInstance("helloAction").sayHello(name, sayHelloCallback);

 

这行的第一部分, Seam.Component.getInstance("helloAction") 返回一个代理,或者我们的helloAction 组件的"存根(stub)"。 根据这个存根,我们可以调用我们组件的方法,这行的剩余部分sayHello(name, sayHelloCallback);它又究竟做了什么?

 

这行代码唯一做的事情是通过传递name参数调用我们组件的sayHello方法。第二个参数sayHelloCallback并不是我们组件的sayHello方法的参数,它却通知Seam远程框架一旦它收到我们请求的响应,它应该传递它到sayHelloCallback Javascript方法。这个回调参数完全是可选的,如果你调用一个使用void返回类型的方法或者你不关心结果,你随时可抛弃它。

 

sayHelloCallback方法,一旦收到我们远程请求的响应,那么弹出一个警告消息,显示我们方法调用的结果。

 

25.2.2. Seam.Component

 

Seam.Component Javascript对象提供了一些客户边方法操纵你的Seam组件。 两个主要的方法是newInstance()和getInstance() ,描述在下面章节。它们的主要区别是newInstance()总会创建一个新的组件类型的实例,而 getInstance() 会返回一个单独的实例。

 

25.2.2.1. Seam.Component.newInstance()

 

使用这个方法创建一个实体或Javabean 组件的新实例。通过这个方法返回的对象将会和它的服务边副本一样有同样的getter/setter方法, 或者如果你愿意,你可以直接访问它的字段。以下面Seam实体组件为例子:

 

@Name("customer")

 

@Entity

 

public class Customer implements Serializable

 

{

 

  private Integer customerId;

 

  private String firstName;

 

  private String lastName;

 

  @Column public Integer getCustomerId() { 

 

    return customerId; 

 

  }

 

  public void setCustomerId(Integer customerId} { 

 

    this.customerId = customerId; 

 

  }

 

  @Column public String getFirstName() { 

 

    return firstName; 

 

  }

 

  public void setFirstName(String firstName) {

 

    this.firstName = firstName; 

 

  }

 

  @Column public String getLastName() {

 

    return lastName;

 

  }

 

  public void setLastName(String lastName) {

 

    this.lastName = lastName;

 

  }

 

}

为创建一个客户边Customer,你会编写下列代码:

 

var customer = Seam.Component.newInstance("customer");

 

那么,从这里你可以设置customer对象的字段:

 

customer.setFirstName("John");

 

// 或者你可以直接设置字段

 

customer.lastName = "Smith";

 

25.2.2.2. Seam.Component.getInstance()

 

getInstance()方法被用来得到一个Seam会话bean存根的一个引用, 然后,它可以被用来根据你的组件远程执行方法。这个方法对指定的组件返回一个单独元素,所以用同样的组件名连续地调用它两次会返回一样的组件实例。

继续我们的例子之前,如果我们已创建了一个新的customer,我们现在希望保存它,我们会传递它到我们的customerAction组件的saveCustomer()方法。

 

Seam.Component.getInstance("customerAction").saveCustomer(customer);

 

25.2.2.3. Seam.Component.getComponentName()

 

传递一个对象到这个方法,如果它是一个组件,会返回它的组件名字,否则返回null。

 

if (Seam.Component.getComponentName(instance) == "customer")

 

  alert("Customer");

 

else if (Seam.Component.getComponentName(instance) == "staff")

 

  alert("Staff member");

 

25.2.3. Seam.Remoting

 

大多数客户边Seam远程功能被包含在Seam.Remoting对象内。虽然你不必直接调用它的大多数方法,有几个重要的方法还是值得一提。

 

25.2.3.1. Seam.Remoting.createType()

 

如果你的应用程序包含或使用了不是Seam组件的Javabean类,你可能需要在客户边创建这些类型,作为参数传递到你的组件方法。使用createType()方法创建一个你的类型实例,用全限定名Java 类名作为参数传递:

 

var widget = Seam.Remoting.createType("com.acme.widgets.MyWidget");

 

25.2.3.2. Seam.Remoting.getTypeName()

 

这个方法是等价于 Seam.Component.getComponentName(),然而是对非组件类型的。 它会返回对象实例的类型名字,或者如果类型不知道,返回null。名字是全限定名Java 类类型名。

 

25.3. 求EL表达式的值

 

Seam远程也支持求EL表达式的值,它提供另一个方便的方法从服务器索检数据。使用Seam.Remoting.eval()函数, 一个EL表达式可以在服务器上远程求值,并将结果值返回到客户边回调方法。这个函数接受两个参数,第一个是要求值的EL表达式,第二个是调用表达式值的回调方法。下面是例子:

 

  function customersCallback(customers) {

 

    for (var i = 0; i < customers.length; i++) {

 

      alert("Got customer: " + customers[i].getName());

 

    }    

 

  }

 

  Seam.Remoting.eval("#{customers}", customersCallback);  

 

在这个例子中,表达式#{customers}由Seam求值, 并且表达式的值(在本例是Customer对象的列表)被返回到customersCallback()方法。这种返回对象的方法必须有它们的类型导入(通过s:remote),以便在Javascript中可以操作它们,记住这点是很重要的。所以操作customer对象的列表,导入customer类型是必需的:

 

<s:remote include="customer"/>

 

25.4. 客户端接口

 

在前面的配置章节,接口,或我们组件的“存根”被导入到我们的页面,通过seam/resource/remoting/interface.js: 或使用s:remote标签:

 

<script type="text/javascript" 

 

        src="seam/resource/remoting/interface.js?customerAction"></script>

 

 

<s:remote include="customerAction"/>

 

通过在我们的页面包含这个脚本,我们组件的接口定义,插入另一些组件或产生执行我们组件的方法必需的类型,使seam远程框架可以利用。

 

可以产生两种客户端存根类型, "可执行(executable)"存根和"类型(type)" 存根。 可执行存根是行为,被用来执行你的会话bean的方法,而类型存根包含状态,代表可以作为参数传递或作为结果返回的类型。

 

产生的客户端存根类型取决于你的Seam组件类型。如果该组件是一个会话bean,那么会产生一个可执行存根,否则它是一个实体或JavaBean,那么会产生一个类型存根。对这个规则有一个例外;如果你的组件是一个JavaBean (即它不是一个会话bean ,也不是一个实体Bean ),并且它的一些方法用@WebRemote注释了,那么,不会产生一个类型存根,而会产生一个可执行存根。 这允许你在一个你不能访问会话bean的非EJB 环境下使用远程调用你的JavaBean 组件。

 

25.5. 上下文


Seam远程上下文包含附加的信息,作为一个远程请求/响应(request/response)周期的一部分被发送和接收。在本阶段,它只包含对话ID,但可能将来会被扩展。


25.5.1. 设置和读取对话ID


如果你打算在一个对话作用域中使用远程调用,那么你需要能够在Seam 远程上下文中读取或设置对话ID。在执行一个远程请求后,调用Seam.Remoting.getContext().getConversationId()读取对话ID。在执行一个请求前,调用Seam.Remoting.getContext().setConversationId()设置对话ID。

 

如果没有用Seam.Remoting.getContext().setConversationId()明确设置对话ID,那么会自动指派由任何远程调用返回的初始有效值ID。如果你在你的页面内操作多个对话,你可能需要在每个调用之前明确地设置对话ID。如果仅操作单个对话,那么你不需要做任何特殊的事情。

 

25.5.2. 在当前对话作用域内的远程调用

 

在某些情况下,可能需要在当前视图的对话作用域内执行一个远程调用。要做到这一点,你必须在执行远程调用前明确地对这个视图设置对话ID。此JavaScript小片段将设置对话ID,用于远程调用当前视图中的对话ID:

 

Seam.Remoting.getContext().setConversationId( #{conversation.id} );

 

25.6. 批处理请求

 

Seam远程允许在单个请求中调用多个组件。推荐使用这个功能,无论什么情况,其适当地减少了网络流量。

 

方法Seam.Remoting.startBatch() 会启动一个新的批处理,在启动一个批处理后,所有组件调用被排队,而不是被立即发送。当所有想要的组件调用被增加到批处理,Seam.Remoting.executeBatch()方法会发送包含所有排队请求的单个请求到服务器,在那儿它们被依次执行。在调用被执行后,包含所有返回值的单个响应会被返回到客户边,并且回调函数(如果提供)以同样的顺序被触发执行。

 

如果你通过startBatch()方法启动一个新的批处理, 但后来你又决定你不相发送它, Seam.Remoting.cancelBatch()方法将舍弃所有被排队的调用,并退出批处理模式。

 

了解使用批处理的例子,请看/examples/remoting/chatroom.

 

25.7. 操纵数据类型


25.7.1. 原始/基本类型


本节描述支持的基本数据类型。在服务器边,这些值通常是兼容其原始类型或它们相应的包装类。

 

25.7.1.1. String

 

在设置字符串参数值时,完全使用Javascript字符串对象。

 

25.7.1.2. Number

 

支持Java支持的所有数字类型。在客户边,数值总是被序列化成字符串表示,而且在服务器边,它们被转化成恰当的目标类型。转化成原始或包装类型支持的Byte, Double, Float, Integer, Long 和 Short 类型。

 

25.7.1.3. Boolean


布尔型,在客户边用Javascript Boolean值表示,在服务器边用Java boolean表示。


25.7.2. JavaBeans


一般来说,它会是Seam实体或JavaBean组件,或另外某些非组件的类。使用适当的方法(Seam组件用Seam.Component.newInstance(),其它情况用Seam.Remoting.createType())来创建该对象的一个新实例。

 

重要的是要注意,只有这两个方法创建的对象才可以被用来作为参数类型不是本节提及的其它有效类型之一的参数的值。在某些情况下,你可能有一个不能准确确定参数的组件方法,如下:

 

@Name("myAction")

 

public class MyAction implements MyActionLocal {

 

  public void doSomethingWithObject(Object obj) {

 

    // code

 

  }

 

}

 

在此案中,你可能想传递你的myWidget 组件的一个实例,然而myAction 接口没有包含myWidget,因为myWidget没有被它的任何一个方法直接引用。要解决此问题,你需要明确地导入MyWidget:

 

<s:remote include="myAction,myWidget"/>

 

然后才允许用Seam.Component.newInstance("myWidget")创建一个myWidget对象, 这以后才可以传递它到myAction.doSomethingWithObject()。

 

25.7.3. 日期和时间

 

日期值被序列化成一个精确到毫妙的字符串表示。在客户边,使用Javascript Date对象操作日期值。在服务器边,使用java.util.Date (或派生的,如java.sql.Date 或 java.sql.Timestamp类)。

 

25.7.4. 枚举

 

在客户边,枚举同样被看作字符串。在对一个enum 参数设置值时,完全使用字符串表示enum 。以下面组件为例:

 

@Name("paintAction")

 

public class paintAction implements paintLocal {

 

  public enum Color {red, green, blue, yellow, orange, purple};

 

 

  public void paint(Color color) {

 

    // code

 

  }    

 

 

为了用red色调用paint()方法,以一个字符串作为参数值传递:

 

Seam.Component.getInstance("paintAction").paint("red");

 

反之亦然,如果一个组件方法返回了一个枚举参数(或者在返回对象的图表中包含了一个enum字段),那么客户边会用一个字符串来表示它。

 

25.7.5. 集合

 

25.7.5.1. Bags

 

Bags囊括了所有的集合类型,包含arrays、collections、lists、sets,(但Maps除外 —— 见下一节),并且在客户边作为Javascript array被实现 。当以这些类型中的一个作为参数调用一个组件方法时,你的参数应该是Javascript array。如果一个组件返回的类型是这些类型中的一个,那么返回值也应该是一个Javascript array。在调用组件方法时,服务器边的远程框架非常聪明地将bag转换为相应的一个类型。

 

25.7.5.2. Maps

 

因为Javascript没有提供对Maps的内部支持, 所以Seam远程框架提供了一个简单的Maps实现。 为创建一个用来作为一个远程调用参数的Map,创建一个新的Seam.Remoting.Map对象:

 

var map = new Seam.Remoting.Map();

 

这个Javascript实现提供了操作Maps的基本方法: size()、 isEmpty()、 keySet()、 values()、 get(key)、 put(key, value)、 remove(key)和 contains(key)。这些方法的每一个都等价于它们的Java副本。这些方法返回一个集合,比如keySet()和values(),一个Javascript Array对象会被返回,其包含key或value对象 (分别)。

 

25.8. 调试

 

为了协助追踪bugs, 可以激活调试模式,用一个弹出窗来显示出在客户端和服务器之间往返的所有包的内容。为激活调试模式,在Javascript中执行setDebug()方法:

 

Seam.Remoting.setDebug(true);

 

或者通过components.xml配置它:

 

<remoting:remoting debug="true"/>

 

为关掉调试,调用setDebug(false)。 如果你想编写你自己的消息到调试日志,调用Seam.Remoting.log(message)。

 

25.9. 处理异常

 

在调用一个远程组件方法时,可以指定一个异常处理器,它将处理在组件调用期间异常事件的响应。在你的JavaScript中,为了指定一个异常处理器函数,在回调参数后面要包含它的一个引用:

 

var callback = function(result) { alert(result); };

var exceptionHandler = function(ex) { alert("An exception occurred: " + ex.getMessage()); };

Seam.Component.getInstance("helloAction").sayHello(name, callback, exceptionHandler);

 

如果你没有定义一个回调处理器,你必须在它的位置指定为null:

 

var exceptionHandler = function(ex) { alert("An exception occurred: " + ex.getMessage()); };

Seam.Component.getInstance("helloAction").sayHello(name, null, exceptionHandler);

 

被传递到异常处理器的异常对象暴露了一个方法,getMessage(),其返回由@WebRemote方法抛出的异常产生的异常消息。

 

25.10. 加载消息

 

显示在屏幕的右上角的默认加载消息可以被修改、自定义显示或完全关掉。

 

25.10.1. 改变消息

 

为将"Please Wait..."消息改变为不同的消息,设置 Seam.Remoting.loadingMessage的值:

 

Seam.Remoting.loadingMessage = "Loading..."; 

 

25.10.2. 隐藏加载消息

 

为完全禁用加载消息的显示,用空函数覆盖 displayLoadingMessage()和 hideLoadingMessage()的实现:

 

// 不显示加载指示器

 

Seam.Remoting.displayLoadingMessage = function() {};

 

Seam.Remoting.hideLoadingMessage = function() {};

 

 

25.10.3. 自定义加载指示器

 

也可以覆盖加载指示器,显示一个动画图标,或者你想显示的其它东西。要做到这点,用你自己的实现覆盖displayLoadingMessage()和 hideLoadingMessage() 消息:

 

  Seam.Remoting.displayLoadingMessage = function() {

 

    // 在这里编写代码显示指示器

 

  };

 

  Seam.Remoting.hideLoadingMessage = function() {

 

    // 在这里编写代码隐藏指示器

 

  };

 

25.11. 控制被返回的数据

 

当执行一个远程方法时,其结果被序列化为一个XML响应,返回到客户端。然后,客户端散集响应到一个Javascript对象。对包含了引用其它对象的复杂类型(如Javabeans),所有这些被引用的对象也被序列化为响应的一部分。这些对象可以引用其他对象,而它们又可以引用其他对象,等等。如果不加限制,这个对象的“图表”有可能是巨大的,这取决于对象之间存在的关系。作为一个枝节问题(除了潜在的冗长响应外),你可能也希望防止敏感信息暴露给客户端。

 

Seam远程提供了一个简单的手段来“限制”对象图表,即通过指定远程方法的@WebRemote注释的exclude字段。 这个字段接收一个用.符号指定的一个或多个路径字符串数组。在调用一个远程方法时,在结果对象图表中与这些路径配置的对象被排除在序列化结果包中。

 

对我们整个的例子,我们将使用下面的Widget例子:

 

@Name("widget")

 

public class Widget

 

{

 

  private String value;

 

  private String secret;

 

  private Widget child;

 

  private Map<String,Widget> widgetMap;

 

  private List<Widget> widgetList;

 

  

 

  // getters and setters for all fields

 

}

 

25.11.1. 约束普通字段

 

如果你的远程方法返回一个Widget实例,但是你不想暴露secret字段,因为它包含敏感信息,你可以象这样来限制它:

 

@WebRemote(exclude = {"secret"})

 

public Widget getWidget(); 

 

"secret" 引用返回对象的secret字段。 现在,假若我们不在乎暴露这个字段给客户端。相反,注意到被返回的Widget值有一个child 字段,也是一个Widget。如果我们想隐藏child 的secret 值又该如何做呢?我们可能通过在结果对象图表中用.符号来指定字段路径:

 

@WebRemote(exclude = {"child.secret"})

 

public Widget getWidget();

 

25.11.2. 约束Maps和Collections

 

 

在一个对象图表内可能存在对象的其他地方是在一个Map或某些collection类 (List, Set, Array, 等等)中. 集合容易被当作别的字段来看待。例如,如果我们的Widget 有一个包含了另外的Widgets的一个列表widgetList,为了约束在这个列表中的Widgets的secret字段,象这样注释:

 

@WebRemote(exclude = {"widgetList.secret"})

 

public Widget getWidg

分享到:
评论

相关推荐

    linux 网络编程

    第二章 UNIX/Linux 模型........ 第三章 进程控制......... 第四章 进程间通信....... 第五章 通信协议简介 第六章 Berkeley 套接字. 第七章 网络安全性.... 第八章 Ping 例程.. 第九章 tftp 例程.... 第十章 远程...

    Linux网络编程.pdf socket tcp udp

    第二章 UNIX/Linux 模型...............................................................................................17 2.1 UNIX/Linux 基本结构...........................................................

    远程数据灾备 云平台 CDP

    第二章 平台建设分析.................................................................................................................................................10 2.1 平台建设的系统分析 ............

    嵌入式WEB服务器及远程测控应用详解.rar

    第五章:简单的 LED 测试 第六章:A/D测量及在网页中的显示 第七章: 基于 ZC301摄像头开源视频服务器代码移植 第八章: IP 自动获得的设置和测试 第九章:复杂 LED测试 第十章:基于 I/O 多路复用技术的并发...

    第2章 Linux 2 2.1. 简介 2 2.1.1. 概述 2 2.2. 环境搭建 2 2.2.1. 安装vmware 2

    第2章 Linux 2 2.1. 简介 2 2.1.1. 概述 2 2.2. 环境搭建 2 2.2.1. 安装vmware 2 2.2.2. 安装CentOS 2 2.2.3. 虚拟机网络配置 4 2.2.4. 配置主机名 7 2.2.5. 配置防火墙 8 2.2.6. SSH远程登陆 10 2.2.7. 使用yum源 ...

    Quartz-Job-Scheduling-Framework-中文版-V0.9.1.zip

    使用 Quartz 的远程方式 (第二部分) 内容提要:配置、创建并运行 Quartz RMI 服务端。 第九章. 使用 Quartz 的远程方式 (第三部分) 内容提要:配置、创建并运行 Quartz RMI 端户端,演示了 Quartz RMI 客户端通过...

    Linux网络编程

    第二章 UNIX/Linux 模型...............................................................................................17 2.1 UNIX/Linux 基本结构............................................................

    linux 网络编程源代码

    第二章 UNIX/Linux 模型...............................................................................................17 2.1 UNIX/Linux 基本结构............................................................

    servser 2003完整教程part2

    第五章 文件系统....................................................................................................................... 111 第一节 Windows Server 2003 支持的文件系统......................

    Python基础教程(第3版)-201802出版-文字版

    久负盛名的 Python 入门经典针对 Python 3 全新升级十个出色的项目,让你尽快可以使用 Python 解决实际问题目录第 1章 快速上手:基础知识 ........................ 1 1.1 交互式解释器 .............................

    linux网络编程

    第二章 UNIX/Linux 模型....................................17 第三章进程控制 ............................................22 第四章进程间通信...........................................50 第五章通信协议...

    server2003完整教程part1

    第五章 文件系统....................................................................................................................... 111 第一节 Windows Server 2003 支持的文件系统......................

    富士通16位单片机C语言手册提高篇中文版

    第二章 C 编译器...................................................................................10 第一节 编译的结构.....................................................................................

    Python基础教程(第3版)中文高清无水印+数据源代码

    项目 5:虚拟茶话会...................364第 25 章 项目 6:使用 CGI 进行远程编辑................................................ 379第 26 章 项目 7:自建公告板................... 387第 27 章 项目 8:...

    linux应用与开发基础

    第二章 LINUX的安装与组成......................................................... 10 2.1 你适合学习LINUX吗........................................................... 10 2.2 四大LINUX发行版本.............

    linux网路编程 中文 23M 版

    第1 章Linux操作系统概述................... .......................................................................... 2 1.1 Linux发展历史........................................................ 2 ...

    富士通C手册(基础篇-应用篇-提高篇)

    第二章 C 编译器...................................................................................10 第一节 编译的结构.....................................................................................

    Sybase ASE 15.7 开发文档:系统管理指南(卷二)

    Sybase ASE 15.7 开发文档:系统管理指南(卷二)共两卷 第 1 章 限制对服务器资源的访问 第 2 章 镜像数据库设备 第 3 章 配置内存 第 4 章 配置数据高速缓存 第 5 章 管理多处理器服务器 第 6 章 创建和管理用户...

    常用生物数据分析软件

    第2 章 数据的基本处理........................................................................................................................25 2.1 测序原理介绍...........................................

Global site tag (gtag.js) - Google Analytics