最常用、最标准的方式是使用 HTTPService 或 WebService 来与后端进行数据交换,但更现代、更高效的方式是使用 BlazeDS(一个开源的、基于 AMF 的消息服务),它由 Adobe 开发,现在是 Apache Flex 的一部分,专门用于 Flex 和 Java 之间的通信。
下面我将分三种主要方式来详细说明,并给出完整的示例。
核心概念
无论使用哪种方式,Flex 调用 Java 的基本流程都遵循以下模式:
- Flex (客户端):发起一个请求,这个请求可以是一个简单的 HTTP GET/POST,或者一个 AMF 对象。
- 网络传输:请求通过网络发送到 Java 后端。
- Java (服务端):接收请求,执行相应的 Java 业务逻辑(方法)。
- Java (服务端):将执行结果(数据)打包成 Flex 能识别的格式(如 XML, JSON, 或 AMF 对象)。
- 网络传输:将响应数据发送回 Flex 客户端。
- Flex (客户端):接收响应,解析数据,并更新 UI。
使用 HTTPService (最通用)
这种方式不依赖于任何 Flex 特有的技术,它就是标准的 HTTP 请求,类似于网页中的 AJAX 请求,后端可以是一个普通的 Servlet。
Flex 端代码
// Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
// 定义一个 Java 对象的 ActionScript 映射
[RemoteClass(alias="com.example.model.User")]
public class User {
public var id:int;
public var name:String;
public var email:String;
}
// 当用户点击按钮时触发
protected function callJavaMethod():void {
// 创建 HTTPService 对象
var service:HTTPService = new HTTPService();
service.url = "http://localhost:8080/YourJavaApp/getUser"; // 你的 Java Servlet 地址
service.method = "POST"; // 或 "GET"
// 设置请求参数
var params:Object = new Object();
params.userId = 123; // 传递给 Java 方法的参数
service.send(params);
// 添加结果和错误事件监听器
service.addEventListener(ResultEvent.RESULT, onResult);
service.addEventListener(FaultEvent.FAULT, onFault);
}
// 请求成功回调
protected function onResult(event:ResultEvent):void {
// event.result 是从 Java 返回的数据
// 如果返回的是 JSON,需要使用 JSONDecoder 解析
// 如果返回的是 XML,可以直接访问 XML 对象
// 这里假设返回的是 JSON 格式: {"id": 123, "name": "John Doe", "email": "john@example.com"}
var user:Object = JSON.decode(String(event.result));
// 更新 UI
resultText.text = "用户信息: \nID: " + user.id +
"\n姓名: " + user.name +
"\n邮箱: " + user.email;
}
// 请求失败回调
protected function onFault(event:FaultEvent):void {
resultText.text = "发生错误: " + event.fault.faultString;
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout paddingTop="20" paddingLeft="20"/>
</s:layout>
<s:Button label="调用 Java 方法获取用户信息" click="callJavaMethod()"/>
<s:TextArea id="resultText" width="400" height="200"/>
</s:Application>
Java 端代码 (Servlet)
// GetUserServlet.java
package com.example.servlet;
import com.example.model.User;
import com.google.gson.Gson; // 使用 Gson 库处理 JSON
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class GetUserServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取 Flex 发送的参数
String userIdStr = request.getParameter("userId");
int userId = Integer.parseInt(userIdStr);
// 2. 执行业务逻辑(调用Java方法)
User user = findUserById(userId); // 假设这是你的业务方法
// 3. 将结果序列化为 JSON
Gson gson = new Gson();
String jsonUser = gson.toJson(user);
// 4. 设置响应头和内容,并返回给 Flex
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.print(jsonUser);
out.flush();
}
// 模拟的业务方法
private User findUserById(int id) {
User user = new User();
user.setId(id);
user.setName("John Doe");
user.setEmail("john.doe@example.com");
return user;
}
}
使用 BlazeDS (性能最高,推荐)
BlazeDS 使用 AMF (ActionScript Message Format) 协议,它是一种二进制协议,比 XML/JSON 更紧凑、传输更快,并且支持 ActionScript 和 Java 对象之间的直接映射(序列化/反序列化),这通常与 Spring 或其他 Java 框架集成。
配置 BlazeDS (在 Java 后端)
你需要配置 flex-services.xml 和 web.xml,这是一个简化的示例。
flex-services.xml (在 WEB-INF/flex/ 目录下)
<service id="remoting-service"
class="flex.messaging.services.RemotingService"
messageTypes="flex.messaging.messages.RemotingMessage">
<adapters>
<adapter-definition id="java-object" class="flex.messaging.adapters.JavaAdapter" default="true"/>
</adapters>
<destination id="userService">
<properties>
<source>com.example.service.UserService</source> <!-- 指向你的 Java 服务类 -->
</properties>
</destination>
</service>
web.xml
<!-- ... 其他配置 ... -->
<servlet>
<servlet-name>MessageBrokerServlet</servlet-name>
<servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
<init-param>
<param-name>services.configuration.file</param-name>
<param-value>/WEB-INF/flex/flex-services.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MessageBrokerServlet</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>
<!-- ... 其他配置 ... -->
Java 端代码 (服务类)
// UserService.java
package com.example.service;
import com.example.model.User;
public class UserService {
// 这个方法将被 Flex 直接调用
public User getUserById(int userId) {
System.out.println("Java 方法 getUserById 被调用,参数: " + userId);
User user = new User();
user.setId(userId);
user.setName("Jane Doe (via BlazeDS)");
user.setEmail("jane.doe@example.com");
return user;
}
}
Flex 端代码
// Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.RemoteObject;
// 定义一个 Java 对象的 ActionScript 映射
// [RemoteClass(alias="com.example.model.User")] // 如果使用 RemoteObject,通常不需要这个
// 当用户点击按钮时触发
protected function callJavaMethod():void {
// 创建 RemoteObject 对象
var remoteObject:RemoteObject = new RemoteObject();
remoteObject.destination = "userService"; // 对应 flex-services.xml 中的 destination id
remoteObject.endpoint = "http://localhost:8080/YourJavaApp/messagebroker/amf"; // BlazeDS 的 AMF 端点
// 调用 Java 方法,并传递参数
// Flex 会自动将 ActionScript 对象转换为 Java 对象
remoteObject.getUserById(456);
// 添加结果和错误事件监听器
remoteObject.addEventListener(ResultEvent.RESULT, onResult);
remoteObject.addEventListener(FaultEvent.FAULT, onFault);
}
// 请求成功回调
protected function onResult(event:ResultEvent):void {
// event.result 已经是自动反序列化好的 User 对象
var user:Object = event.result;
// 更新 UI
resultText.text = "用户信息 (BlazeDS): \nID: " + user.id +
"\n姓名: " + user.name +
"\n邮箱: " + user.email;
}
// 请求失败回调
protected function onFault(event:FaultEvent):void {
resultText.text = "发生错误: " + event.fault.faultString;
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout paddingTop="20" paddingLeft="20"/>
</s:layout>
<s:Button label="通过 BlazeDS 调用 Java 方法" click="callJavaMethod()"/>
<s:TextArea id="resultText" width="400" height="200"/>
</s:Application>
使用 WebService (基于 SOAP)
如果后端已经提供了标准的 WebService (SOAP),Flex 可以直接消费它。
Flex 端代码
// Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
protected function callWebService():void {
var ws:WebService = new WebService();
ws.wsdl = "http://www.webservicex.net/globalweather.asmx?wsdl"; // 示例 WSDL 地址
ws.useProxy = false;
// 调用 WSDL 中定义的方法
ws.GetWeather("New York", "United States");
ws.addEventListener(ResultEvent.RESULT, onResult);
ws.addEventListener(FaultEvent.FAULT, onFault);
}
protected function onResult(event:ResultEvent):void {
resultText.text = "获取到的天气信息:\n" + String(event.result);
}
protected function onFault(event:FaultEvent):void {
resultText.text = "SOAP 错误: " + event.fault.faultString;
}
]]>
</fx:Script>
<s:layout>
<s:VerticalLayout paddingTop="20" paddingLeft="20"/>
</s:layout>
<s:Button label="调用 WebService" click="callWebService()"/>
<s:TextArea id="resultText" width="400" height="200"/>
</s:Application>
总结与对比
| 特性 | HTTPService (JSON/XML) | BlazeDS (AMF) | WebService (SOAP) |
|---|---|---|---|
| 协议 | HTTP (文本: JSON/XML) | HTTP (二进制: AMF) | HTTP (文本: SOAP XML) |
| 性能 | 较慢 (文本解析开销大) | 最快 (二进制,序列化高效) | 较慢 (SOAP 协议开销大) |
| 易用性 | 简单,无需额外服务 | 需要配置 BlazeDS | 简单,直接消费 WSDL |
| 类型安全 | 弱 (需手动解析) | 强 (对象直接映射) | 弱 (基于 XML Schema) |
| 依赖 | 无 (任何 Servlet 容器) | 需要 BlazeDS/Flex | 需要 WebService 容器 |
| 适用场景 | 简单应用,或与现有 REST API 集成 | 企业级 Flex/Java 应用 (推荐) | 与现有 SOAP 服务集成 |
对于新建的 Flex 和 Java 集成项目,强烈推荐使用 BlazeDS,它提供了最佳的性能和开发体验,是 Flex 生态系统的核心组件,如果你的项目只需要简单的数据交互,或者后端是 RESTful 服务,HTTPService 是一个很好的选择。WebService 则用于对接已有的 SOAP 服务。
