[英]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.