基于unix或类unix的科学应用软件准WEB化的初步探讨

 

摘要:介绍了基于unix或类unix的科学应用软件WEB化的结构框架及设计方法,并给出了一个科学应用软件的准web的实例。

关键词:科学应用软件,web化,j2ee模式,perl语言,shell脚本,插件。

背景

科学应用软件在生物,物理,化学,地理,气象等领域为广大的科技工作者提供了一个快速,准确,方便的平台。像matlabAnsys。但是这些软件大多是采用的是C/S结构。应用程序都是GUI界面的。客户需要安装应用程序软件。但是应用程序由于需要经常更新,升级,因此逐台更新的问题比较复杂;另一方面,C/S结构对网络底层协议的依赖性大,由于部分程序不是建立在TCP/IP协议之上的,因此对防火墙、多网端等等问题的解决并不方便,对跨平台( Unix-Windows)的支持也稍显不足;另外,目前的应用系统建设一般都超出了局域网范畴,传统C/S结构对实现内网/外网、局域网/广域网间的有机整合也有局限。 但是现在流行的B/S结构对用户的技术要求比较低,对服务器的配置要求也较低,而且界面丰富、客户端维护量小、程序分发简单、更新维护方便。它容易进行跨平台布置,容易在局域网与广域网之间进行协调。客户只需要IE或者netscape浏览器即可。而目前关于这些软件大多是基于unix或类unix(如linux系统)的,正是基于两者的比较,把目前我所(中科院寒区旱区环境与工程研究所)的所用的科学应用软件从c/s模式向b/s模式转化。

从宏观上看,对既存系统进行Web化再工程可以说存在准Web化和真Web化两类方案。使既存系统适应Web计算环境,但并不对既存系统本身进行再构的方案,我们称之为准Web化。相对而言,对既存系统本身进行再构、以适应Web计算环境的方案可以称为真Web化或Web化。Web化再工程解决方案的选择将直接影响具体作业的工作量以及Web化后新系统的性能和生存期。因而在再分析阶段,根据既存系统特点选择合适的解决方案从某种意义上可以说是Web化再工程价值的天平。

由于Web化再工程前的既存系统基本都不直接支持Web访问,所以采用真Web化方案对其进行再构时,往往需要使用支持Web访问的编程语言重新编写程序去实现既存系统的功能。

Web化再工程是一个重新构建活动,它需要先对既存系统实施逆向工程,以便建立适当的数据、功能和行为模型。而且真Web化方案需要对既存系统进行二次开发,涉及既存系统分析、应用程序分割、软件构件化等诸多工作。所以采用这种方案进行Web化再工程难度高、手工开发工作量大。准Web化方案能够快速地把WindowsUnixJava、类unix上的科学应用软件以嵌入和发布的方式转换为HTML页面,而无需重新编写程序代码。其工作量主要集中在测试阶段,大大少于真 Web化方案。准Web化方案由于无需二次开发,即可充分利用用户原有的基础设施和应用软件资源,因而有效地降低了总体成本。而且准Web化后系统的可扩展性、负载平衡、容错性等依赖于成熟的科学应用软件,通常可以提供较优的性能。 正是基于这两者的比较,而较多的科学计算软件大多是国外产商多年的成果结晶,我们不可能对其系统进行再构、以适应Web计算环境。由此我们选择了把科学计算软件准web化的方案。 

 

二实现的方式

2.1Shell或者perl语言的cgi程序

      shell或者perl语言都能用来开发功能强大的cgi页面程序。

shell是用在unix系统和类unix系统上的。它是操做系统的核心,所以用shell写的cgi程序功能强大。Shell脚本一般用于小的、快速的甚至可以用完就不要的CGI程序,因此,编写它们时常常不考虑安全性。这种疏忽可以导致一些缺陷,使得仅对系统具有一般知识的人也能进入系统任意走动。尽管Shell CGI 程序最容易写,甚至只需拼凑一下即可,但控制它们却很困难,因为它们一般是通过执行外部的其他程序来完成工作的。这就导致一些可能的隐患,CGI 程序会继承任何它使用的程序的安全问题。

PerlLarry Wall发明的一种语言。PerlShell脚本更进一步。Perl用于CGI编程有很多优点,并且相当安全。Perl能给CGI 作者提供足够的灵活性。Perl是解释型的。这意味着它实际在调用时是先编译,然后每次执行一步。这就很容易使得不正确的用户数据被包括进来作为代码的一部分,从而错误地进行解释,形成程序中止。

 

2.2J2EE模式    

Java程序的最小执行环境可以在Web 浏览器中执行而不需要另外安装软件,因此,理论上全球任意一台装有Web浏览器的机器都可以进行全球计算。J2EE是美国Sun公司刚刚推出的一种全新的基于Java的概念的模型,与传统的互联网应用程序模型相比有着不可比拟的优势。它是在分布式环境中的一种体系结构,它提供了一种基于组件的设计,开发,集成,部署企业应用系统的方法。J2EE平台提供了多层分布式的应用系统模型,重用组件的能力,统一的安全模型和灵活的事物控制。基于组件的J2EE企业应用系统具有平台独立性,所以不受任何软件产品和任何软件厂家API的约束。以下是J2EE架构。

 

 

    对于远程计算系统而言,由于它基于internet,特别是万维网,所以,必须采用高效,安全的网络开发技术。Javasun推出的开发语言,它以其强大的功能,尤其是适合internet开发的特点而在互联网上得到了广泛的应用。

在系统的支撑系统,即用户界面以及人机交互中,我们使用JSPJava Server Page.JSP基于java的技术,主要用于创建支持跨平台的动态网页,它可以在客户端和服务器端执行。它在IE以及netscape的浏览器上都得了良好的支持。系统正是通过它,来接受用户请求并作有效性检查,最后负责把计算结果发送给用户。

    在服务器端,我们采用的是javabeans。以JavaSoft JavaBeans的定义为基础,其由java语言编写,并可在任何的java平台上执行。它采用多变的沟通机制,包括Java RMIRemote Method Invocation)及IIOPJavaBeans允许服务开发者集中于业务逻辑,并且让EJB Server处理传送稳定的,可升级服务的复杂工作。

    为了使计算效果更好的展示给用户,我们在客户端也使用插件(plug-in)的技术。Plug-innetscape推出的一种用于客户端的网络技术。它从服务器端接收数据并在客户端用户的机器上执行。用户只需要安装插件一次即可。在网络三维展示方面,现在使用最多的是VRML。通过插件技术,我们可以根据专业要求定义自己的三维图形格式,让插件将计算结果以定义的格式展示给用户。插件程序是用java语言来进行开发的。

 

准备

3.1 科学软件

   我们以一个科学应用软件来实现web化。这个科学计算的软件是Computing the statistical functions for one or two variables。这个软件是用fortran写的应用程序。用户必须先在本地安装这个程序,然后编译,生成一个执行文件。运行这个软件的方法如下:

Computing the statistical functions for one or two variables

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

REFERENCE: 'Mathematiques et statistiques by H.

Haut, PSI Editions, France, 1981'

F90 version by J-P Moreau, Paris

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

SAMPLE RUN:

 

TUTORIAL

 

1. Define type of calculus:

1: Statistical functions for a set X(i)

2: Statistical functions for a set X(i), Y(i)

 

2. Input number n of data

 

3. Input successively the n values X(i) [and Y(i)]

Type of calculus (1 or 2): 2

 

Number of data: 5

 

1 1 12

2 2 9

3 3 7

4 4 15

5 5 6

 

Mean of X(i)....................: 3.00000000000000

 

(n-1) standard deviation of X(i): 1.58113883008419

 

(n) standard deviation of X(i): 1.41421356237310

 

(n-1) standard dev. of X mean...: 0.707106781186548

 

(n) standard dev. of X mean...: 0.632455532033676

 

Mean of Y(i)....................: 9.80000000000000

 

(n-1) standard deviation of Y(i): 3.70135110466435

(n) standard deviation of Y(i): 3.31058907144937

 

(n-1) standard dev. of Y mean...: 1.65529453572468

(n) standard dev. of Y mean...: 1.48054044186574

 

(n-1) covariance of X,Y.........: -1.50000000000000

(n) covariance of X,Y.........: -1.20000000000000

 

Correlation coefficient.........: -0.256307297315028

 

 

 

Description: This program computes the usual statistical functions

for a set of n variables X(i) or for a set of n pairs X(i), Y(i).

 

 

 

3.2关键技术

3.2.1 格式转换

其中我们把所有需要输入的参数进行重定向到一个文件,使得这个应用程序可以一次读取这个文件,并把结果输出。我们总共需要输入3个参数组。第一个是Define type of calculus。第二个是Input number n of data,第三个是Input successively the n values X(i) [and Y(i)]

我们以一个例子作为讲解:

第一个参数是:1

第二个参数是:5,所以第三个参数组必须是5个数值,比方是:1 2 3 4 5

我们需要一次一个的读取这些参数。为了把这三个参数组重定向到一个文件里去。其显示的格式就应该是:

  

重定向文件格式

1

 

      5

 

      1

      2

      3

      4

      5

 

所以我们的目的是把输入的参数转化成以上格式的文件。                   

 

3.2.2.调用科学应用软件

   如果fortran编译后生成一个a.out的文件。重定向的文件名叫data.dat

   Shell调用科学应用软件是最简单的:./a.out < data.dat

   如果要用J2EE来实现,则采用javabean的来控制。

  

String[] cmds = {"sh","-c","./a.out < /data.dat"};                                              

Process proc = Runtime.getRuntime().exec(cmds);

 

(1)shell实现

1.输入参数页面 first.cgi

#!/bin/sh

echo "<Cotent-type: text/html>"

echo ""

echo "<HTML>"

echo "<BODY>"

echo "<H2>This is example for the demonstration of te WEB computing</H2>"

echo "<HR>"

echo "<center>"

echo "<H4>"

echo "     Computing the statistical functions "          

echo "             for one or two variables <br>"                

                                                       

echo " -----------------------------------------------------  <br>"

echo " REFERENCE:  'Mathematiques et statistiques by H.  <br>     "

echo "              Haut, PSI Editions, France, 1981'         <br>"

                                                       

echo "                F90 version by J-P Moreau, Paris        <br>"

 

echo "  -----------------------------------------------------<br>  "

echo "  SAMPLE RUN:                  <br>   <br>               "       

                                                        

echo "  TUTORIAL     <br>    <br>                              "       

                                                        

echo "  1. Define type of calculus:'   <br>                    "   

echo "     1: Statistical functions for a set X(i)  <br>        "  

echo "     2: Statistical functions for a set X(i), Y(i)    <br><br>"  

                                                        

echo "  2. Input number n of data     <br><br>                 "       

                                                        

echo "  3. Input successively the n values X(i) [and Y(i)] <br>"   

                                                        

echo "  Type of calculus (1 or 2): 2    <br>  <br>             "       

                                                        

echo "  Number of data: 5     <br> <br>                        "       

                                                        

echo "    1  1 12   <br>                                       "   

echo "    2  2 9    <br>                                        "  

echo "    3  3 7    <br>                                         " 

echo "    4  4 15  <br>                                           "

echo "    5  5 6   <br> <br>                                       "   

                                                            

                                                        

echo "  Mean of X(i)....................:    3.00000000000000<br><br>"     

                                                        

echo "  (n-1) standard deviation of X(i):    1.58113883008419   <br><br>"  

echo "    (n) standard deviation of X(i):    1.41421356237310    <br><br>" 

                                                         

echo "  (n-1) standard dev. of X mean...:   0.707106781186548 <br><br>"    

echo "    (n) standard dev. of X mean...:   0.632455532033676   <br><br> " 

                                                        

echo "  Mean of Y(i)....................:    9.80000000000000    <br><br> "

                                                        

echo "  (n-1) standard deviation of Y(i):    3.70135110466435  <br>"

echo "    (n) standard deviation of Y(i):    3.31058907144937 <br><br>"    

                                                        

echo "  (n-1) standard dev. of Y mean...:    1.65529453572468   <br> " 

echo "    (n) standard dev. of Y mean...:    1.48054044186574  <br><br>"   

                                                           

                                                          

echo "  (n-1) covariance of X,Y.........:   -1.50000000000000  <br>"    

echo "    (n) covariance of X,Y.........:   -1.20000000000000    <br><br>" 

                                                         

echo "  Correlation coefficient.........:  -0.256307297315028  <br><br><br><br>"

                                                        

                                                        

                                                         

echo "Description: This program computes the usual statistical functions<br>"

echo "             for a set of n variables X(i) or for a set of n pairs X(i), Y(i).<br><br>"

echo "</H4>"

echo "</center>"

 

 

echo "<FORM ACTION="/cgi-bin/convert.cgi" METHOD=POST>"

 

echo "<h4>Here is the form for the caculating parameters input</h4>"

 

echo "<HR>"

echo "<BR><BR>"

echo "<SELECT NAME=sfset>"

echo "1. Define type of calculus"                         

echo"     1: Statistical functions for a set X(i)"            

echo "2: Statistical functions for a set X(i), Y(i)"

echo "<OPTION> --Define type of calculus:--              "            

echo "<OPTION>1             "

echo "<OPTION>2"

echo "</SELECT>"

echo "<BR><BR>"

echo " 2. Input number n of data"

echo "<INPUT NAME=datnum SIZE=3>"

echo "<BR><BR>"

echo "3. Input successively the n values X(i) [and Y(i)]"

echo" (Please use the space to separate one data from the other. )"

echo "<TEXTAREA COLS="100" ROWS="1" NAME="inpdat"></TEXTAREA>"

echo "<BR>"

echo "<INPUT TYPE=Submit VALUE="Send the parameter and Caculation">"

echo "<INPUT TYPE=Reset VALUE="Clear form">"

echo "</FORM>"

echo "</BODY>"

echo "</HTML>"

 

 

 

2.调用科学应用软件页面 two.cgi

/wdcpub/apache/cgi-bin/a.out < /wdcpub/apache/cgi-bin/tt.dat

 

3.输出页面 convert.cgi

#!/bin/sh

#convert.cgi

# This cgi script use for decode the URL string

#

echo  "Content-type: text/html"

echo ""

echo "<HTML><PRE>"

 

#display the method and the coded string

if [ "$REQUEST_METHOD"="POST" ]; then

QUERY_STRING=`cat -`

fi

echo "Method : $REQUEST_METHOD"

echo "Query String: $QUERY_STRING"

echo  "<HR>"

 

 

LINE=`echo $QUERY_STRING | sed 's/&/  /g'`

 

for LOOP in $LINE

do

NAME=`echo $LOOP | sed 's/=/ /g' | awk '{print $1}'`

 

 

TYPE=`echo $LOOP | sed "s/=/ /g" | awk "{print $2}" | \

sed -e "s/%\(\)/\\\x/g" | sed "s/+/ /g"`

#  TYPE=`echo $TYPE1 | sed -e 's/%\(\)/\\\x/g' | sed 's/+/ /g'`

 

VARS=`printf  "${NAME}=\\${TYPE}\n"`

eval `printf $VARS`

done

 

echo "<HR>"

 

printf "Your select the type of calculus is :  $sfset\n"

printf "Your input the data number for caculation is : $datnum\n"

printf "Your input data value is: $inpdat\n"

sfset1=`echo $sfset | sed "s/sfset//g"`

datnum1=`echo $datnum | sed "s/datnum//g"`

inpdat1=`echo $inpdat | sed "s/inpdat//g"`

inpdat2=`echo $inpdat1 | tr " " "\n"`

echo `echo "$sfset1\n">tt.dat`

echo `echo "$datnum1\n">>tt.dat`

echo `echo "$inpdat2\n">>tt.dat`

rt=`/wdcpub/apache/cgi-bin/t.cgi`

echo "rt : $rt"

echo "</PRE>"

echo "</HTML>"

 

(2)J2EE模式实现

1.输入参数页面 MathByFor.jsp

<%@ page import="java.util.*" %>

<%@ page import="java.util.Hashtable"%>

<%@ page import="com.sarsover.*" %>

<%@ page contentType="text/html; charSet=GB2312" %>

<jsp:useBean id="myMathByFor" scope="session" class="com.sarsover.MathByFor" />

<%

response.setHeader("Pragma","no-cache");

response.setHeader("Cache-Control","no-cache");

response.setDateHeader("Expires", 0);

%>

 

 

<%

       

        String sfset=new String("");

        String datnum=new String("");

        String inpdat=new String("");

 

        if(request.getParameter("sfset")!=null)

            sfset=request.getParameter("sfset").trim();

        if(request.getParameter("datnum")!=null)

            datnum=request.getParameter("datnum").trim();

        if(request.getParameter("inpdat")!=null)

            inpdat=request.getParameter("inpdat").trim();

       

%>

<HTML>

<BODY>

<H2>This is example for the demonstration of te WEB computing</H2>

<HR>

<center>

<H4>

     Computing the statistical functions

             for one or two variables <br>

 -----------------------------------------------------  <br>

 REFERENCE:  'Mathematiques et statistiques by H.  <br>    

              Haut, PSI Editions, France, 1981'         <br>

                F90 version by J-P Moreau, Paris        <br>

  -----------------------------------------------------<br> 

  SAMPLE RUN:                  <br>   <br>              

  TUTORIAL     <br>    <br>                             

  1. Define type of calculus:'   <br>                    

     1: Statistical functions for a set X(i)  <br>       

     2: Statistical functions for a set X(i), Y(i)    <br><br>

  2. Input number n of data     <br><br>                

  3. Input successively the n values X(i) [and Y(i)] <br>

  Type of calculus (1 or 2): 2    <br>  <br>            

  Number of data: 5     <br> <br>                       

    1  1 12   <br>                                      

    2  2 9    <br>                                       

    3  3 7    <br>                                         

    4  4 15  <br>                                          

    5  5 6   <br> <br>                                      

  Mean of X(i)....................:    3.00000000000000<br><br>

  (n-1) standard deviation of X(i):    1.58113883008419   <br><br>

    (n) standard deviation of X(i):    1.41421356237310    <br><br>

  (n-1) standard dev. of X mean...:   0.707106781186548 <br><br>

    (n) standard dev. of X mean...:   0.632455532033676   <br><br>

  Mean of Y(i)....................:    9.80000000000000    <br><br>

  (n-1) standard deviation of Y(i):    3.70135110466435  <br>

    (n) standard deviation of Y(i):    3.31058907144937 <br><br>

  (n-1) standard dev. of Y mean...:    1.65529453572468   <br>

    (n) standard dev. of Y mean...:    1.48054044186574  <br><br>

  (n-1) covariance of X,Y.........:   -1.50000000000000  <br>

    (n) covariance of X,Y.........:   -1.20000000000000    <br><br>

  Correlation coefficient.........:  -0.256307297315028  <br><br><br><br>

Description: This program computes the usual statistical functions<br>

             for a set of n variables X(i) or for a set of n pairs X(i), Y(i).<br><br>

</H4>

</center>

<form name="frmmsenter" action="MathByForDo.jsp" method="post">

<h4>Here is the form for the caculating parameters input</h4>

<HR>

<BR><BR>

<SELECT NAME=sfset>

1. Define type of calculus

2: Statistical functions for a set X(i), Y(i)

<OPTION> --Define type of calculus:--             

<OPTION>1            

<OPTION>2

</SELECT>

<BR><BR>

 2. Input number n of data

<INPUT NAME=datnum SIZE=3>

<BR><BR>

3. Input successively the n values X(i) [and Y(i)]

<TEXTAREA COLS=100 ROWS=1 NAME=inpdat></TEXTAREA>

<BR>

<INPUT TYPE=Submit VALUE=OK onClick="btnokClicked()">

<input type="hidden" name="event" value="exec" >

<INPUT TYPE=Reset VALUE=RESET>

</FORM>

</BODY>

<script language="javascript">

<!--

function btnokClicked(){

    document.frmmsenter.event.value="exec";

    document.frmmsenter.submit();

}

 

-->

</script>

</HTML>

 

 

 

1.   javabean控制程序 MathByFor.java

/**

 * This is example for the demonstration of te WEB computing

 * Computing the statistical functions for one or two variables

 * version 0.01

 * author luolh

 * date 2003/12/01

 * Company casnw

 */

 

package com.sarsover;

 

import java.lang.*;

import java.io.*;

import java.util.*;

 

public class MathByFor {

        public MathByFor(){}

 

        //create a file for "<"

        public String WriteFile(String sfset,String datnum,String inpdat){

                String strRtn=new String("");

                if(sfset.equals(""))

                   strRtn="Define type of calculus isn't NULL!<br>";

                if(datnum.equals(""))

                   strRtn+="Input number n of data isn't NULL!<br>";

                if(inpdat.equals(""))

                   strRtn+="Input successively the n values isn't NULL!<br>";

 

                if(!strRtn.equals(""))

                   return strRtn;

 

                 //create a file in local directory

                File f1=new File("/home/wwz/","test.dat");

                try{

                    boolean exists=f1.exists();

                    if(exists){

                       //

                    }else{

                        boolean success= f1.createNewFile();

                        if(success){

                           //

                        }else{

                           //

                        }

                      }

                }catch(IOException e){

                                       //

                }

 

                try{

                    BufferedWriter bw = new BufferedWriter(new FileWriter(f1));

                    bw.write(sfset+"\n\n");

                    bw.write(datnum+"\n\n");

                    //analyse inpdat into a style

                    //eg 1 2 3 4 -->1

                    //              2

                    //              3

                    //              4

                    StringTokenizer st = new StringTokenizer(inpdat);

                    while (st.hasMoreTokens()) {

                        bw.write(st.nextToken()+"\n");

                    }

                    //flush

                    bw.flush();

                    bw.close();

                    strRtn="ok";

 

                }catch (IOException ioe){

                //

                }

        return strRtn;

        }

 

        //exec the System Command

        public String[] runCommand()

            throws Exception {

 

            ArrayList list = new ArrayList();

            String[] cmds = {"sh","-c","/home/wwz/a.out < /home/wwz/test.dat"};

            //Process proc = Runtime.getRuntime().exec("/home/wwz/a.out < /home/wwz/test.dat");                                              

            Process proc = Runtime.getRuntime().exec(cmds);

            InputStream istr = proc.getInputStream();

            BufferedReader br =

                new BufferedReader(new InputStreamReader(istr));

 

            String str;

                        while ((str = br.readLine()) != null)

               list.add(str);

                   System.out.println(str);

 

            try {

                proc.waitFor();

            }

 

            catch (InterruptedException e) {

                System.err.println("process was interrupted");

            }

 

            if (proc.exitValue() != 0)

                System.err.println("exit value was non-zero");

 

            br.close();

 

            //return str;

            return (String[])list.toArray(new String[0]);

        }

 

}

 

 

2.输出页面 MathByForDo.jsp

<%@ page import="java.util.*" %>

<%@ page import="java.util.Hashtable"%>

<%@ page contentType="text/html; charSet=GB2312" %>

<jsp:useBean id="myMathByFor" scope="session" class="com.sarsover.MathByFor" />

<%

response.setHeader("Pragma","no-cache");

response.setHeader("Cache-Control","no-cache");

response.setDateHeader("Expires", 0);

%>

 

 

<%

 

        String sfset=new String("");

        String datnum=new String("");

        String inpdat=new String("");

 

        if(request.getParameter("sfset")!=null)

            sfset=request.getParameter("sfset").trim();

        if(request.getParameter("datnum")!=null)

            datnum=request.getParameter("datnum").trim();

        if(request.getParameter("inpdat")!=null)

            inpdat=request.getParameter("inpdat").trim();

           

 

        String[] strRtn;

        String strRtn1;

        if(event.equals("exec")){

            strRtn1=myMathByFor.WriteFile(sfset,datnum,inpdat);

            if(strRtn1.equals("ok")){

               strRtn=myMathByFor.runCommand();

               String value=new String("");

               for (int i=0;i<strRtn.length;i++) {

                    value=strRtn[i];

           

%>

<html>

          <tr>

            <td width="100%"><%=value%><br></td>

          </tr>

<%

}

}

}

%>

          <tr>

            <td width="100%" colspan="2"><p align="center"><input type="button" name="btnok" value="BACK" onClick="btnokClicked()"></td>

          </tr>

 

<script language="javascript">

<!--

function btnokClicked(){

    var strUrl="TextFile.jsp";

    window.location.replace(strUrl);

}   

-->

</script>

</html>

 

 

 

 

以上是这个软件的一个web化页面。

 

总结     

     准Web化方案将既存科学应用软件系统发布到Internet/Intranet上实现Web化。如同通过Web浏览器即可访问网上资源一样,用户可以通过web浏览器在任何地方通过Internet/Intranet来运行原系统,原系统的C/S应用程序只要原封不动地配置在unix或类unix的服务器端即可。科学应用软件的web化改变了它固有的使用模式,使得一套软件可以实时的为更多的科技者工作,也同时减少了软件的购买成本。

     关于科学应用软件web化,现在还刚刚起步。由于以前软件的开发所遵循的模式已经对现在的运用造成了障碍,所以现在研究科学应用软件web化是一个重要的课题。以上所举的只是一个简单的例子。

 

 

 

 


 

编写:罗立辉

日期:2005-10-21