java - 使用 Sesame 或 Apache Jena 通过套接字发送 RDF/XML

标签 java sockets rdf jena sesame

我正在尝试使用 Java 中的套接字将 RDF/XML 从客户端发送到服务器。当我发送信息时,服务器程序会挂起并且不会接收信息,除非我关闭客户端的 Socket 或 OutputStream。即使我刷新客户端上的 OutputStream,服务器也不会收到数据,除非我关闭套接字/流。我想在不关闭套接字的情况下发送信息。以下是客户端的一些示例代码(使用 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 很长时间了,但无法解决问题。我想这一定是我误解的简单的事情。有什么想法吗?

最佳答案

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

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

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

丑陋的 Hacky 解决方案

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

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

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

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

关于java - 使用 Sesame 或 Apache Jena 通过套接字发送 RDF/XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17577398/

相关文章:

java - Dijkstra算法中的无限循环?

java - 如何添加 AdMob 广告?

java - EntityListener 未调用

flash - Flex 4.6增加套接字接收缓冲区的大小

RDF - 分发 rdf :type to all items in the list

java - 动态更改提交给Executor服务的命令列表

java - 寻求用于套接字编程(Java 或 Python)的高级库

node.js - 发出事件时,数据是仅到达监听器还是所有客户端?

c - Redland RDF 库 : why does parsing model from Turtle without base URI cause error?

rdf - .ttl Turtle 文件可以有两个空前缀吗?