簡體   English   中英

帶有Apache HTTPComponents的HTTP標頭

[英]HTTP Header with Apache HTTPComponents

我用客戶端聊天應用程序編寫基本的http服務器。 我使用自己的HTTP服務器實現,因為我想了解其功能。

客戶端使用來自Apache的HTTPComponents庫。

如果我向服務器發送請求,則此失敗代碼失敗:

org.apache.http.ProtocolException: Invalid header: <html>
at org.apache.http.impl.io.AbstractMessageParser.parseHeaders(AbstractMessageParser.java:232)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:268)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124)
at com.ssjd.client.sockets.SSJDClient.getNachrichten(SSJDClient.java:130)
at com.ssjd.client.sockets.SSJDClient.run(SSJDClient.java:82)
at java.lang.Thread.run(Thread.java:745)

我手動發送HTTP標頭,其中包含以下文本:

                              "HTTP/1.1 200 OK\n " 
                              + "Via: HTTP/1.1 localhost\n "
                              + "Server: Apache/1.3\n " +                         
                            "Content-type:       text/plain; 

                              charset=UTF-8\n " + "content-length:"
                              + body.getBytes().length;

內容長度是正文文本的長度,它是一個簡單的HTML文檔。 在我看來,語法是正確的,但我不確定。

這里是Client-Worker類:

/**
 * @throws IOException
 * @throws UnknownHostException
 * 
 */
 public SSJDClient() throws UnknownHostException, IOException
 {
  socket = new Socket( "localhost", PORT_SERVER );
 }

@Override
public void run()
{
  try
  {
    getNachrichten();
  }
  catch ( IOException | HttpException e )
  {
    LOGGER.log( Level.INFO, "Fehler beim Verarbeiten der Serverantwort",   e );
  }

}

 /**
   * @throws IOException
   * @throws HttpException
   * 
   */
  protected void getNachrichten() throws IOException, HttpException
  {
    HttpProcessor httpproc = HttpProcessorBuilder.create().add( new RequestContent() )
    .add( new RequestTargetHost() ).add( new RequestConnControl() )
    .add( new RequestUserAgent( "Mozilla/39" ) ).add( new RequestExpectContinue() ).build();

HttpRequestExecutor httpexecutor = new HttpRequestExecutor(
    HttpRequestExecutor.DEFAULT_WAIT_FOR_CONTINUE );

HttpCoreContext coreContext = HttpCoreContext.create();
HttpHost host = new HttpHost( "localhost", RequiredNetworkInformationInterface.PORT_SERVER );
coreContext.setTargetHost( host );

DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection( 8 * 1024 );
ConnectionReuseStrategy connStrategy = DefaultConnectionReuseStrategy.INSTANCE;

try
{
  // Hier ist die eigentliche Anfrage die zum Server geschickt wird.
  HttpEntity requestBodie = new StringEntity( "This is the first test request",
      ContentType.create( "text/plain", Consts.UTF_8 ) );

  if ( !conn.isOpen() )
  {
    Socket httpSocket = new Socket( host.getHostName(), host.getPort() );
    conn.bind( httpSocket );
  }
  BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest( "POST", "" );
  //wird auf die Anfrage gesetzt
  request.setEntity( requestBodie );
  LOGGER.log( Level.INFO, ">> Request URI: " + request.getRequestLine().getUri() );

  httpexecutor.preProcess( request, httpproc, coreContext );
  //Anfrage wird abgeschickt und es wird auf Antwort gewartet
  HttpResponse response = httpexecutor.execute( request, conn, coreContext );
  httpexecutor.postProcess( response, httpproc, coreContext );

  LOGGER.log( Level.INFO, "<< Anfragestatus: " + response.getStatusLine() );
  LOGGER.log(
      Level.INFO,
      "Body der Anfrage: "
          + (EntityUtils.toString( response.getEntity() ) != "" ? "Leer" : EntityUtils
              .toString( response.getEntity() )) );

  cache.add( getStringFromInputStream( response.getEntity().getContent() ) );

  // umkopieren auf ein Array, damit das wieder angezeigt werden kann
  String[] strings = new String[cache.size()];

  for ( int j = 0; j < cache.size(); j++ )
  {
    strings[ j ] = cache.get( j );
  }

  // in die Liste fügen
  getView().getVerlaufsPanel().getVerlaufListe().setListData( (strings)     );
  getView().getVerlaufsPanel().repaint();

  if ( !connStrategy.keepAlive( response, coreContext ) )
  {
    conn.close();
  }
  else
  {
    LOGGER.log( Level.INFO, "Connection ist geschlossen" );
  }

}
catch ( Exception e )
{
  LOGGER.log( Level.SEVERE, "Fehler beim Senden der Anfrage", e );
}
finally
{
  conn.close();
}
}

// convert InputStream to String
private String getStringFromInputStream( InputStream is )
{

StringBuilder sb = new StringBuilder();

String line;
try (BufferedReader br = new BufferedReader( new InputStreamReader( is     )   ))
{

  while ( (line = br.readLine()) != null )
  {
    sb.append( line );
  }

}
catch ( IOException e )
{
  e.printStackTrace();
}

return sb.toString();

}

@Override
public void actionPerformed( ActionEvent e )
{ 
  switch ( e.getID() )
  {
    case COMMAND_SENDEN:
      LOGGER.log( Level.INFO, "Nachricht wird zum Server gesendet" );
      this.run();
      break;
   } 
  }

 @Override
 protected MainFrame createView()
 {
  return new MainFrame();
 }
}

因此,我希望您能告訴我更多有關那些請求/響應操作的信息,並可能找到一個簡單的解決方案

喬納斯

我懷疑您忘記了在HTTP響應標頭和正文之間的分隔符之間添加空的新行(\\ r \\ n)。 在這種情況下,客戶端將不知道何時開始讀取正文。

您可以通過將以下參數添加到客戶端的命令行中來啟用Apache httpclient上的連線日志,從而檢查HTTP服務器到底返回了客戶端什么:

-Dorg.apache.commons.logging.simplelog.log.org.apache.http.wire=DEBUG
-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM