Struct Support for RESTful Requests Using Protocol Buffers in the Java Client

This example shows how to send MATLAB® structures (struct) represented as arrays of Java® objects as input when you make a synchronous request using the Java client API, MATLAB Production Server™ RESTful API, and protocol buffers (protobuf). The example provides and explains a sample Java client, SortStudentsSyncREST.java, for evaluating a MATLAB function deployed on the server.

To use protobuf when making a request to the server, set the HTTP Content-Type header to application/x-google-protobuf in the client code. The Java client library provides helper classes to internally create protobuf messages based on a proto format and returns the corresponding byte array. Use this byte array in the HTTP request body. The Java client library provides methods and classes to deserialize the protobuf responses.

To use the Java client library, you must include mps_client.jar in the CLASSPATH.

The following table shows where to find the mps_client.jar file, Javadoc, and sample code for the example.

Location of mps_client.jar
  • MPS_INSTALL/client/java

  • MATLABProductionServer_<release>_Clients/java

Location of Javadoc
  • MPS_INSTALL/client/java/doc

  • MATLABProductionServer_<release>_Clients/java/doc

Location of code for the example files
  • MPS_INSTALL/client/java/examples

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

The example uses the java.net package for making HTTP requests to evaluate a MATLAB function deployed on a MATLAB Production Server instance running on http://localhost:9910.

Deploy your MATLAB function on the server

Write a MATLAB function sortstudents that takes an array of structures as input and returns a sorted array of students based on their score. Student name, score and grade form the fields of the input structure. Deploy this function on the server. For information on how to deploy, see Create a Deployable Archive for MATLAB Production Server.

function sorted = sortstudents(unsorted)

scores = {unsorted.score};
scores = cell2mat(scores);
[s i] = sort(scores);
sorted = unsorted(i);

Create helper classes

  1. Create a Java class Student with the same data members as the input structure.

    class Student {
        String name;
        int score;
        String grade;
    }
    
  2. Create a Java class StudentMarshaller that extends the interface MWDefaultMarshalingRules. Since Java does not natively support structs, extending the MWDefaultMarshalingRules interface lets you implement a new set of marshaling rules for the list of classes being marshaled and serialize Java objects to structs and deserialize structs to Java objects.

        public class StudentMarshaller extends MWDefaultMarshalingRules {
            @override
            public List<Class> getStructTypes() {
            List structType = new ArrayList();
            structType.add(Student.class);
            return structType;
            }
        }

  3. Create an array of type Student that you want to sort.

        Student[] students = new Student[]{new Student("Toni Miller", 90, "A"),
        new Student("Ed Plum", 80, "B+"),
        new Student("Mark Jones", 85, "A-")};

Make a synchronous request to the server

  1. Construct the request URL.

    In the Java client, use the POST Synchronous Request RESTful API to make the initial request to the server. The request URL comprises of the address of the server instance, the name of the deployed archive and the name of the MATLAB function to evaluate.

        String mpsBaseUrl = "http://localhost:9910";
        URL url;
        url = new URL(mpsBaseUrl + "/sortstudents/sortstudents");

  2. Set the request headers.

    Set the HTTP Content-Type header to application/x-google-protobuf, as the API returns a byte array of protocol buffer messages.

        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. Create the HTTP request body.

    To create the HTTP request body, pass the StudentMarshaller class as an argument to the MATLABParamsnewInstance method. StudentMarshaller class serializes an array of Java objects of the class Student into an array of structs and deserializes the array of structs into to an array of Java objects of class Student.

        MATLABParams mlMakeBody = MATLABParams.newInstance(1, Student[].class, new StudentMarshaller(), new Object[]{students});

  4. Send the request to the server.

    Write the MATLABParams mlMakeBody object to the output stream of the HTTP request.

        OutputStream output = urlConnection.getOutputStream();
        output.write(mlMakeBody.getRequestBody());
        output.flush();
    

Receive and interpret the server response

On successful execution of the HTTP request, the server responds with a protocol buffer message. Parse the protocol buffer message using methods from the MATLABResult class to get the result of the request. Create a MATLABResult object using the newInstance method. The newInstance method takes the MATLABParams mlMakeBody object and the response body of the HTTP request as input arguments. Set the return type of the MATLABResult object to Student[].

    MATLABResult<Student[]> mlFinalResult = MATLABResult.newInstance(mlMakeBody, urlConnection.getInputStream());
    try{
        Student[] magicSq = mlFinalResult.getResult();
        for (Student student : magicSq) {
        System.out.println(student);
        }
    }catch(MATLABException e){
        e.printStackTrace();
    }

Sample code for the SortStudentsSyncREST.java Java client and the Student.java helper class follows.

Code:

 SortStudentsSyncREST.java

 Student.java

Related Topics