Java tutorial
/* * Copyright 2013 Simon Thiel * * This file is part of SitJar. * * SitJar is free software: you can redistribute it and/or modify * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SitJar 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with SitJar. If not, see <http://www.gnu.org/licenses/lgpl.txt>. */ package sit.web.client; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.Charset; import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.HttpsURLConnection; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import sit.sstl.ByteBuilder; import sit.tools.Base64; import sit.web.HttpConstants; import sit.web.MimeTypes; import sit.web.multipart.MultipartContainer; public class HttpHelper { private final static boolean USE_APACHE = true; private static final int BUFFER_SIZE = 1024 * 512; public static String getBase64UserNamePwdToken(String username, String password) { return Base64.encodeBytes((username + ":" + password).getBytes()); } public static String encodeString(String myString) { if (myString == null) { throw new NullPointerException("encodeString: myString == null!"); } try { return java.net.URLEncoder.encode(myString, "UTF-8"); } catch (UnsupportedEncodingException ex) { throw new AssertionError("UTF-8 not supported"); } } public static String decodeString(String myString) { if (myString == null) { throw new NullPointerException("decodeString: myString == null!"); } try { return java.net.URLDecoder.decode(myString, "UTF-8"); } catch (UnsupportedEncodingException ex) { throw new AssertionError("UTF-8 not supported"); } } public static URI getURI(String host, int port, String path, boolean isHTTPS) throws MalformedURLException, URISyntaxException { String myUrl = isHTTPS ? "https" : "http"; myUrl += "://" + host + ":" + port + path; return new URI(myUrl); } public static URL getURL(String host, int port, String path, boolean isHTTPS) throws MalformedURLException { String myUrl = isHTTPS ? "https" : "http"; myUrl += "://" + host + ":" + port + path; return new URL(myUrl); } public HttpHelper() { HTTPTrustHelper.initAllTrustingManager("TLS"); //or "SSL" } public HttpHelper(String sslContext) { HTTPTrustHelper.initAllTrustingManager(sslContext); } public HTTPResponse postMultiPartContainer(String host, int port, String path, MultipartContainer mpc, boolean isHTTPS, String unamePword64) throws MalformedURLException, IOException, ProtocolException { if (mpc == null) { //make sure multipartContainer is initialized return null; } String contentType = mpc.getContentType(); ByteBuilder bb = new ByteBuilder(); OutputStream os = bb.getOutputStream(); mpc.write(os); os.close(); Logger.getLogger(HttpHelper.class.getName()).log(Level.INFO, "mpc length " + mpc.getContentLength() + " bb.size():" + bb.size()); byte[] payload = bb.toByteArray(); try { return doHTTPRequest(HttpConstants.HTTP_COMMAND_POST, host, port, path, payload, contentType, isHTTPS, unamePword64); } catch (URISyntaxException ex) { Logger.getLogger(HttpHelper.class.getName()).log(Level.SEVERE, null, ex); return null; } } /** * * convenient call, sets charSet automatically to * <code>Charset.defaultCharset()</code> * * @param method * @param host * @param port * @param path * @param payload * @param mimeType mimetype as string e.g. "application/json" will be added * to the content type of the http call * @param isHTTPS * @param unamePword64 * @return * @throws MalformedURLException * @throws ProtocolException * @throws IOException */ public HTTPResponse doHTTPRequest(String method, String host, int port, String path, String payload, String mimeType, boolean isHTTPS, String unamePword64) throws MalformedURLException, ProtocolException, IOException { return doHTTPRequest(method, host, port, path, payload, mimeType, Charset.defaultCharset(), isHTTPS, unamePword64); } /** * * * @param method * @param host * @param port * @param path * @param payload * @param mimeType mimetype as string e.g. "application/json" will be added * to the content type of the http call * @param charSet set charSet to null to omit sending a char flag (e.g. for * binary files) * @param isHTTPS * @param unamePword64 * @return * @throws MalformedURLException * @throws ProtocolException * @throws IOException */ public HTTPResponse doHTTPRequest(String method, String host, int port, String path, String payload, String mimeType, Charset charSet, boolean isHTTPS, String unamePword64) throws MalformedURLException, ProtocolException, IOException { if (mimeType == null || mimeType.length() == 0) { mimeType = MimeTypes.getMimeType(""); //get unknown mime type if mimetype not set } String contentType = mimeType; if (charSet != null) { contentType += HttpConstants.SUB_FIELD_SEPARATOR + HttpConstants.CHARSET_CONTENT_TYPE_TAG + charSet.name(); //text/html; charset=utf-8 //##CHARSET_MARKER## } else { charSet = Charset.defaultCharset(); } try { return doHTTPRequest(method, host, port, path, payload.getBytes(charSet), contentType, isHTTPS, unamePword64); } catch (URISyntaxException ex) { throw new MalformedURLException(ex.getMessage()); } } /** * * * @param method * @param host * @param port * @param path * @param payload * @param contentType content type e.g. "application/json" * @param isHTTPS * @param unamePword64 * @return * @throws MalformedURLException * @throws ProtocolException * @throws IOException */ public HTTPResponse doHTTPRequest(String method, String host, int port, String path, byte[] payload, String contentType, boolean isHTTPS, String unamePword64) throws MalformedURLException, ProtocolException, IOException, URISyntaxException { if (USE_APACHE) { return doApacheHTTPRequest(method, host, port, path, payload, contentType, isHTTPS, unamePword64); } //else return doHttpURLConnectionRequest(method, host, port, path, payload, contentType, isHTTPS, unamePword64); } /** * * * @param method * @param host * @param port * @param path * @param payload * @param contentType content type e.g. "application/json" * @param isHTTPS * @param unamePword64 * @return * @throws MalformedURLException * @throws ProtocolException * @throws IOException * @throws URISyntaxException */ public HTTPResponse doApacheHTTPRequest(String method, String host, int port, String path, byte[] payload, String contentType, boolean isHTTPS, String unamePword64) throws MalformedURLException, ProtocolException, IOException, URISyntaxException { if (payload == null) { //make sure payload is initialized payload = new byte[0]; } URI url = getURI(host, port, path, isHTTPS); HttpClient httpclient; if (isHTTPS) { httpclient = HTTPTrustHelper.getNewHttpClient(Charset.defaultCharset(), port); } else { httpclient = new DefaultHttpClient(); } HTTPResponse result = null; HttpResponse response = null; if (method.equalsIgnoreCase(HttpConstants.HTTP_COMMAND_GET)) { HttpGet request = new HttpGet(url); request.setHeader("Authorization", "Basic " + unamePword64); response = httpclient.execute(request); } else if (method.equalsIgnoreCase(HttpConstants.HTTP_COMMAND_POST)) { HttpPost request = new HttpPost(url); request.setHeader("Authorization", "Basic " + unamePword64); InputStreamEntity reqEntity = new InputStreamEntity(new ByteArrayInputStream(payload), payload.length); request.setEntity(reqEntity); reqEntity.setContentType(contentType); response = httpclient.execute(request); } else if (method.equalsIgnoreCase(HttpConstants.HTTP_COMMAND_PUT)) { HttpPut request = new HttpPut(url); request.setHeader("Authorization", "Basic " + unamePword64); InputStreamEntity reqEntity = new InputStreamEntity(new ByteArrayInputStream(payload), payload.length); request.setEntity(reqEntity); reqEntity.setContentType(contentType); response = httpclient.execute(request); } else if (method.equalsIgnoreCase(HttpConstants.HTTP_COMMAND_DELETE)) { HttpDelete request = new HttpDelete(url); request.setHeader("Authorization", "Basic " + unamePword64); response = httpclient.execute(request); } else { throw new RuntimeException("HTTP method not supported! Method:" + method); } result = new HTTPResponse(path, payload, Charset.defaultCharset()); HttpEntity responseEntity = response.getEntity(); if (responseEntity != null) { result.reply = EntityUtils.toString(responseEntity); } result.code = response.getStatusLine().getStatusCode(); result.message = response.getStatusLine().getReasonPhrase(); httpclient.getConnectionManager().shutdown(); return result; } private static boolean isHTTPS(String downloadUrl) { return downloadUrl.startsWith("https"); } public static void apacheDownload(String downloadUrl, File targetFile) throws IOException { URL url = new URL(downloadUrl); HttpClient httpclient; if (isHTTPS(downloadUrl)) { httpclient = HTTPTrustHelper.getNewHttpClient(Charset.defaultCharset(), (url.getPort() != -1) ? url.getPort() : url.getDefaultPort()); } else { httpclient = new DefaultHttpClient(); } HttpGet request = new HttpGet(downloadUrl); HttpResponse response = httpclient.execute(request); InputStream is = response.getEntity().getContent(); FileOutputStream writer = new FileOutputStream(targetFile); try { byte[] buffer = new byte[BUFFER_SIZE]; int bytesRead = 0; while ((bytesRead = is.read(buffer, 0, buffer.length)) >= 0) { writer.write(buffer, 0, bytesRead); } } finally { writer.close(); is.close(); httpclient.getConnectionManager().shutdown(); } } /** * * * @param method * @param host * @param port * @param path * @param payload * @param contentType content type e.g. "application/json" * @param isHTTPS * @param unamePword64 * @return * @throws MalformedURLException * @throws ProtocolException * @throws IOException * @throws URISyntaxException */ public HTTPResponse doHttpURLConnectionRequest(String method, String host, int port, String path, byte[] payload, String contentType, boolean isHTTPS, String unamePword64) throws MalformedURLException, ProtocolException, IOException, URISyntaxException { URL url = getURL(host, port, path, isHTTPS); return doHttpUrlConnectionRequest(url, method, contentType, payload, unamePword64); } public HTTPResponse doHttpUrlConnectionRequest(URL url, String method, String contentType, byte[] payload, String unamePword64) throws MalformedURLException, ProtocolException, IOException, URISyntaxException { if (payload == null) { //make sure payload is initialized payload = new byte[0]; } boolean isHTTPS = url.getProtocol().equalsIgnoreCase("https"); HttpURLConnection connection; if (isHTTPS) { connection = (HttpsURLConnection) url.openConnection(); } else { connection = (HttpURLConnection) url.openConnection(); } connection.setRequestMethod(method); connection.setRequestProperty("Host", url.getHost()); connection.setRequestProperty("Content-Type", contentType); connection.setRequestProperty("Content-Length", String.valueOf(payload.length)); if (isHTTPS) { connection.setRequestProperty("Authorization", "Basic " + unamePword64); } Logger.getLogger(HttpHelper.class.getName()).log(Level.FINER, "trying to connect:\n" + method + " " + url + "\nhttps:" + isHTTPS + "\nContentType:" + contentType + "\nContent-Length:" + String.valueOf(payload.length)); connection.setDoInput(true); if (payload.length > 0) { // open up the output stream of the connection connection.setDoOutput(true); FilterOutputStream output = new FilterOutputStream(connection.getOutputStream()); // write out the data output.write(payload); output.close(); } HTTPResponse response = new HTTPResponse(method + " " + url.toString(), payload, Charset.defaultCharset()); //TODO forward charset ot this method response.code = connection.getResponseCode(); response.message = connection.getResponseMessage(); Logger.getLogger(HttpHelper.class.getName()).log(Level.FINE, "received response: " + response.message + " with code: " + response.code); if (response.code != 500) { byte[] buffer = new byte[20480]; ByteBuilder bytes = new ByteBuilder(); // get ready to read the response from the cgi script DataInputStream input = new DataInputStream(connection.getInputStream()); boolean done = false; while (!done) { int readBytes = input.read(buffer); done = (readBytes == -1); if (!done) { bytes.append(buffer, readBytes); } } input.close(); response.reply = bytes.toString(Charset.defaultCharset()); } return response; } }