Java - Illegal character(s) in message header value: Basic

16,691

It appears the illegal character is a newline. Use a base 64 encoder that doesn't put newlines in the result, or remove the newline yourself.

As of Java 8, you should use:

String encoding3 = Base64.getEncoder().encodeToString(
    credentials.getBytes(StandardCharsets.UTF_8));

In older versions of Java, you can use DatatypeConverter:

String encoding3 = DatatypeConverter.printBase64Binary(
    credentials.getBytes(StandardCharsets.UTF_8));

You could also remove the newline character directly, but you should use one of the above approaches instead. The sun.* classes are not for development use, and they can change or disappear from one Java release to the next. Furthermore, as I understand it, they may not even be usable at all as of Java 9, regardless of whether they exist, due to module restrictions.

Share:
16,691
teej2542
Author by

teej2542

Updated on June 14, 2022

Comments

  • teej2542
    teej2542 almost 2 years

    I get the following error when trying to query an api in Java using HttpUrlConnection:

        "Exception in thread "main" java.lang.IllegalArgumentException: Illegal   character(s) in message header value: Basic MTk2YTVjODdhNWI2YjFmNWE3ZmQ5ODEtYjFjYTEzZmUtM2FkNC0xMWU1LWEyZjAtMDBkMGZlYTgy
    NjI0OmY3NDQ2ZWQ0YjhjNzI2MzkyMzY1YzczLWIxY2ExNjQ4LTNhZDQtMTFlNS1hMmYwLTAwZDBm
    ZWE4MjYyNA=="
    

    Here is my code:

    public class LocalyticsTest {
    
            public static void main(String[] args) throws UnsupportedEncodingException {
    
                String apiKey = "MyKey";
                String apiSecret = "MySecretKey";
                String apiUrl = "https://api.localytics.com/v1/query";
                String credentials = apiKey + ":" + apiSecret;
                //String encoding = Base64.encode(apiKey.getBytes("UTF-8"));
                //String encoding2 = Base64.encode(apiSecret.getBytes("UTF-8"));
                String encoding3 = new sun.misc.BASE64Encoder().encode (credentials.getBytes("UTF-8"));
    
                String appId = "myAppId";
                String metric = "sessions";
                String dimensions = "day";
                String condition = "'{\"day\":[\"between\",\"'.$newDate.'\",\"'.$newDate.'\"]}'";
                Map data = new HashMap();
                data.put("app_id", appId);
                data.put("metric", metric);
                data.put("dimensions", dimensions);
                data.put("condition", condition);
    
                QueryEncoder q = new QueryEncoder();
                String newData = q.toQueryString(data);
    
                String newUrl = String.format("%s?%s", apiUrl, newData);
    
    
                try{
                    URL url = new URL(newUrl);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    //conn.setRequestMethod("GET");
                    //conn.setRequestProperty("Authorization", "Basic");
                    //conn.setRequestProperty(apiKey,apiSecret);
                    conn.setRequestProperty("Authorization", "Basic " + encoding3);
                    conn.setRequestProperty("Accept", "application/vnd.localytics.v1+hal+json");
    
    
                    if (conn.getResponseCode() != 200) {
                        throw new RuntimeException("Failed : HTTP error code : "
                                + conn.getResponseCode());
                    }
    
                    BufferedReader br = new BufferedReader(new InputStreamReader(
                            (conn.getInputStream())));
    
                    String output;
                    System.out.println("Output from Server .... \n");
                    while ((output = br.readLine()) != null) {
                        System.out.println(output);
                    }
    
                    conn.disconnect();
    
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (ProtocolException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
           }
        }
    

    I am able to get it to work fine in php with Curl with the following:

    function call_localytics_api($method, $url, $data)
    {
        $curl = curl_init();
        $url = sprintf("%s?%s", $url, http_build_query($data));
        $api_key = "myKey";
        $api_secret = "mySecret";
        // Optional Authentication:
        curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_setopt($curl, CURLOPT_USERPWD, $api_key . ":" . $api_secret);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        // Disable the SSL verificaiton process
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_HTTPHEADER, array("Accept: application/vnd.localytics.v1+hal+json"));
    
        // Confirm cURL gave a result, if not, write the error
    
        $response = curl_exec($curl);
    
        if ($response === FALSE) {
            die("Curl Failed: " . curl_error($curl));
        } else {
            return $response;
        }
    }
    
    $api_querystring = "https://api.localytics.com/v1/query";
    $app_id = "myAppId";
    
    $metric = "sessions";
    $dimensions = "day";
    //$data = array(app_id => $app_id, metrics => $metric, dimensions => $dimensions, conditions => '{"day":["in","'.$requestDate.'"]}');
    $data = array(app_id => $app_id, metrics => $metric, dimensions => $dimensions, conditions => '{"day":["between","'.$newDate.'","'.$newDate.'"]}');
    $response = call_localytics_api('GET', $api_querystring, $data);
    $json = json_decode($response);
    print_r($json);
    

    Just need help getting it to work in Java.

  • Anand Varkey Philips
    Anand Varkey Philips over 6 years
    Thank you so much!