杰瑞科技汇

flex如何调用Java方法?

最常用、最标准的方式是使用 HTTPServiceWebService 来与后端进行数据交换,但更现代、更高效的方式是使用 BlazeDS(一个开源的、基于 AMF 的消息服务),它由 Adobe 开发,现在是 Apache Flex 的一部分,专门用于 Flex 和 Java 之间的通信。

下面我将分三种主要方式来详细说明,并给出完整的示例。


核心概念

无论使用哪种方式,Flex 调用 Java 的基本流程都遵循以下模式:

  1. Flex (客户端):发起一个请求,这个请求可以是一个简单的 HTTP GET/POST,或者一个 AMF 对象。
  2. 网络传输:请求通过网络发送到 Java 后端。
  3. Java (服务端):接收请求,执行相应的 Java 业务逻辑(方法)。
  4. Java (服务端):将执行结果(数据)打包成 Flex 能识别的格式(如 XML, JSON, 或 AMF 对象)。
  5. 网络传输:将响应数据发送回 Flex 客户端。
  6. 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.xmlweb.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 服务。

分享:
扫描分享到社交APP
上一篇
下一篇