将来自JInterface Java应用程序的二进制响应转换回Elixir中的字符串列表

问题描述 投票:1回答:1

我有一个小型Java应用程序,并且我已经使用JInterface在我的灵丹妙药应用程序中将其作为OTP进程公开。我可以调用它并成功获得响应。

我的问题是我在elixir中返回的响应是二进制的,但我无法弄清楚如何将二进制转换为响应的字符串列表。

使用JInterface的Java OTP节点代码如下:

public void performAction(Object requestData, OtpMbox mbox, OtpErlangPid lastPid){
    List<String> sentences = paragraphSplitter.splitParagraphIntoSentences((String) requestData, Locale.JAPAN);
    mbox.send(lastPid, new OtpErlangBinary(getOtpStrings(sentences)));
    System.out.println("OK");
}

private List<OtpErlangString> getOtpStrings(List<String> sentences) {
    List<OtpErlangString> erlangStrings = new ArrayList<>();
    for(int i = 0; i < sentences.size(); i++){
        erlangStrings.add(new OtpErlangString(sentences.get(i)));
    }
    return erlangStrings;
}

有必要将响应包装在OtpErlangBinary中,并且我已将字符串协调为OTPErlangString。我也尝试过不将字符串转换为OTPErlangString。

在长生不老药方面,我可以接收二进制响应并对其进行IO。检查。

有人知道除了单个字符串以外的其他内容时,有人知道如何使用JInterface正确反序列化结果吗?或者,如果我犯了一些错误,如何构建正确的响应类型,以便可以正确地反序列化?

由于我多年来一直在努力解决这个问题,因此我们将不胜感激。预先感谢。

java elixir deserialization otp jinterface
1个回答
0
投票

我一直在玩JInterface和Elixir,我想我已经解决了你的问题。

因此,您正在尝试将字符串列表从Elixir / Erlang节点发送到Java节点,但是您无法正确地对其进行反序列化。

Elixir具有其自身的类型(例如atomstuples,..),而Java具有其自身的类型(例如ObjectStringList<String> ..)。如果应该彼此交谈,则需要从一种类型转换为另一种类型。最后,无论如何都是通过电线发送的一堆1和0。

如果将Erlang列表发送到Java,则到达的内容始终可以解释为OtpErlangObject。然后,您甚至可以尝试猜测实际的类型,然后再将其转换为Java值。

// We know that everything is at least an OtpErlangObject value!
OtpErlangObject o = mbox.receive();

但是如果您知道它实际上是一个列表,我们可以将其转换为OtpErlangList值。

// We know o is an Erlang list!
OtpErlangList erlList = (OtpErlangList) o;

但是,此列表的元素仍然未知。因此,这时它仍然是OtpErlangObject的列表。

但是,我们知道这是一个字符串列表,因此我们可以将OtpErlangObject的列表解释为OtpErlangString的列表,并将其转换为Java字符串。

public static List<String> ErlangListToStringList(OtpErlangList estrs) {
    OtpErlangObject[] erlObjs = estrs.elements();
    List<String> strs = new LinkedList<String>();

    for (OtpErlangObject erlO : erlObjs) {
        strs.add(erlO.toString());
    }
    return strs;
}

请注意,我在这里经常使用术语列表,因为它实际上是一个Erlang列表,在Java中,它们全部表示为数组!

下面列出了我的完整代码。

import com.ericsson.otp.erlang.*;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

public class Main {
    public static OtpErlangList StringListToErlangList(List<String> strs) {
        OtpErlangObject[] elems = new OtpErlangObject[strs.size()];

        int idx = 0;
        for (String str : strs) {
            elems[idx] = new OtpErlangString(str);
            idx++;
        }

        return new OtpErlangList(elems);
    }

    public static List<String> ErlangListToStringList(OtpErlangList estrs) {
        OtpErlangObject[] erlObjs = estrs.elements();
        List<String> strs = new LinkedList<String>();

        for (OtpErlangObject erlO : erlObjs) {
            strs.add(erlO.toString());
        }
        return strs;
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        // Do some initial setup.
        OtpNode node = new OtpNode("alice", "secret");
        OtpMbox mbox = node.createMbox();
        mbox.registerName("alice");

        // Check that the remote node is actually online.
        if (node.ping("bob@rioolputje", 2000)) {
            System.out.println("remote is up");
        } else {
            System.out.println("remote is not up");
        }

        // Create the list of strings that needs to be sent to the other node.
        List<String> strs = new LinkedList<String>();
        strs.add("foo");
        strs.add("bar");
        OtpErlangList erlangStrs = StringListToErlangList(strs);

        // Create a tuple so the other node can reply to use.
        OtpErlangObject[] msg = new OtpErlangObject[2];
        msg[0] = mbox.self();
        msg[1] = erlangStrs;
        OtpErlangTuple tuple = new OtpErlangTuple(msg);

        // Send the tuple to the other node.
        mbox.send("echo", "bob@rioolputje", tuple);

        // Await the reply.
        while (true) {
            try {
                System.out.println("Waiting for response!");
                OtpErlangObject o = mbox.receive();

                if (o instanceof OtpErlangList) {
                    OtpErlangList erlList = (OtpErlangList) o;
                    List<String> receivedStrings = ErlangListToStringList(erlList);
                    for (String s : receivedStrings) {
                        System.out.println(s);
                    }
                }
                if (o instanceof OtpErlangTuple) {
                    OtpErlangTuple m = (OtpErlangTuple) o;
                    OtpErlangPid from = (OtpErlangPid) (m.elementAt(0));
                    OtpErlangList value = (OtpErlangList) m.elementAt(1);
                    List<String> receivedStrings = ErlangListToStringList(value);

                    for (String s : receivedStrings) {
                        System.out.println(s);
                    }
                }

            } catch (OtpErlangExit otpErlangExit) {
                otpErlangExit.printStackTrace();
            } catch (OtpErlangDecodeException e) {
                e.printStackTrace();
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.