Java tutorial
/* OpenSyncro - A web-based enterprise application integration tool * Copyright (C) 2008 Smilehouse Oy, support@opensyncro.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Created on 04.01.2005 * * */ package smilehouse.opensyncro.defaultcomponents.http; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.methods.StringRequestEntity; import smilehouse.util.Utils; public class HTTPUtils { private static final String SOAPMESSAGE = "SOAPMessage"; private static final String SOAP_ACTION_HEADER = "SOAPAction"; private static final String CONTENT_TYPE_HEADER = "Content-Type"; private static final String DEFAULT_CONTENT_TYPE = "text/xml"; /** * Makes a HTTP request to the specified url with a set of parameters, * request method, user name and password * * @param url the <code>URL</code> to make a request to * @param method either "GET", "POST", "PUT" or "SOAP" * @param parameters two dimensional string array containing parameters to send in the request * @param user user name to submit in the request * @param password password to submit in the request * @param charsetName charset name used for message content encoding * @param responseCharsetName charset name used to decode HTTP responses, * or null to use default ("ISO-8859-1") * @param contentType Content-Type header value (without charset information) * for POST (and SOAP) type requests. If null, defaults to * "text/xml". * @return a string array containing the body of the response, the headers of * the response and possible error message * @throws Exception */ public static HTTPResponse makeRequest(URL url, String method, String[][] parameters, String user, String password, String charsetName, String responseCharsetName, String contentType) throws Exception { HttpClient httpclient = new HttpClient(); HttpMethod request_method = null; HTTPResponse responseData = new HTTPResponse(); NameValuePair[] names_values = null; String requestContentType; if (contentType != null && contentType.length() > 0) { requestContentType = contentType; } else { requestContentType = DEFAULT_CONTENT_TYPE; } if (parameters != null && method.equals("PUT") == false) { names_values = new NameValuePair[parameters.length]; for (int i = 0; i < parameters.length; i++) { names_values[i] = new NameValuePair(parameters[i][0], parameters[i][1]); } } if (method.equalsIgnoreCase("POST")) { request_method = new PostMethod(url.toString()); if (names_values != null) ((PostMethod) request_method).setRequestBody(names_values); } else if (method.equalsIgnoreCase("PUT")) { if (parameters == null) throw new Exception("No data to use in PUT request"); request_method = new PutMethod(url.toString()); StringRequestEntity sre = new StringRequestEntity(parameters[0][0]); ((PutMethod) request_method).setRequestEntity(sre); } else if (method.equalsIgnoreCase("SOAP")) { String urlString = url.toString() + "?"; String message = null; String action = null; for (int i = 0; i < parameters.length; i++) { if (parameters[i][0].equals(SOAPMESSAGE)) message = parameters[i][1]; else if (parameters[i][0].equals(SOAP_ACTION_HEADER)) action = parameters[i][1]; else urlString += parameters[i][0] + "=" + parameters[i][1] + "&"; } urlString = urlString.substring(0, urlString.length() - 1); request_method = new PostMethod(urlString); // Encoding content with requested charset StringRequestEntity sre = new StringRequestEntity(message, requestContentType, charsetName); ((PostMethod) request_method).setRequestEntity(sre); if (action != null) { request_method.setRequestHeader(SOAP_ACTION_HEADER, action); } // Adding charset also into header's Content-Type request_method.addRequestHeader(CONTENT_TYPE_HEADER, requestContentType + "; charset=" + charsetName); } else { request_method = new GetMethod(url.toString()); if (names_values != null) ((GetMethod) request_method).setQueryString(names_values); } user = (user == null || user.length() < 1) ? null : user; password = (password == null || password.length() < 1) ? null : password; if ((user != null & password == null) || (user == null & password != null)) { throw new Exception("Invalid username or password"); } if (user != null && password != null) { httpclient.getParams().setAuthenticationPreemptive(true); Credentials defaultcreds = new UsernamePasswordCredentials(user, password); httpclient.getState().setCredentials(new AuthScope(url.getHost(), url.getPort(), AuthScope.ANY_REALM), defaultcreds); request_method.setDoAuthentication(true); } try { httpclient.executeMethod(request_method); if (request_method.getStatusCode() != HttpStatus.SC_OK) { responseData .setResponseError(request_method.getStatusCode() + " " + request_method.getStatusText()); } //Write response header to the out string array Header[] headers = request_method.getResponseHeaders(); responseData.appendToHeaders("\nHTTP status " + request_method.getStatusCode() + "\n"); for (int i = 0; i < headers.length; i++) { responseData.appendToHeaders(headers[i].getName() + ": " + headers[i].getValue() + "\n"); } /* * TODO: By default, the response charset should be read from the Content-Type header of * the response and that should be used in the InputStreamReader constructor: * * <code>new InputStreamReader(request_method.getResponseBodyAsStream(), * ((HttpMethodBase)request_method).getResponseCharSet());</code> * * But for backwards compatibility, the charset used by default is now the one that the * HttpClient library chooses (ISO-8859-1). An alternative charset can be chosen, but in * no situation is the charset read from the response's Content-Type header. */ BufferedReader br = null; if (responseCharsetName != null) { br = new BufferedReader( new InputStreamReader(request_method.getResponseBodyAsStream(), responseCharsetName)); } else { br = new BufferedReader(new InputStreamReader(request_method.getResponseBodyAsStream())); } String responseline; //Write response body to the out string array while ((responseline = br.readLine()) != null) { responseData.appendToBody(responseline + "\n"); } } finally { request_method.releaseConnection(); } return responseData; } /** * Makes a HTTP request to the specified url using the specified method, user name and password * * @param url the <code>URL</code> to make a request to * @param method either "GET", "POST, "PUT" or "SOAP" * @param user user name to submit in the request * @param pass password to submit in the request * @param charsetName charset name used for message content encoding * @return a string array containing the body of the response, the headers of the response and possible error message */ public static HTTPResponse makeRequest(URL url, String method, String user, String pass, String charsetName) throws Exception { return makeRequest(url, method, null, user, pass, charsetName, null, null); } /** * Makes a HTTP request to the specified url using the specified method. * * @param url the <code>URL</code> to make a request to * @param method either "GET", "POST", "PUT" or "SOAP" * @return a string array containing the body of the response, the headers of the response and possible error message */ public static HTTPResponse makeRequest(URL url, String method) throws Exception { return makeRequest(url, method, null, null, null, null, null, null); } /** * Splits the input string, first at each occurence of <b>delimiter</b> then at the first * occurence of <b>inline_delimiter</b>. * @param namevaluepairs the <code>URL</code> to make a request to * @param delimiter * @param inline_delimiter * @return a two dimesional string containing names and values */ public static String[][] splitParameters(String namevaluepairs, String delimiter, String inline_delimiter) { //return null if no input data or if inline_delimiter is not present in the input string if (namevaluepairs == null || namevaluepairs.length() < 1 || namevaluepairs.indexOf(inline_delimiter) == -1) return null; String[] splitparameters; splitparameters = Utils.split(namevaluepairs, delimiter); String[] single; String[][] parameters = new String[splitparameters.length][2]; try { for (int i = 0; i < splitparameters.length; i++) { single = splitparameters[i].split(inline_delimiter, 2); parameters[i][0] = single[0]; parameters[i][1] = single[1]; } } catch (ArrayIndexOutOfBoundsException ex) { return null; } return parameters; } }