Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.openjena.riot.web; import static java.lang.String.format; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.EntityTemplate; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.openjena.atlas.web.HttpException; import org.openjena.atlas.web.MediaType; import org.openjena.riot.WebContent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.hp.hpl.jena.sparql.ARQInternalErrorException; /** Simplified HTTP operations; simplification means only supporting certain needed uses of HTTP. * The expectation is that the simplified operations in this class can be used by other code to * generate more application specific HTTP interactions (e.g. SPARQL queries). * <p> * For HTTP GET, the application supplies a URL, the accept header string, and a * list of handlers to deal with different content type responses. * <p> * For HTTP POST, the application supplies a URL, content, * the accept header string, and a list of handlers to deal with different content type responses, * or no response is expected. * @see HttpNames HttpNames, for HTTP related constants * @see WebContent WebContent, for content type name constants */ public class HttpOp { // See also: // Fluent API in HttpClient from v4.2 static private Logger log = LoggerFactory.getLogger(HttpOp.class); static private AtomicLong counter = new AtomicLong(0); // /** GET with unencoded query string. // * See {@link #execHttpGet(String, String, Map)} for additional details. // * <p>The query string will be encoded as needed and appended to the URL, inserting a "?". // */ // public static void execHttpGet(String url, String queryString, String acceptHeader, Map<String, HttpResponseHandler> handlers) // { // try { // System.err.println("BROKEN - encodes the queyr string structure") ; // String requestURL = url+"?"+URLEncoder.encode(queryString, "UTF-8") ; // execHttpGet(requestURL, acceptHeader, handlers) ; // } catch (UnsupportedEncodingException ex) // { // // UTF-8 required of all Java platforms. // throw new ARQInternalErrorException("No UTF-8 charset") ; // } // } /** GET * <p>The acceptHeader string is any legal value for HTTP Accept: field. * <p>The handlers are the set of content types (without charset), * used to dispatch the response body for handling. * <p>A Map entry of ("*",....) is used "no handler found". * <p>HTTP responses 400 and 500 become exceptions. */ public static void execHttpGet(String url, String acceptHeader, Map<String, HttpResponseHandler> handlers) { try { long id = counter.incrementAndGet(); String requestURI = determineRequestURI(url); String baseIRI = determineBaseIRI(requestURI); HttpGet httpget = new HttpGet(requestURI); if (log.isDebugEnabled()) log.debug(format("[%d] %s %s", id, httpget.getMethod(), httpget.getURI().toString())); // Accept if (acceptHeader != null) httpget.addHeader(HttpNames.hAccept, acceptHeader); // Execute HttpClient httpclient = new DefaultHttpClient(); HttpResponse response = httpclient.execute(httpget); // Handle response httpResponse(id, response, baseIRI, handlers); httpclient.getConnectionManager().shutdown(); } catch (IOException ex) { ex.printStackTrace(System.err); } } /** POST a string without response body. * <p>Execute an HTTP POST, with the string as content. * <p>No response content expected or processed. */ //TODO Use MediaType public static void execHttpPost(String url, String contentType, String content) { execHttpPost(url, contentType, content, null, null); } /** POST without response body. * Content read from the the input stream. * <p>Execute an HTTP POST, with the string as content. * <p>No response content expected or processed. */ //TODO Use MediaType public static void execHttpPost(String url, String contentType, InputStream input, int length) { execHttpPost(url, contentType, input, length, null, null); } /** POST a string, expect a response body.*/ public static void execHttpPost(String url, String contentType, String content, String acceptType, Map<String, HttpResponseHandler> handlers) { StringEntity e = null; try { e = new StringEntity(content, "UTF-8"); e.setContentType(contentType); execHttpPost(url, e, acceptType, handlers); } catch (UnsupportedEncodingException e1) { throw new ARQInternalErrorException("Platform does not support required UTF-8"); } finally { closeEntity(e); } } /** POST with response body. * The input stream is assumed to be UTF-8. */ public static void execHttpPost(String url, String contentType, InputStream input, int length, String acceptType, Map<String, HttpResponseHandler> handlers) { InputStreamEntity e = new InputStreamEntity(input, length); e.setContentType(contentType); e.setContentEncoding("UTF-8"); execHttpPost(url, e, acceptType, handlers); } /** POST with response body */ public static void execHttpPost(String url, String contentType, ContentProducer provider, String acceptType, Map<String, HttpResponseHandler> handlers) { EntityTemplate entity = new EntityTemplate(provider); entity.setContentType(contentType); execHttpPost(url, entity, acceptType, handlers); } /** POST with response body. * <p>The content for the POST body comes from the HttpEntity. * <p>The response is handled bythe handler map, as per {@link #execHttpGet(String, String, Map)} */ public static void execHttpPost(String url, HttpEntity provider, String acceptType, Map<String, HttpResponseHandler> handlers) { try { long id = counter.incrementAndGet(); String requestURI = determineBaseIRI(url); String baseIRI = determineBaseIRI(requestURI); HttpPost httppost = new HttpPost(requestURI); if (log.isDebugEnabled()) log.debug(format("[%d] %s %s", id, httppost.getMethod(), httppost.getURI().toString())); if (provider.getContentType() == null) log.debug(format("[%d] No content type")); // Execute HttpClient httpclient = new DefaultHttpClient(); httppost.setEntity(provider); HttpResponse response = httpclient.execute(httppost); httpResponse(id, response, baseIRI, handlers); httpclient.getConnectionManager().shutdown(); } catch (IOException ex) { ex.printStackTrace(System.err); } finally { closeEntity(provider); } } private static void closeEntity(HttpEntity entity) { if (entity == null) return; try { entity.getContent().close(); } catch (Exception e) { } } private static String determineRequestURI(String url) { String requestURI = url; if (requestURI.contains("#")) { // No frag ids. int i = requestURI.indexOf('#'); requestURI = requestURI.substring(0, i); } return requestURI; } private static String determineBaseIRI(String requestURI) { // Technically wrong, but including the query string is "unhelpful" String baseIRI = requestURI; if (requestURI.contains("?")) { // No frag ids. int i = requestURI.indexOf('?'); baseIRI = requestURI.substring(0, i); } return baseIRI; } private static void httpResponse(long id, HttpResponse response, String baseIRI, Map<String, HttpResponseHandler> handlers) throws IllegalStateException, IOException { if (response == null) return; try { StatusLine statusLine = response.getStatusLine(); if (statusLine.getStatusCode() >= 400) { log.debug(format("[%d] %s %s", id, statusLine.getStatusCode(), statusLine.getReasonPhrase())); throw new HttpException(statusLine.getStatusCode() + " " + statusLine.getReasonPhrase()); } String ct = "*"; MediaType mt = null; if (statusLine.getStatusCode() == 200) { String contentType = response.getFirstHeader(HttpNames.hContentType).getValue(); if (contentType != null) { mt = new MediaType(contentType); if (log.isDebugEnabled()) log.debug(format("[%d] %d %s :: %s", id, statusLine.getStatusCode(), statusLine.getReasonPhrase(), mt)); } else { if (log.isDebugEnabled()) log.debug(format("[%d] %d %s :: (no content type)", id, statusLine.getStatusCode(), statusLine.getReasonPhrase())); } HttpResponseHandler handler = handlers.get(ct); if (handler == null) // backstop handler = handlers.get("*"); if (handler != null) handler.handle(ct, baseIRI, response); else log.warn(format("[%d] No handler found for %s", id, ct)); } else { if (handlers != null) log.warn(format("[%d] No content returned but handlers provided")); } } finally { closeEntity(response.getEntity()); } } // public static void main2(String...argv) throws Exception // { // String queryString = "SELECT * { ?s ?p ?o } LIMIT 1" ; // // HttpClient 4.1.2 // URI uri = URIUtils.createURI("http", // "sparql.org", // -1, // "books", // "query="+URLEncoder.encode(queryString,"UTF-8"), // null // ) ; // HttpGet httpget = new HttpGet(uri); // httpget.addHeader("Accept", "application/sparql-results+json") ; // // System.out.println(httpget.getURI()); // // DefaultHttpClient httpclient = new DefaultHttpClient(); // // HttpContext localContext = new BasicHttpContext(); // // HttpResponse response = httpclient.execute(httpget, localContext) ; // System.out.println(response.getFirstHeader("Content-type")) ; // // System.out.println(response.getStatusLine()) ; // HttpEntity entity = response.getEntity(); // InputStream instream = entity.getContent() ; // try { // //entity = new BufferedHttpEntity(entity) ; // String x = FileUtils.readWholeFileAsUTF8(instream) ; // System.out.print(x) ; // } finally { // instream.close(); // } // } }