java corba实例,OpenORB开发CORBA的实例介绍
目录:
概述
开发步骤
创建Java项目,配置Lib
创建IDL文件
创建服务单
创建客户端
测试本地调用
NamingService命名服务实现远程调用
[一]、概述
本文主要是图文介绍 Eclipse+OpenORB 开发CORBA应用的详细步骤,以供初学者借鉴。有关Eclipe中CORBA开发环境的配置详见:
http://www.micmiu.com/opensource/corba/corba-eclipse-env-config/
[二]、开发步骤
【1】、创建Java项目,配置lib
在Eclipe中首先创建一个Java Project 取名为:Corba-demo;在刚创建好的项目上右击,选择 Build Path → Configure Build Path … ,然后在右侧选中页签 Libraries ,点击 Add Library… 添加已经配置好的OpenORB相关的lib库,如下图:
【2】、创建IDL文件
在 src 文件夹上右键依次选择 New → Other… → CORBA Wizard → IDL files → Simple IDL 如下图:
点击 Next 按钮,在File Name:输入Hello.idl 如下图:
点击 Finish 即可。
Hello.idl 文件修改为如下内容:
/*
* IDL helloworld demo
* author by micmiu.com
*/
module com
{
module micmiu
{
module idl
{
module hello
{
interface HelloService {
string sayHello(in string msg);
};
};
};
};
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
* IDL helloworld demo
* author by micmiu.com
*/
modulecom
{
modulemicmiu
{
moduleidl
{
modulehello
{
interfaceHelloService{
stringsayHello(instringmsg);
};
};
};
};
};
选中创建好的Hello.idl文件,右键 ORB Menu → Compile,就自动编译生成Java文件,类似下图:
【3】、创建服务端
在 src 文件夹上右键依次选择 New → Other… → CORBA Wizard → Server → Active object map 如下图:
点击Next ,弹出新的对话框,如下图:
IDL filename :选中创建的Hello.idl
Interface :选择IDL文件里定义的接口名
Package :输入包名
Server classesname :服务端类的名称
然后点击 Next,在弹出对话框里选中 Create server class 项,如下图:
点击Finish完成服务端类的初步创建,然后需要在生成的服务端类中添加还未具体实现的方法,
打开 HelloServiceServerImpl.java 文件,添加如下方法:
@Override
public String sayHello(String msg) {
System.out.println("[服务端] 接收的参数 : " + msg);
String ret = "Hi," + msg + " welcome to CORBA";
System.out.println("[服务端] 返回信息 : " + ret);
return ret;
}
1
2
3
4
5
6
7
@Override
publicStringsayHello(Stringmsg){
System.out.println("[服务端] 接收的参数 : "+msg);
Stringret="Hi,"+msg+" welcome to CORBA";
System.out.println("[服务端] 返回信息 : "+ret);
returnret;
}
【4】、创建客户端
在 src 文件夹上右键依次选择 New → Other… → CORBA Wizard → Client→ Simple implementation 如下图:
点击Next ,弹出新的对话框,如下图:
IDL filename :选中创建的Hello.idl
Interface :选择IDL文件里定义的接口名
Package :输入包名
Client classesname :客户端类的名称
点击 Finish 按钮完成客户端类的初步创建,把客户端类
HelloServiceClientImpl.java 中的main方法修改成如下:
public static void main(String[] args) {
try {
HelloServiceClientImpl test = new HelloServiceClientImpl();
// test.getORBInterface().operation1("A message in the bottle...");
String ret = test.getORBInterface().sayHello("micmiu.com");
System.out.println("[客户端] 调用结果 : " + ret);
test.shutdown();
} catch (IOException ex) {
ex.printStackTrace();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
publicstaticvoidmain(String[]args){
try{
HelloServiceClientImpltest=newHelloServiceClientImpl();
// test.getORBInterface().operation1("A message in the bottle...");
Stringret=test.getORBInterface().sayHello("micmiu.com");
System.out.println("[客户端] 调用结果 : "+ret);
test.shutdown();
}catch(IOExceptionex){
ex.printStackTrace();
}
}
【5】、测试本地调用
首先运行服务端:Server_AOM.java 然后再运行客户端类:HelloServiceClientImpl.java
服务端日志如下:
CORBA Server ready…
[服务端] 接收的参数 : micmiu.com
[服务端] 返回信息 : Hi,micmiu.com welcome to CORBA
客户端日志如下:
[客户端] 调用结果 : Hi,micmiu.com welcome to CORBA
【6】.NamingService 命名服务实现远程调用
第一步: 服务端Server_AOM.java代码修改
注释调以下代码:
//PrintWriter ps = new PrintWriter(new FileOutputStream(new File("server.ior")));
//ps.println(orb.object_to_string(obj));
//ps.close();
1
2
3
//PrintWriter ps = new PrintWriter(new FileOutputStream(new File("server.ior")));
//ps.println(orb.object_to_string(obj));
//ps.close();
取消以下代码注释:
// ---- Uncomment below to enable Naming Service access. ----
org.omg.CORBA.Object ncobj = orb.resolve_initial_references("NameService");
NamingContextExt nc = NamingContextExtHelper.narrow(ncobj);
nc.bind(nc.to_name("MyServerObject"), obj);
1
2
3
4
// ---- Uncomment below to enable Naming Service access. ----
org.omg.CORBA.Objectncobj=orb.resolve_initial_references("NameService");
NamingContextExtnc=NamingContextExtHelper.narrow(ncobj);
nc.bind(nc.to_name("MyServerObject"),obj);
导入相关类的引用。
修改后完整代码如下:
package com.micmiu.idl.server;
import java.util.Properties;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.PortableServer.IdAssignmentPolicyValue;
import org.omg.PortableServer.LifespanPolicyValue;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.ThreadPolicyValue;
public class Server_AOM {
public static void main(String[] args) {
Properties props = System.getProperties();
//props.setProperty("org.omg.CORBA.ORBClass", "org.openorb.CORBA.ORB");
//props.setProperty("org.omg.CORBA.ORBSingletonClass", "org.openorb.CORBA.ORBSingleton");
// OpenORB 1.4.X
props.setProperty("org.omg.CORBA.ORBClass", "org.openorb.orb.core.ORB");
props.setProperty("org.omg.CORBA.ORBSingletonClass", "org.openorb.orb.core.ORBSingleton");
try {
// Initialize the ORB.
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, props);
// get a reference to the root POA
org.omg.CORBA.Object obj = orb.resolve_initial_references("RootPOA");
POA poaRoot = POAHelper.narrow(obj);
// Create policies for our persistent POA
org.omg.CORBA.Policy[] policies = {
poaRoot.create_lifespan_policy(LifespanPolicyValue.PERSISTENT),
poaRoot.create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID),
poaRoot.create_thread_policy(ThreadPolicyValue.ORB_CTRL_MODEL)
};
// Create myPOA with the right policies
POA poa = poaRoot.create_POA("HelloServiceServerImpl_poa",poaRoot.the_POAManager(), policies);
// Create the servant
HelloServiceServerImpl servant = new HelloServiceServerImpl();
// Activate the servant with the ID on myPOA
byte[] objectId = "AnyObjectID".getBytes();
poa.activate_object_with_id(objectId, servant);
// Activate the POA manager
poaRoot.the_POAManager().activate();
// Get a reference to the servant and write it down.
obj = poa.servant_to_reference(servant);
// ---- Uncomment below to enable Naming Service access. ----
org.omg.CORBA.Object ncobj = orb.resolve_initial_references("NameService");
NamingContextExt nc = NamingContextExtHelper.narrow(ncobj);
nc.bind(nc.to_name("MyServerObject"), obj);
//PrintWriter ps = new PrintWriter(new FileOutputStream(new File("server.ior")));
//ps.println(orb.object_to_string(obj));
//ps.close();
System.out.println("CORBA Server ready...");
// Wait for incoming requests
orb.run();
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
packagecom.micmiu.idl.server;
importjava.util.Properties;
importorg.omg.CosNaming.NamingContextExt;
importorg.omg.CosNaming.NamingContextExtHelper;
importorg.omg.PortableServer.IdAssignmentPolicyValue;
importorg.omg.PortableServer.LifespanPolicyValue;
importorg.omg.PortableServer.POA;
importorg.omg.PortableServer.POAHelper;
importorg.omg.PortableServer.ThreadPolicyValue;
publicclassServer_AOM{
publicstaticvoidmain(String[]args){
Propertiesprops=System.getProperties();
//props.setProperty("org.omg.CORBA.ORBClass", "org.openorb.CORBA.ORB");
//props.setProperty("org.omg.CORBA.ORBSingletonClass", "org.openorb.CORBA.ORBSingleton");
// OpenORB 1.4.X
props.setProperty("org.omg.CORBA.ORBClass","org.openorb.orb.core.ORB");
props.setProperty("org.omg.CORBA.ORBSingletonClass","org.openorb.orb.core.ORBSingleton");
try{
// Initialize the ORB.
org.omg.CORBA.ORBorb=org.omg.CORBA.ORB.init(args,props);
// get a reference to the root POA
org.omg.CORBA.Objectobj=orb.resolve_initial_references("RootPOA");
POApoaRoot=POAHelper.narrow(obj);
// Create policies for our persistent POA
org.omg.CORBA.Policy[]policies={
poaRoot.create_lifespan_policy(LifespanPolicyValue.PERSISTENT),
poaRoot.create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID),
poaRoot.create_thread_policy(ThreadPolicyValue.ORB_CTRL_MODEL)
};
// Create myPOA with the right policies
POApoa=poaRoot.create_POA("HelloServiceServerImpl_poa",poaRoot.the_POAManager(),policies);
// Create the servant
HelloServiceServerImplservant=newHelloServiceServerImpl();
// Activate the servant with the ID on myPOA
byte[]objectId="AnyObjectID".getBytes();
poa.activate_object_with_id(objectId,servant);
// Activate the POA manager
poaRoot.the_POAManager().activate();
// Get a reference to the servant and write it down.
obj=poa.servant_to_reference(servant);
// ---- Uncomment below to enable Naming Service access. ----
org.omg.CORBA.Objectncobj=orb.resolve_initial_references("NameService");
NamingContextExtnc=NamingContextExtHelper.narrow(ncobj);
nc.bind(nc.to_name("MyServerObject"),obj);
//PrintWriter ps = new PrintWriter(new FileOutputStream(new File("server.ior")));
//ps.println(orb.object_to_string(obj));
//ps.close();
System.out.println("CORBA Server ready...");
// Wait for incoming requests
orb.run();
}
catch(Exceptionex){
ex.printStackTrace();
}
}
}
第二步:客户端 HelloServiceClientImpl.java代码的修改
在main 方法中注释调如下代码:
//LineNumberReader input = new LineNumberReader(new FileReader(
//"server.ior"));
//String ior = input.readLine();
//org.omg.CORBA.Object obj = orb.string_to_object(ior);
1
2
3
4
//LineNumberReader input = new LineNumberReader(new FileReader(
//"server.ior"));
//String ior = input.readLine();
//org.omg.CORBA.Object obj = orb.string_to_object(ior);
取消下面代码的注释:
// ---- Uncomment below to enable Naming Service access. ----
org.omg.CORBA.Object ncobj = orb.resolve_initial_references("NameService");
NamingContextExt nc = NamingContextExtHelper.narrow(ncobj);
org.omg.CORBA.Object obj = nc.resolve_str("MyServerObject");
1
2
3
4
// ---- Uncomment below to enable Naming Service access. ----
org.omg.CORBA.Objectncobj=orb.resolve_initial_references("NameService");
NamingContextExtnc=NamingContextExtHelper.narrow(ncobj);
org.omg.CORBA.Objectobj=nc.resolve_str("MyServerObject");
并且修改成如下:
org.omg.CORBA.Object ncobj =
orb.string_to_object("corbaloc::1.2@127.0.0.1:1234/NameService");
NamingContextExt nc = NamingContextExtHelper.narrow(ncobj);
org.omg.CORBA.Object obj = nc.resolve_str("MyServerObject");
1
2
3
4
org.omg.CORBA.Objectncobj=
orb.string_to_object("corbaloc::1.2@127.0.0.1:1234/NameService");
NamingContextExtnc=NamingContextExtHelper.narrow(ncobj);
org.omg.CORBA.Objectobj=nc.resolve_str("MyServerObject");
并且把客户端中 IOException 全部改成 Exception。
ps: “corbaloc::1.2@127.0.0.1:1234/NameService” 这个和服务端启动的参数-ORBInitRef NameService 一致.
修改后客户端的完整代码如下:
package com.micmiu.idl.client;
/**
* The client implementation is generated by the ORB Studio.
*/
import java.io.IOException;
import java.util.Properties;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
class HelloServiceClientImpl {
private com.micmiu.idl.hello.HelloService target = null;
private org.omg.CORBA.ORB orb = null;
/**
* Constructor for HelloServiceClientImpl
*
* @throws IOException
*/
public HelloServiceClientImpl() throws Exception {
initORB(null);
}
/**
* Constructor for HelloServiceClientImpl
*
* @throws IOException
* @see java.lang.Object#Object()
*/
public HelloServiceClientImpl(String[] args) throws Exception {
initORB(args);
}
/**
* Initialize ORB.
*
* @param args
* @throws IOException
*/
public void initORB(String[] args) throws Exception {
Properties props = System.getProperties();
// props.setProperty("org.omg.CORBA.ORBClass", "org.openorb.CORBA.ORB");
// props.setProperty("org.omg.CORBA.ORBSingletonClass",
// "org.openorb.CORBA.ORBSingleton");
// OpenORB 1.4.X
props.setProperty("org.omg.CORBA.ORBClass", "org.openorb.orb.core.ORB");
props.setProperty("org.omg.CORBA.ORBSingletonClass",
"org.openorb.orb.core.ORBSingleton");
// Initialize the ORB
orb = org.omg.CORBA.ORB.init((String[]) args, props);
// ---- Uncomment below to enable Naming Service access. ----
org.omg.CORBA.Object ncobj =
orb.string_to_object("corbaloc::1.2@127.0.0.1:1234/NameService");
NamingContextExt nc = NamingContextExtHelper.narrow(ncobj);
org.omg.CORBA.Object obj = nc.resolve_str("MyServerObject");
//LineNumberReader input = new LineNumberReader(new FileReader(
//"server.ior"));
//String ior = input.readLine();
//org.omg.CORBA.Object obj = orb.string_to_object(ior);
target = com.micmiu.idl.hello.HelloServiceHelper.narrow(obj);
}
/**
* Obtain ORB Interface.
*
* @return
*/
public com.micmiu.idl.hello.HelloService getORBInterface() {
return target;
}
/**
* Shutdown ORB.
*/
public void shutdown() {
orb.shutdown(true);
}
/**
* Test driver for HelloServiceClientImpl.
*
* @param args
*/
public static void main(String[] args) {
try {
HelloServiceClientImpl test = new HelloServiceClientImpl();
// test.getORBInterface().operation1("A message in the bottle...");
String ret = test.getORBInterface().sayHello("micmiu.com");
System.out.println("[客户端] 调用结果 : " + ret);
test.shutdown();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
packagecom.micmiu.idl.client;
/**
* The client implementation is generated by the ORB Studio.
*/
importjava.io.IOException;
importjava.util.Properties;
importorg.omg.CosNaming.NamingContextExt;
importorg.omg.CosNaming.NamingContextExtHelper;
classHelloServiceClientImpl{
privatecom.micmiu.idl.hello.HelloServicetarget=null;
privateorg.omg.CORBA.ORBorb=null;
/**
* Constructor for HelloServiceClientImpl
*
* @throws IOException
*/
publicHelloServiceClientImpl()throwsException{
initORB(null);
}
/**
* Constructor for HelloServiceClientImpl
*
* @throws IOException
* @see java.lang.Object#Object()
*/
publicHelloServiceClientImpl(String[]args)throwsException{
initORB(args);
}
/**
* Initialize ORB.
*
* @param args
* @throws IOException
*/
publicvoidinitORB(String[]args)throwsException{
Propertiesprops=System.getProperties();
// props.setProperty("org.omg.CORBA.ORBClass", "org.openorb.CORBA.ORB");
// props.setProperty("org.omg.CORBA.ORBSingletonClass",
// "org.openorb.CORBA.ORBSingleton");
// OpenORB 1.4.X
props.setProperty("org.omg.CORBA.ORBClass","org.openorb.orb.core.ORB");
props.setProperty("org.omg.CORBA.ORBSingletonClass",
"org.openorb.orb.core.ORBSingleton");
// Initialize the ORB
orb=org.omg.CORBA.ORB.init((String[])args,props);
// ---- Uncomment below to enable Naming Service access. ----
org.omg.CORBA.Objectncobj=
orb.string_to_object("corbaloc::1.2@127.0.0.1:1234/NameService");
NamingContextExtnc=NamingContextExtHelper.narrow(ncobj);
org.omg.CORBA.Objectobj=nc.resolve_str("MyServerObject");
//LineNumberReader input = new LineNumberReader(new FileReader(
//"server.ior"));
//String ior = input.readLine();
//org.omg.CORBA.Object obj = orb.string_to_object(ior);
target=com.micmiu.idl.hello.HelloServiceHelper.narrow(obj);
}
/**
* Obtain ORB Interface.
*
* @return
*/
publiccom.micmiu.idl.hello.HelloServicegetORBInterface(){
returntarget;
}
/**
* Shutdown ORB.
*/
publicvoidshutdown(){
orb.shutdown(true);
}
/**
* Test driver for HelloServiceClientImpl.
*
* @param args
*/
publicstaticvoidmain(String[]args){
try{
HelloServiceClientImpltest=newHelloServiceClientImpl();
// test.getORBInterface().operation1("A message in the bottle...");
Stringret=test.getORBInterface().sayHello("micmiu.com");
System.out.println("[客户端] 调用结果 : "+ret);
test.shutdown();
}catch(Exceptionex){
ex.printStackTrace();
}
}
}
第三步:测试命名服务实现远程调用
先启动命名服务的监听,以端口 1234 为例:
%OPENORB_HOME%/NamingService/bin/ins -ORBPort=1234
1
%OPENORB_HOME%/NamingService/bin/ins-ORBPort=1234
micmiu-mbp:OpenORB-1.4.0 micmiu$ NamingService/bin/ins -ORBPort=1234
[main] [INFO ] (ins): NameService 1.4.0 Copyright (c) 2002-2005 The Community OpenORB
[main] [INFO ] (ins): calling ORB.init
[main] [INFO ] (ins): Service started. Press CTRL-C to stop the service!
然后启动服务端:Server_AOM.java 需要配置启动参数:
-ORBInitRef NameService=corbaloc::1.2@127.0.0.1:1234/NameService
最后启动客户端HelloServiceClientImpl.java 测试调用,运行结果和上面本地调用测试的结果一样。
java corba实例,OpenORB开发CORBA的实例介绍相关推荐
- delphi android 蓝牙,Android实例-Delphi开发蓝牙官方实例解析(XE10+小米2+小米5)
[实例简介] 2.保证无毒 3.简单,方便,实用 4.实例可以自行改用 5.如有非法,本人无法律责任,由改动代码人负责! 6.需要更多本人作品,查找标签"朱建强" 7.请下载,杀毒 ...
- java JFreechart开发报表的实例demo下载
原文:java JFreechart开发报表的实例demo下载 源代码下载地址:http://www.zuidaima.com/share/1550463472110592.htm 运行效果图如下: ...
- Java微信开发-微信java开发接入平台实例
微信上接入平台的demo是PHP的,没得java的,所以我自己做接入的时候遇到了一点小问题.用java做带薪开发,首先就要先通过微信的接入配置,大概原理就是微信往服务器发送一些数据,然后在服务器端做一 ...
- jni java共享变量_JNI/NDK开发指南(七)——C/C++访问Java实例变量和静态变量 .
在上一章中我们学习到了如何在本地代码中访问任意Java类中的静态方法和实例方法,本章我们也通过一个示例来学习Java中的实例变量和静态变量,在本地代码中如何来访问和修改.静态变量也称为类变量(属性), ...
- jni java共享变量_Android JNI开发系列(十)JNI访问 Java 实例变量和静态变量
JNI访问 Java 实例变量和静态变量 Java 中的实例变量和静态变量,在本地代码中如何来访问和修改.静态变量也称为类变量(属性),在所有实例对象中共享同一份数据,可以直接通过类名.变量名来访问. ...
- java开发成语的过程_基于JAVA的成语词典接口调用代码实例
基于JAVA的成语词典接口调用代码实例 接口描述:基于JA V A的成语词典接口调用代码实例 接口平台:聚合数据 import java.io.BufferedReader; import java. ...
- android studio小案例代码,AndroidStudio开发小相册实例
郑州app开发AndroidStudio开发小相册实例代码如下. 布局代码如下: java代码如下: package cn.xhhkj.xhhkjtest; import android.app.Ac ...
- Android游戏开发的入门实例
在Android系统上开发游戏是Android开发学习者所向往的,有成就感也有乐趣,还能取得经济上的报酬.那怎样开发Android游戏呢?下面介绍一个简单的入门实例. 一.创建 ...
- 常见Java面试题之静态变量和实例变量的区别
静态变量和实例变量的区别有哪些? 静态变量和实例变量可能大多数同学用的比较多,但是相关阐述并不是很常见,尤其对新手同学可以不能清楚表达. 静态变量和实例变量也是最经常遇到的一个基础java面试题,不管 ...
最新文章
- MySql 中的常见问题解决方法
- php项目打开快捷方式,PHP_克隆一个新项目的快捷方式,有没想过最土的项目如何快速 - phpStudy...
- python读取序列5之后的数据_Python核心编程读笔 5: python的序列
- java for循环遍历解释,三种for循环遍历
- 如何辨别二逼互联网公司!?
- python的特性注定了代码无法保密_python 基础
- 一建机电实务教材电子版_这是属于一建人的“五年真题+3年模拟”,实务能考128分全靠它了...
- 035——VUE中表单控件处理之使用vue控制select操作文字栏目列表
- 大型油烟机清洗机器人_大型油烟机清洗机
- 《How to Reshape Input Data for Long Short-Term Memory Networks in Keras》学习笔记
- 具体解说Android的图片下载框架UniversialImageLoader之磁盘缓存(一)
- 算法整理(二)---高速排序的两种实现方式:双边扫描和单边扫描
- Ubuntu 18.04 国内源
- 罗技 logic C930c 摄像头 驱动 win7 64位 家庭中文版 无法使用
- 基于栈的字节码解释执行引擎图解
- java的string的intern_java String的intern()方法
- DLL文件如何还原打开方式
- maven 生成脚手架_如何通过脚手架和自动表格生成加速流星开发
- 腾讯云主机免费升级有感而发
- python URL解析转换成字典
热门文章
- MapReduce编程 -词频统计
- 博奥智源营销劵发放平台网页端技术开发功能清单
- 《品味大数据》的“魔力”
- 从0基础到全国亚军,自学机器学习如何挺进Kaggle前20%
- ActionBar之分享图片
- C语言数组指定初始化器
- 基于JAVA的银行柜员绩效考核系统,适合用来练手【数据库设计、源码、开题报告】
- centos-7(1908)配置HTTPS
- 【2】CentOS-8.4.2105-x86_64的下载说明与安装
- java反射行跨站脚本攻击_Web安全之防止XSS跨站脚本攻击