/* * Copyright (c) 1998-2017 by Richard A. Wilkes. All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public * License, version 2.0. If a copy of the MPL was not distributed with * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This Source Code Form is "Incompatible With Secondary Licenses", as * defined by the Mozilla Public License, version 2.0. */ package com.trollworks.gcs.services; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.Scanner; /** A class used for interacting with web services */ public class WebServiceClient { private static final String SLASH = "/"; //$NON-NLS-1$ private String mBaseUrl; private Map<String, String> mQueryParameters = new HashMap<>(); private String mBody; private byte[] mByteBody; private String mPath; private HttpMethodType mMethod = HttpMethodType.GET; /** Creates a WebServiceClient with a base url: ("http://example.com/") */ public WebServiceClient(String baseUrl) { mBaseUrl = baseUrl; } /** Adds a querystring parameter: (?key=value) */ public boolean addQueryParameter(String key, String value) { try { mQueryParameters.put(key, URLEncoder.encode(value, StandardCharsets.UTF_8.toString())); } catch (UnsupportedEncodingException exception) { return false; } return true; } /** Sets the body of the request */ public void setBody(String body) { mBody = body; } /** Sets the path of the request: (/api/testmethod) */ public void setPath(String path) { mPath = path; } /** Sets the http method type of the request (GET, POST, PUT, DELETE) */ public void setHttpMethodType(HttpMethodType method) { mMethod = method; } /** * Sends the http request and returns string. */ public String sendRequest(HttpMethodType method, String path, Map<String, String> queryParameters, String body) throws MalformedURLException, IOException, NotImplementedException { mBody = body; return sendRequest(method, path, queryParameters); } /** * Sends the http request and returns a string. */ public String sendRequest(HttpMethodType method, String path, Map<String, String> queryParameters) throws MalformedURLException, IOException, NotImplementedException { if (queryParameters != null) { mQueryParameters = queryParameters; } return sendRequest(method, path); } /** * Sends the http request and returns a string. */ public String sendRequest(HttpMethodType method, String path) throws MalformedURLException, IOException, NotImplementedException { mMethod = method; mPath = path; return sendRequest(); } public String sendRequest(HttpMethodType method, String path, byte[] bytes) throws MalformedURLException, IOException, NotImplementedException { mBody = null; mByteBody = bytes; return sendRequest(method, path); } /** * Sends the http request and returns a string. */ public String sendRequest() throws MalformedURLException, IOException, NotImplementedException { URLConnection connection = buildUrl().openConnection(); connection.setRequestProperty("Accept-Charset", StandardCharsets.UTF_8.toString()); //$NON-NLS-1$ if (mMethod == HttpMethodType.GET) { try (InputStream stream = connection.getInputStream()) { return convertStreamToString(stream); } } if (mMethod == HttpMethodType.POST) { connection.setDoOutput(true); // Triggers POST. connection.setRequestProperty("Content-Type", "application/json"); //$NON-NLS-1$ //$NON-NLS-2$ if (mBody != null && mBody.length() > 0) { try (OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream())) { writer.write(mBody); } try (InputStream stream = connection.getInputStream()) { return convertStreamToString(stream); } } if (mByteBody != null) { try (DataOutputStream writer = new DataOutputStream(connection.getOutputStream())) { writer.write(mByteBody); } try (InputStream stream = connection.getInputStream()) { return convertStreamToString(stream); } } } throw new NotImplementedException("Method type not currently supported"); //$NON-NLS-1$ } static String convertStreamToString(java.io.InputStream is) { try (Scanner s = new Scanner(is)) { s.useDelimiter("\\A"); //$NON-NLS-1$ String result = s.hasNext() ? s.next() : ""; //$NON-NLS-1$ return result; } } private URL buildUrl() throws MalformedURLException { // sanitize strings mBaseUrl = ditchLeadingTrailingSlashes(mBaseUrl); mPath = ditchLeadingTrailingSlashes(mPath); // build the url StringBuilder url = new StringBuilder(mBaseUrl); url.append(SLASH); url.append(mPath); url.append(SLASH); // add query string variables if (mQueryParameters.isEmpty()) { return new URL(url.toString()); } url.append("?"); //$NON-NLS-1$ for (String key : mQueryParameters.keySet()) { url.append(key); url.append("="); //$NON-NLS-1$ url.append(mQueryParameters.get(key)); } return new URL(url.toString()); } private static String ditchLeadingTrailingSlashes(String str) { if (str.length() < 2) { return str; } if (str.endsWith(SLASH)) { str = str.substring(0, str.length() - 1); } if (str.startsWith(SLASH)) { str = str.substring(1, str.length()); } return str; } }