【问题标题】:Sending RDF/XML using Sesame or Apache Jena with Sockets使用 Sesame 或带有套接字的 Apache Jena 发送 RDF/XML
【发布时间】:2013-07-10 17:43:51
【问题描述】:

我正在尝试使用 Java 中的套接字将 RDF/XML 从客户端发送到服务器。当我发送信息时,服务器程序挂起并且不接收信息,除非我关闭客户端的 Socket 或 OutputStream。即使我在客户端刷新 OutputStream,除非我关闭 Socket/Stream,否则服务器也不会接收数据。我想在不关闭套接字的情况下发送信息。这是客户端的一些示例代码(使用 Sesame):

import java.io.*;
import java.net.*;
import org.openrdf.rio.*;
import org.openrdf.rio.helpers.*;
import org.openrdf.model.URI;
import org.openrdf.model.Model;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.Statement;
import org.openrdf.model.impl.*;
import org.openrdf.model.vocabulary.*;
public class SimpleRDFClient {
    private Socket socket = null;
    public static void main(String[] args) {
        new SimpleRDFClient(args[0],Integer.parseInt(args[1])).launch();
    }
    public SimpleRDFClient(String host, int port) {
        try {
            socket = new Socket(host,port);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    public void launch() {
        try {
            OutputStream out = socket.getOutputStream();
            BufferedOutputStream dos = new BufferedOutputStream(out);
            Model model = new LinkedHashModel();
            ValueFactory factory = new ValueFactoryImpl();
            URI clive = factory.createURI("http://www.site.org/cliveAnderson");
            Statement st = factory.createStatement(clive, RDF.TYPE, FOAF.PERSON);
            model.add(st);
            Rio.write(model,dos,RDFFormat.RDFXML);
            dos.flush();
            //Some other stuff
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}   

还有服务器处理程序:

import java.io.*;
import java.net.*;
import org.openrdf.rio.*;
import org.openrdf.rio.helpers.*;
import org.openrdf.model.*;
import org.openrdf.model.impl.*;

public class SimpleRDFSHandler implements Handler {
    public void handleConnection(Socket socket) {
        Model model = null;
        try {
            InputStream in = socket.getInputStream();

            model = Rio.parse(in,"www.blah.com",RDFFormat.RDFXML);

            for (Statement st: model) {
                System.out.println(st);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

问题似乎来自 Rio.parse() 方法挂起(我认为是因为它不知道输入何时结束)。当我以类似的方式使用 Jena api 时,我遇到了类似的问题,即使用 Model.write(outputstream,format) 和 Model.read(inputstream,format) 而不是 Rio。我已经查看了源代码和 javadoc 多年但无法解决问题。我想这一定是我误解了一些简单的事情。有什么想法吗?

【问题讨论】:

    标签: java sockets rdf jena sesame


    【解决方案1】:

    我认为这绝不是 Jena/Sesame 特有的问题,而是与您使用套接字有关的 Java 问题。实际上你不想关闭套接字有实际原因吗?

    我不明白为什么这会是可取的,除非您想连续发布数据并在服务器端接收到数据时对其进行处理?如果是这种情况,Jena 和 Sesame 都有 API,专门允许您控制数据在解析时发生的情况,这样您就不必依赖读取调用在处理数据之前完成。

    还有为什么要使用套接字,Sesame 和 Jena 都具有全面的 HTTP 集成,这比滚动您自己的基于套接字的服务器和客户端更易于使用和部署。

    丑陋的哈克解决方案

    如果你真的必须这样做,那么有一个解决方法,但它有点可怕和脆弱,我会强烈建议你不要这样做。

    在客户端写入数据后,写入指示流结束的字节序列。在服务器端使用自定义 InputStream 实现包装套接字流,该实现识别此序列并在看到它时停止返回数据。这应该允许期望流完成的 Jena/Sesame 代码正常运行。

    需要仔细选择字节序列,使其不会自然地出现在数据中。

    老实说,这是一个糟糕的主意,如果您的目标是连续发布数据,这并不能真正解决您的问题,因为除非您将服务器端套接字处理代码放在while (true) 循环,这可能是另一个坏主意。

    【讨论】:

    • 你说得对,我想不断地发布数据并在服务器端收到数据时对其进行处理。不使用 HTTP 集成的原因(可能不正确)是因为我有一个规则引擎,我需要对传入的数据做出反应;对服务器端存储库的任何请求都是由规则引擎而不是客户端发出的。所以我认为套接字将是要走的路。
    • 当您引用 Jena 和 Sesame API 时,允许您“控制数据在解析时发生的情况,这样您就不会依赖于在处理数据之前完成读取调用”,您想到了 API 的哪些特定部分?我看到这可以解决问题,但我需要一个关于 API 调用的指针。无法从文档中准确了解您的意思。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多