Построение форм запросов в Википедии в java с использованием jena - PullRequest
1 голос
/ 02 апреля 2011
#!/usr/local/bin/python

import sys
sys.path.append('/usr/home/bobd/lib/python/') # needed for hosted version
from SPARQLWrapper import SPARQLWrapper, JSON
import string
import urllib
import cgi

def main():
  form = cgi.FieldStorage() 
  dir1name = form.getvalue('dir1')
  dir2name = form.getvalue('dir2')

  sparql = SPARQLWrapper("http://data.linkedmdb.org/sparql")
  queryString = """

PREFIX m: <http://data.linkedmdb.org/resource/movie/>
SELECT DISTINCT ?actorName WHERE {

  ?dir1     m:director_name "DIR1-NAME".
  ?dir2     m:director_name "DIR2-NAME".
  ?dir1film m:director ?dir1;
            m:actor ?actor.

  ?dir2film m:director ?dir2;
            m:actor ?actor.

  ?actor    m:actor_name ?actorName.
}
  """

  queryString = queryString.replace("DIR1-NAME",dir1name)
  queryString = queryString.replace("DIR2-NAME",dir2name)

  sparql.setQuery(queryString)
  sparql.setReturnFormat(JSON)

  try:
    ret = sparql.query()
    results = ret.convert()
    requestGood = True
  except Exception, e:
    results = str(e)
    requestGood = False

  print """Content-type: text/html

    <html>
      <head>
        <title>results</title>
          <link href="simple.css" type="text/css" rel="stylesheet" />
      </head>
      <body>
"""

  if requestGood == False:
    print "<h1>Problem communicating with the server</h1>"
    print "<p>" + results + "</p>"
  elif (len(results["results"]["bindings"]) == 0):
      print "<p>No results found.</p>"

  else:
    for result in results["results"]["bindings"]:
      print "<p>" + result["actorName"]["value"] + "</p>"

  print "</body></html>"

main()

Я получил вышеуказанный код от http://www.ibm.com/developerworks/xml/library/x-wikiquery/#download

Теперь я хочу сделать то же самое в Java с сервлетами вместо сценария CGI.

так,как передать запрос из сервлета в http://data.linkedmdb.org/sparql конечную точку с использованием jena?

и как мне получить результат обратно и отобразить его в виде html?

PLease, HELP

1 Ответ

1 голос
/ 04 апреля 2011

Вот пример кода. Обратите внимание, что на самом деле я бы не стал так делать по-настоящему: код представления и обработка внутренних запросов смешаны в одном классе. Реальные приложения этого не делают! Этот пример верен вашему образцу, за исключением того, что вместо запроса строки я использую средство Jena для предварительной привязки некоторых переменных запроса (поэтому DIR1-NAME становится ?dir-1-name). Я думаю, что это намного чище и дает вам больше гибкости в отношении того, какие параметры запроса передаются от клиента.

package example;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.*;

import com.hp.hpl.jena.query.*;
import com.hp.hpl.jena.rdf.model.*;

public class ServletExample
    extends HttpServlet
{
    /***********************************/
    /* Constants                       */
    /***********************************/

    private static final long serialVersionUID = 1L;

    public static final String SPARQL_ENDPOINT = "http://data.linkedmdb.org/sparql";

    public static final String QUERY = "PREFIX m: <http://data.linkedmdb.org/resource/movie/>\n" +
            "SELECT DISTINCT ?actorName WHERE {\n" +
            "  ?dir1     m:director_name %dir_name_1%.\n" +
            "  ?dir2     m:director_name %dir_name_2%.\n" +
            "  ?dir1film m:director ?dir1;\n" +
            "            m:actor ?actor.\n" +
            "  ?dir2film m:director ?dir2;\n" +
            "            m:actor ?actor.\n" +
            "  ?actor    m:actor_name ?actorName.\n" +
            "}\n" +
            "";

    private static final String HEADER = "<html>\n" +
            "      <head>\n" +
            "        <title>results</title>\n" +
            "          <link href=\"simple.css\" type=\"text/css\" rel=\"stylesheet\" />\n" +
            "      </head>\n" +
            "      <body>\n" +
            "";

    private static final String FOOTER = "</body></html>";

    /**
     * Respond to HTTP GET request. Will need to be mounted against some URL
     * pattern in web.xml
     */
    @Override
    protected void doGet( HttpServletRequest req, HttpServletResponse resp )
        throws ServletException, IOException
    {
        String dir1 = req.getParameter( "dir1" );
        String dir2 = req.getParameter( "dir2" );

        if (dir1 == null || dir2 == null || dir1.isEmpty() || dir2.isEmpty()) {
            noInput( resp );
        }
        else {
            runQuery( resp, dir1, dir2 );
        }
    }

    protected void noInput( HttpServletResponse resp )
        throws IOException
    {
        header( resp );
        resp.getWriter().println( "<p>Please select director names as query params <code>dir1</code> and <code>dir2</code></p>" );
        footer( resp );
    }

    protected void footer( HttpServletResponse resp ) throws IOException {
        resp.getWriter().println( FOOTER );
    }

    protected void header( HttpServletResponse resp ) throws IOException {
        resp.getWriter().println( HEADER );
    }

    protected void runQuery( HttpServletResponse resp, String dir1, String dir2 )
        throws IOException
    {
        PrintWriter out = resp.getWriter();

        // Set up the query
        String q = QUERY.replace( "%dir_name_1%", "\"" + dir1 + "\"" )
                        .replace( "%dir_name_2%", "\"" + dir2 + "\"" );

        Query query = QueryFactory.create( q ) ;
        QueryExecution qexec = QueryExecutionFactory.sparqlService( SPARQL_ENDPOINT, query );

        // perform the query
        ResultSet results = qexec.execSelect();

        // generate the output
        header( resp );
        if (!results.hasNext()) {
            out.println( "<p>No results, sorry.</p>" );
        }
        else {
            out.println( "<h1>Results</h1>" );
            while (results.hasNext()) {
                QuerySolution qs = results.next();
                String actorName = qs.getLiteral( "actorName" ).getLexicalForm();
                out.println( String.format( "<div>Actor named: %s</div>", actorName ) );
            }
        }
        footer( resp );
    }
}

Насколько я могу судить, этот код работает, но я не знаю, какие запросы, которые вы используете, должны возвращать некоторые результаты.

...