Serving RDF representation of Java model with Spring MVC?

此生再无相见时 提交于 2019-12-04 15:01:16

Assuming that you are using annotation driven configuration for your MVC application, this actually could be quite simple. Using the W3C's Media Types Issues for Text RDF Formats as a guide for content type specification, it's quite easy to augment your existing solution. The real question is what is your desired serialization type when a request for RDF is made? If we are utilizing Jena as the underlying model technology, then supporting any of the standard serializations is trivial out of the box. Json is the only one that provided me with a little difficulty, but you have already solved that.

As you can see, the implementation of the serialization (using standard Jena, and no additional libraries) is actually quite easy to do! The problem is ultimately just matching the proper serialization to the provided content-type.

EDIT April 19th, 2014

Previous content types were from a document capturing discussions of the working group. The post has been edited to reflect the content types of the IANA Media Type registry supplemented with the RDF1.1 N-Triples and JSON-LD standards.

@Controller
public class SpecialController 
{
    public Model model = null; // set externally

    @RequestMapping(value="your/service/location", method=RequestMethod.GET, produces={"application/x-javascript", "application/json", "application/ld+json"})
    public @ResponseBody String getModelAsJson() {
       // Your existing json response
    }

    @RequestMapping(value="your/service/location", method=RequestMethod.GET, produces={"application/xml", "application/rdf+xml"})
    public @ResponseBody String getModelAsXml() {
       // Note that we added "application/rdf+xml" as one of the supported types
       // for this method. Otherwise, we utilize your existing xml serialization
    }

    @RequestMapping(value="your/service/location", method=RequestMethod.GET, produces={"application/n-triples"})
    public @ResponseBody String getModelAsNTriples() {
       // New method to serialize to n-triple
       try( final ByteArrayOutputStream os = new ByteArrayOutputStream() ){
           model.write(os, "N-TRIPLE");
           return os.toString();
       }
    }

    @RequestMapping(value="your/service/location", method=RequestMethod.GET, produces={"text/turtle"})
    public @ResponseBody String getModelAsTurtle() {
       // New method to serialize to turtle
       try( final ByteArrayOutputStream os = new ByteArrayOutputStream() ){
           model.write(os, "TURTLE");
           return os.toString();
       }
    }

    @RequestMapping(value="your/service/location", method=RequestMethod.GET, produces={"text/n3"})
    public @ResponseBody String getModelAsN3() {
       // New method to serialize to N3
       try( final ByteArrayOutputStream os = new ByteArrayOutputStream() ){
           model.write(os, "N3");
           return os.toString();
       }
    }
}

I'll preface this by mentioning that I don't know anything about Spring MVC. But, if you have a Java object you want to serialize as RDF, a library like Empire (I'm the author), might help you. You can annotate the object to specify what things should be turned into RDF and then use the RdfGenerator class to return back an RDF graph representing the object. You can then use something like the RIO RDF writer from the Sesame framework to serialize the graph as whatever RDF serialization is requested.

I know that's not Spring MVC specific, but if you can get the OutputStream & the requested content-type, you should be able to make it work with Empire & Sesame's RIO.

In addition, you must add the charset parameter. StringHttpMessageConverter uses as default character encoding ISO-8859-1 unless you change it. When the output format has a fixed encoding different from ISO-8859-1 (e.g. UTF-8), it must be declared in produces. This behaviour is consistent with specs. For example, when the model contains non ASCII characters and it is encoded in turtle, the specification says that the media type text/turtle must contain the parameter charset with the value UTF-8. Otherwise, it is optional.

  @RequestMapping(value = "your/service/location", method = RequestMethod.GET, 
        produces = { "text/turtle;charset=UTF-8"})
  public @ResponseBody String getModelAsTurtle() throws IOException {
    try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
        RDFDataMgr.write(os, model, RDFFormat.TURTLE_PRETTY);
        return os.toString();
    }
  }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!