4

I somehow always thought that this should be possible:

val client = HttpClients.createDefault()
val httpGet = new HttpGet("file:///Users/user01/testfile")
client.execute(httpGet)

which throws:

client: org.apache.http.impl.client.CloseableHttpClient = org.apache.http.impl.client.InternalHttpClient@4ba3987b
httpGet: org.apache.http.client.methods.HttpGet = GET file:///Users/user01/testfile HTTP/1.1
org.apache.http.client.ClientProtocolException: URI does not specify a valid host name: file:///Users/user01/testfile
    at org.apache.http.impl.client.CloseableHttpClient.determineTarget(test_ws.sc0.tmp:90)
    at org.apache.http.impl.client.CloseableHttpClient.execute(test_ws.sc0.tmp:78)
    at org.apache.http.impl.client.CloseableHttpClient.execute(test_ws.sc0.tmp:103)
    at #worksheet#.#worksheet#(test_ws.sc0.tmp:6)

which kind of makes sense as I am creating an HttpGet instance.

Does anybody know how this can be done?

Todor Kolev
  • 1,432
  • 1
  • 16
  • 33
  • 1
    I would say the **HTTP**client is designed to use the **HTTP** protocol, use other tools for other protocols (file, ftp, ...). – Jozef Chocholacek Oct 21 '15 at 09:57
  • I am on Mac but the file /Users/user01/testfile does exist. – Todor Kolev Oct 21 '15 at 09:58
  • Maybe you want to use an URL with file:// [like this](http://stackoverflow.com/a/1485737/4136325) – Thomas Weller Oct 21 '15 at 10:01
  • @JozefChocholacek Yeah I am just trying to get rid of some http calls to external systems and mock the responses by passing in files instead... i.e. I can only play with the URIs as the https calls are fired from an internal library and I only have access to the configs so can only pass in URIs – Todor Kolev Oct 21 '15 at 10:01

3 Answers3

4

HttpClient is, surprisingly enough, is a client side HTTP transport library. It does not support any other transport protocols. Not even local file system. What you probably want is Apache Commons VFS or something similar.

ok2c
  • 26,450
  • 5
  • 63
  • 71
1

HttpClient is really only for HTTP, but you can achieve the same with plain Java:

try (BufferedInputStream in = new BufferedInputStream(new URL("file:///tmp/test.in").openStream());
     FileOutputStream fileOutputStream = new FileOutputStream(new File("/tmp/test.out"))){
    byte dataBuffer[] = new byte[1024];
    int bytesRead;
    while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
        fileOutputStream.write(dataBuffer, 0, bytesRead);
    }
} catch(IOException e){
    e.printStackTrace();
}
ttulka
  • 10,309
  • 7
  • 41
  • 52
-1

what about using the built-in java.net.URL class? That handles both http and file protocols.

erosb
  • 2,943
  • 15
  • 22
  • that doesn't work either... I can see that internally the httpclient is trying to extract the host so maybe after all it's not possible - target = URIUtils.extractHost(requestURI); – Todor Kolev Oct 21 '15 at 11:12
  • But I am sure I've done this in the past but maybe with some kind of a Spring wrapper: – Todor Kolev Oct 21 '15 at 11:13
  • this just ran properly for me: public static void main(String[] a) throws Exception { URL url = new URL("file:///tmp/foo"); InputStreamReader reader = new InputStreamReader((InputStream) url.getContent(), Charset.defaultCharset()); BufferedReader buffReader = new BufferedReader(reader); String line; StringBuilder strBuilder = new StringBuilder(); while ((line = buffReader.readLine()) != null) { strBuilder.append(line); } System.out.println(strBuilder.toString()); } – erosb Oct 21 '15 at 11:26