主要内容

本页采用了机器翻译。点击此处可查看英文原文。

Java 客户端中使用协议缓冲区进行异步 RESTful 请求

此示例展示如何使用 Java® 客户端 API、MATLAB® Production Server™ 用于 MATLAB 函数执行的 RESTful API 和协议缓冲区 (protobuf) 发出异步 RESTful 请求。该示例提供并解释了一个示例 Java 客户端 AsyncExample.java,用于评估部署在服务器上的 MATLAB 函数。

要在向服务器发出请求时使用 protobuf,请在客户端代码中将 HTTP Content-Type 标头设置为 application/x-google-protobuf。Java 客户端库提供帮助类,以根据 proto 格式内部创建 protobuf 消息并返回相应的字节数组。在 HTTP 请求正文中使用此字节数组。Java 客户端库提供了反序列化 protobuf 响应的方法和类。

要使用 Java 客户端库,必须在 mps_client.jar 中包含 CLASSPATH

下表显示了在哪里可以找到示例的 mps_client.jar 文件、Javadoc 和示例代码。

mps_client.jar 的位置
  • MPS_INSTALL/client/java

  • MATLABProductionServer_<release>_Clients/java

Javadoc 的位置
  • MPS_INSTALL/client/java/doc

  • MATLABProductionServer_<release>_Clients/java/doc

示例文件的代码位置
  • MPS_INSTALL/client/java/examples

  • MATLABProductionServer_<release>_Clients/java/examples/MagicSquare

该示例使用 java.net 包发出 HTTP 请求来评估在 http://localhost:9910 上运行的 MATLAB Production Server 实例上部署的 MATLAB 函数。

在服务器上部署您的 MATLAB 函数

编写一个使用 magic (MATLAB) 函数创建幻方的 MATLAB 函数 mymagic,然后将其部署在服务器上。

有关如何部署的信息,请参阅针对 MATLAB Production Server 创建可部署存档

function m = mymagic(in)

  m = magic(in);
end

函数 mymagic 接受单个 int32 输入并以二维 double 数组的形式返回一个幻方。

向服务器发出异步请求

  1. 构建请求 URL。

    在 Java 客户端中,使用POST Asynchronous Request向服务器发出初始请求。请求 URL 包括服务器实例的地址、部署的存档的名称和要评估的 MATLAB 函数的名称。将 HTTP 请求的 mode 设置为 async,将 client 设置为查询参数中的用户定义的标识符值。

        String clientId = "123";
        String mpsBaseUrl = "http://localhost:9910";
        URL url;
        url = new URL(mpsBaseUrl + "/mymagic/mymagic?mode=async&client="+clientId);

  2. 设置请求标头。

    将 HTTP Content-Type 标头设置为 application/x-google-protobuf,因为 API 返回协议缓冲区消息的字节数组。

        final static protected String CONTENT_TYPE = "application/x-google-protobuf";
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setDoOutput(true);
        urlConnection.setRequestProperty("Content-Type", CONTENT_TYPE);
  3. 创建包含协议缓冲区消息的 HTTP 请求正文。

    使用 newInstance(arg1, arg2, arg3) 类中定义的 MATLABParams 方法来构建协议缓冲区消息。由于 mymagic 函数返回单个二维数组,因此将 arg1 设置为 1,将 arg2 设置为 double[][].class。为 arg3 指定一个整数值,它是 mymagic 函数的输入。

        MATLABParams mlMakeBody = MATLABParams.newInstance(1, double[][].class, 2);
  4. 将请求发送到服务器。

    MATLABParams mlMakeBody 对象写入 HTTP 请求的输出流。

        OutputStream output = urlConnection.getOutputStream();
        output.write(mlMakeBody.getRequestBody());
        output.flush();
    
  5. 接收并解释服务器响应。

    成功执行 HTTP 请求后,服务器将使用协议缓冲区消息进行响应。使用 MATLABRequestHandle 类中的方法解析协议缓冲区消息,以获取请求的状态、请求的 URL 以及请求的最后修改序列值等详细信息。

        MATLABRequestHandle mlInitialResponse = 
            MATLABRequestHandle.newInstance(urlConnection.getInputStream());
        System.out.println("First Request has been Sent. Initial response is below");
        System.out.println("State: "+ mlInitialResponse.getState() + " " + "Request URL: "
            +mlInitialResponse.getRequestURL() + " Last modified sequence: " + 
                mlInitialResponse.getLastModifiedSeq());
    

获取请求的状态信息

  1. 发出请求以获取请求状态信息。

    使用GET State Information RESTful API 获取请求的状态。在请求 URL 中,将查询参数 format 设置为 protobuf,以便服务器以协议缓冲区格式返回输出。

        url = new URL(mpsBaseUrl + mlInitialResponse.getRequestURL() + "/info?" + "format=protobuf");    
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setRequestProperty("Content-Type", CONTENT_TYPE);
        urlConnection.setRequestMethod("GET");
        urlConnection.connect();
  2. 解析响应。

    使用 MATLABRequest 类中定义的方法解析响应以获取请求的状态和服务器上的当前 lastModifiedSeq 值。

        MATLABRequest requestInfoTmp = MATLABRequest.newInstance(urlConnection.getInputStream());
        System.out.println("State: " + requestInfoTmp.getState() + 
                           " Last modified sequence: " + requestInfoTmp.getLastModifiedSeq());

在异步模式下,客户端能够向服务器发送多个请求。要获取每个 POST 请求的状态信息,必须向 GET State Information RESTful API 发出相应的请求。

查看特定客户端拥有的请求集合

使用 GET Collection of Requests RESTful API 查看由 clientId 代表的特定客户端发送的多个请求的信息。在请求 URL 中,将查询参数 format 设置为 protobuf,以便服务器以协议缓冲区格式返回输出。使用 MATLABRequestsnewInstance 方法解析成功请求的响应主体。MATLABRequests 类有一个 getMATLABRequests 方法,它返回 MaprequestURLMATLABRequest 对象。

    url = new URL(mpsBaseUrl + mlInitialResponse.getInstanceId() + "requests" + "?since="
        + mlInitialResponse.getLastModifiedSeq() + "&format=protobuf&" + "clients=" + clientId);
    urlConnection = (HttpURLConnection) url.openConnection();
    urlConnection.setRequestProperty("Content-Type", CONTENT_TYPE);
    urlConnection.setRequestMethod("GET");
    urlConnection.connect();

    MATLABRequests updates = MATLABRequests.newInstance(urlConnection.getInputStream());

    Map<String, MATLABRequest> urlUpdates = updates.getMATLABRequests();
    System.out.println("State of the Requests with the client: " + clientId);
    for (String requestURL : urlUpdates.keySet()) {
        System.out.println(requestURL + ":" + urlUpdates.get(requestURL).getState());
    }

检索请求的结果

  1. 发出请求以获取响应。

    当请求状态变为 READYERROR 后,使用GET Result of Request RESTful API 获取请求结果。在请求 URL 中,将查询参数 format 设置为 protobuf,以便服务器以协议缓冲区格式返回输出。

        url = new URL(mpsBaseUrl + mlInitialResponse.getRequestURL() + "/result?" + "format=protobuf");
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setRequestProperty("Content-Type", CONTENT_TYPE);
        urlConnection.setRequestMethod("GET");
        urlConnection.connect();
    

  2. 解析响应。

    如果请求状态为 READY,则使用 MATLABResult 类中定义的方法来解析响应。要创建 MATLABResult 对象,请将 MATLABParams mlMakeBody 对象和 Request 请求的 GET 结果的响应主体传递给 newInstance 方法。

    如果部署的 MATLAB 函数执行时出现错误,则对 getResult 方法的调用将抛出包含来自 MATLAB 的错误消息的 MATLABException

    如果请求状态为 ERROR,则使用 HTTPErrorInfo 类而不是 MATLABResult 类来解析响应。使用 HTTPErrorInfo 类中定义的方法获取有关错误的信息。

        if (requestInfoTmp.compareTo(MATLABRequestState.ERROR_STATE) == 0) {
            HTTPErrorInfo httpErrorInfo = HTTPErrorInfo.newInstance(urlConnection.getInputStream());
            System.out.println("ErrorCode: " + httpErrorInfo.getHttpErrorCode());
            System.out.println("Error Message: " + httpErrorInfo.getHttpErrorMessage());
            System.out.println("Error body: " + httpErrorInfo.getHttpBody());
        }
        else{
            MATLABResult<double[][]> mlFinalResult1 = MATLABResult.newInstance(mlMakeBody,
                                                                               urlConnection.getInputStream());
            try{
                double[][] magicSq1 = mlFinalResult1.getResult();
                printResult(magicSq1);
            }catch(MATLABException e){
                e.printStackTrace();
            }
        }
    
  3. 显示结果。

    编写一个辅助方法 printResult,将从响应主体解析的结果作为输入并打印相应的二维数组。

        private static void printResult(double[][] result) {
            for (double[] row : result) {
                for (double element : row) {
                    System.out.print(element + " ");
                }
                System.out.println();
            }
        }

AsyncExample.java Java 客户端的示例代码如下。

代码:

 AsyncExample.java

另请参阅

主题