2012-04-13 4 views
9

Как получить OutputStream с использованием org.apache.http.impl.client.DefaultHttpClient?Как написать OutputStream с помощью DefaultHttpClient?

Я ищу, чтобы написать длинную строку в выходной поток.

Использование HttpURLConnection вы можете реализовать его следующим образом:

HttpURLConnection connection = (HttpURLConnection)url.openConnection(); 
OutputStream out = connection.getOutputStream(); 
Writer wout = new OutputStreamWriter(out); 
writeXml(wout); 

Есть ли способ, использующий DefaultHttpClient, похожий на то, что я выше? Как мне написать OutputStream, используя DefaultHttpClient вместо HttpURLConnection?

например

DefaultHttpClient client = new DefaultHttpClient(); 

OutputStream outstream = (get OutputStream somehow) 
Writer wout = new OutputStreamWriter(out); 
+0

@KeithRandall, я отредактировал его. Надеюсь, теперь это ясно. – Fabii

+0

Пожалуйста, объясните, что вы хотите написать.В обоих примерах getOutputStream() возвращает поток, используемый для отправки данных запроса для HTTP-запросов POST. –

+0

@EugeneKuleshov, Как получить выходной поток с использованием org.apache.http.impl.client.DefaultHttpClient? – Fabii

ответ

13

Вы не можете напрямую получить OutputStream из BasicHttpClient. Вы должны создать объект HttpUriRequest и предоставить ему HttpEntity, который инкапсулирует содержимое, которое вы хотите отправить. Например, если ваш выход достаточно мал, чтобы поместиться в памяти, вы можете сделать следующее:

// Produce the output 
ByteArrayOutputStream out = new ByteArrayOutputStream(); 
Writer writer = new OutputStreamWriter(out, "UTF-8"); 
writeXml(writer); 

// Create the request 
HttpPost request = new HttpPost(uri); 
request.setEntity(new ByteArrayEntity(out.toByteArray())); 

// Send the request 
DefaultHttpClient client = new DefaultHttpClient(); 
HttpResponse response = client.execute(request); 

Если данные достаточно велики, что вам нужно, чтобы поток, он становится более трудным, потому что нет HttpEntity реализации, принимает OutputStream. Вы должны были бы написать временный файл и использовать FileEntity или, возможно, установить трубу и использовать ответ InputStreamEntity

EDIT знакомство ОЛЕГА для образца кода, который демонстрирует, как поток контента - вам не нужен темп файла или трубы.

+0

Спасибо, человек, очень ценится. – Fabii

+0

Вопрос: Что делает этот writeXml (writer)? Кроме того, как вы передаете массив байтов в request.setEntity()? –

+0

@MattGrogan реализует логику приложения, фактически создавая контент, который получает POSTed на удаленный сервер (скопированный из кода примера в вопросе). – Alex

-1

Не думаю, что вы можете получить там необработанный выходной поток запроса с HttpClient. Но вы можете использовать PostMethod.getParameters() для доступа к значениям параметров. Также см. post method example.

25

Я знаю, что другой ответ уже принят, только для записи это то, как можно записать контент с помощью HttpClient без промежуточной буферизации в памяти.

AbstractHttpEntity entity = new AbstractHttpEntity() { 

     public boolean isRepeatable() { 
      return false; 
     } 

     public long getContentLength() { 
      return -1; 
     } 

     public boolean isStreaming() { 
      return false; 
     } 

     public InputStream getContent() throws IOException { 
      // Should be implemented as well but is irrelevant for this case 
      throw new UnsupportedOperationException(); 
     } 

     public void writeTo(final OutputStream outstream) throws IOException { 
      Writer writer = new OutputStreamWriter(outstream, "UTF-8"); 
      writeXml(writer); 
      writer.flush(); 
     } 

    }; 
    HttpPost request = new HttpPost(uri); 
    request.setEntity(entity); 
+0

Ницца - я знал, что должен быть простой способ потокового воспроизведения контента, просто не мог думать об этом. – Alex

+1

Есть ли другой пример этого процесса? Откуда writeTo получить вызов? – HGPB

+1

@Haraldo, когда запрос выполняется, инфраструктура HttpClient вызывает 'request.getEntity(). WriteTo()'. Это означает, что вы не можете написать однопоточный клиент, который запускает POST, а затем возвращает свой OutputStream вызывающему абоненту для вызова нескольких записей. – slim

2

Это хорошо работает на android. Он также должен работать для больших файлов, так как не требуется буферизация.

PipedOutputStream out = new PipedOutputStream(); 
PipedInputStream in = new PipedInputStream(); 
out.connect(in); 
new Thread() { 
    @Override 
    public void run() { 
     //create your http request 
     InputStreamEntity entity = new InputStreamEntity(in, -1); 
     request.setEntity(entity); 
     client.execute(request,...); 
     //When this line is reached your data is actually written 
    } 
}.start(); 
//do whatever you like with your outputstream. 
out.write("Hallo".getBytes()); 
out.flush(); 
//close your streams 
+0

отлично работает для меня – mwag

1

Я написал инверсию HTTP Client API для Apache [PipedApacheClientOutputStream], который обеспечивает интерфейс OutputStream для HTTP POST с помощью Apache Commons HTTP Client 4.3.4.

Вызов-код выглядит следующим образом:

// Calling-code manages thread-pool 
ExecutorService es = Executors.newCachedThreadPool(
    new ThreadFactoryBuilder() 
    .setNameFormat("apache-client-executor-thread-%d") 
    .build()); 


// Build configuration 
PipedApacheClientOutputStreamConfig config = new  
    PipedApacheClientOutputStreamConfig(); 
config.setUrl("http://localhost:3000"); 
config.setPipeBufferSizeBytes(1024); 
config.setThreadPool(es); 
config.setHttpClient(HttpClientBuilder.create().build()); 

// Instantiate OutputStream 
PipedApacheClientOutputStream os = new  
PipedApacheClientOutputStream(config); 

// Write to OutputStream 
os.write(...); 

try { 
    os.close(); 
} catch (IOException e) { 
    logger.error(e.getLocalizedMessage(), e); 
} 

// Do stuff with HTTP response 
... 

// Close the HTTP response 
os.getResponse().close(); 

// Finally, shut down thread pool 
// This must occur after retrieving response (after is) if interested 
// in POST result 
es.shutdown(); 

Примечание - На практике же клиент, исполнитель услуг, и конфигурация, вероятно, будет использоваться повторно в течение всего срока применения, так внешний код подготовки и закрытия в приведенном выше примере, скорее всего, будет использоваться в сценарии начальной загрузки/инициализации и завершения, а не непосредственно в инкапсуляции OutputStream.

Смежные вопросы