2013年11月19日星期二

httpClient how to receive a malformed response headers

Use httpClient read data from the server side , abnormal :
Caused by: org.apache.http.ProtocolException: The server failed to respond with a valid HTTP response
executed code is as follows:

public static String getResultByHttpGet()
            throws ClientProtocolException, IOException
    {
        String result = "";
                String url="http://192.168.1.83/imonitorint.html?op=r&33032=0";
        HttpGet httpGet = new HttpGet(url);
                //执行这行代码时出错
        HttpResponse response = new DefaultHttpClient().execute(httpGet);
        if (response.getStatusLine().getStatusCode() == 200)
        {
            HttpEntity entity = response.getEntity();
            result = EntityUtils.toString(entity, "GB2312");
        }
        return result;
    }

String url = "http://192.168.1.83/imonitorint.html?op=r&33032=0";
this url in the browser is opened directly return the results , but the error occurs in the code execution
via ie browser plug httpwatch, view server returns the entire contents of the response was found to return the header is empty.
as shown below:

how to make HttpClient to accept malformed response headers , blog Internet was introduced , but not detailed enough :
http://www.cnblogs.com/loveyakamoz/archive/2011 / 07/21/2113251.html
discussed this issue before posting , but does not address :
http :/ / topic.csdn.net/u/20120816/16/f1092599-6b75-4216-aa24-b5f3f95fde6d.html? seed = 814375011 & r = 79432055 # r_79432055

full error message :
org.apache.http.client.ClientProtocolException
at org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java: 822)
at org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java: 754)
at org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java: 732)
at com.osee.yws.httpAgreement.HttpAgreement.getResultByHttpGet (HttpAgreement.java: 50)
at com.osee.yws.bll.LCDOptionBll.readLcdOption (LCDOptionBll.java: 104)
at com.osee.yws.bll.LCDOptionBll.readInput (LCDOptionBll.java: 73)
at com.osee.yws.gui.SetDeviceOptionLCD $ 1.windowOpened (SetDeviceOptionLCD.java: 74)
at java.awt.AWTEventMulticaster.windowOpened (Unknown Source)
at java.awt.AWTEventMulticaster.windowOpened (Unknown Source)
at java.awt.Window.processWindowEvent (Unknown Source)
at javax.swing.JDialog.processWindowEvent (Unknown Source)
at java.awt.Window.processEvent (Unknown Source)
at java.awt.Component.dispatchEventImpl (Unknown Source)
at java.awt.Container.dispatchEventImpl (Unknown Source)
at java.awt.Window.dispatchEventImpl (Unknown Source)
at java.awt.Component.dispatchEvent (Unknown Source)
at java.awt.EventQueue.dispatchEventImpl (Unknown Source)
at java.awt.EventQueue.access $ 000 (Unknown Source)
at java.awt.EventQueue $ 1.run (Unknown Source)
at java.awt.EventQueue $ 1.run (Unknown Source)
at java.security.AccessController.doPrivileged (Native Method)
at java.security.AccessControlContext $ 1.doIntersectionPrivilege (Unknown Source)
at java.security.AccessControlContext $ 1.doIntersectionPrivilege (Unknown Source)
at java.awt.EventQueue $ 2.run (Unknown Source)
at java.awt.EventQueue $ 2.run (Unknown Source)
at java.security.AccessController.doPrivileged (Native Method)
at java.security.AccessControlContext $ 1.doIntersectionPrivilege (Unknown Source)
at java.awt.EventQueue.dispatchEvent (Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters (Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter (Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy (Unknown Source)
at java.awt.EventDispatchThread.pumpEvents (Unknown Source)
at java.awt.EventDispatchThread.pumpEvents (Unknown Source)
at java.awt.EventDispatchThread.run (Unknown Source)
Caused by: org.apache.http.ProtocolException: The server failed to respond with a valid HTTP response
at org.apache.http.impl.conn.DefaultResponseParser.parseHead (DefaultResponseParser.java: 109)
at org.apache.http.impl.io.AbstractMessageParser.parse (AbstractMessageParser.java: 252)
at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader (AbstractHttpClientConnection.java: 281)
at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader (DefaultClientConnection.java: 247)
at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader (AbstractClientConnAdapter.java: 219)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse (HttpRequestExecutor.java: 298)
at org.apache.http.protocol.HttpRequestExecutor.execute (HttpRequestExecutor.java: 125)
at org.apache.http.impl.client.DefaultRequestDirector.tryExecute (DefaultRequestDirector.java: 645)
at org.apache.http.impl.client.DefaultRequestDirector.execute (DefaultRequestDirector.java: 464)
at org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java: 820)
... 33 more
------ Solution ---------------------------- ----------------
Here is my view:

head light shielding code parsing errors should be of no use.

For content to read, return head of content is essential.

httpclient component gets back , you need a head at least these few items inside
1) HTTP/1.1 200 OK status code

2) Content-Length: 56008 Length
of course also be non- fixed-length content
2) Transfer-Encoding: chunked

3) Content-Type: text / html; charset = utf-8 tag content format

we think about it, even the most basic status code / length / format did not submit to the httpclient. It is how to parse response.


Of course, there may be possible to skip these , get the original response stream. Careful not to analyze the code httpclient bad conclusion.


------ Solution ------------------------------------ --------



public static void main(String[] args) {
String result = "";
    String url="http://www.baidu.com/";
    HttpGet httpGet = new HttpGet(url);
    //执行这行代码时出错
    ClientConnectionManager cm = new MyBasicClientConnectionManager();
DefaultHttpClient hc = new DefaultHttpClient(cm);
HttpResponse response;
try {
response = hc.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200){
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "GB2312");
}
System.out.println(result);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


I use baidu to try.
things play out . . . .
------ For reference only ------------------------------------ ---
landlord made the problem detailed enough . worth learning ~ ~ ~

------ For reference only ---------------------------------- -----
I saw basically know that.
share to the landlord .

you give that website useful.


    class MyClientConnManager extends SingleClientConnManager {
    public MyClientConnManager(
    final HttpParams params,
    final SchemeRegistry sr) {
    super(params, sr);
    }
    @Override
    protected ClientConnectionOperator createConnectionOperator(
    final SchemeRegistry sr) {
    return new MyClientConnectionOperator(sr);
    }
    }

SingleClientConnManager above has been not recommended.
can be replaced
BasicClientConnectionManager, PoolingClientConnectionManager, ThreadSafeClientConnManager
One of the bar. I have not tried.

If BasicClientConnectionManager This inherited words.
constructor can be no argument .
then you

ClientConnectionManager cm = new MyBasicClientConnectionManager()
DefaultHttpClient hc = new DefaultHttpClient(cm);
HttpResponse response = hc.execute(httpGet);


Of course, the most important thing is that in the URL where you



    class MyLineParser extends BasicLineParser {
    @Override
    public Header parseHeader(
    final CharArrayBuffer buffer) throws ParseException {
    try {
    return super.parseHeader(buffer);
    } catch (ParseException ex) {
    // 压制ParseException异常
    return new BasicHeader("invalid", buffer.toString());
    }
    }
    }


exception caught after it how ignored.
with original httpClient library is
super.parseHeader (buffer); happening here ProtocolException
------ For reference only ----------------------- ----------------
If you give your on that site
or
I just hurriedly said there are questions about the case, welcomed the discussion :)
------ For reference only ---------------- -----------------------
you very much, I mainly do not understand what the article describes how to use .
------ For reference only -------------------------------------- -
MyLineParser you give code does not seem to spend.
------ For reference only -------------------------------------- -


I have not used HttpClient. just here to ask than more.
I have not run off , and went down a few jar in the blind fiddle .

MyBasicClientConnectionManager code

package sh.pl;

import org.apache.http.Header;
import org.apache.http.HttpResponseFactory;
import org.apache.http.conn.ClientConnectionOperator;
import org.apache.http.conn.OperatedClientConnection;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.conn.BasicClientConnectionManager;
import org.apache.http.impl.conn.DefaultClientConnection;
import org.apache.http.impl.conn.DefaultClientConnectionOperator;
import org.apache.http.impl.conn.DefaultHttpResponseParser;
import org.apache.http.io.HttpMessageParser;
import org.apache.http.io.SessionInputBuffer;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicLineParser;
import org.apache.http.params.HttpParams;
import org.apache.http.util.CharArrayBuffer;

public class MyBasicClientConnectionManager extends
BasicClientConnectionManager {

public MyBasicClientConnectionManager() {
super();
}

@Override
protected ClientConnectionOperator createConnectionOperator(
final SchemeRegistry sr) {
return new MyClientConnectionOperator(sr);
}

class MyLineParser extends BasicLineParser {
@Override
public Header parseHeader(final CharArrayBuffer buffer) {
try {
return super.parseHeader(buffer);
} catch (Exception ex) {
// 压制ParseException异常
return new BasicHeader("invalid", buffer.toString());
}
}
}

class MyClientConnection extends DefaultClientConnection {
@Override
protected HttpMessageParser createResponseParser(
final SessionInputBuffer buffer,
final HttpResponseFactory responseFactory,
final HttpParams params) {
return new DefaultHttpResponseParser(buffer, new MyLineParser(),
responseFactory, params);
}
}

class MyClientConnectionOperator extends DefaultClientConnectionOperator {
public MyClientConnectionOperator(final SchemeRegistry sr) {
super(sr);
}

@Override
public OperatedClientConnection createConnection() {
return new MyClientConnection();
}
}

}



Use

ClientConnectionManager cm = new MyBasicClientConnectionManager();
DefaultHttpClient hc = new DefaultHttpClient(cm);
HttpResponse response = hc.execute(httpGet);


you try.
------ For reference only ------------------------------------ ---
still the same error .

org.apache.http.client.ClientProtocolException
at org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java: 909)
at org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java: 805)
at org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java: 784)
at HttpAgreement.getResultByHttpGet1 (HttpAgreement.java: 71)
at HttpAgreement.main (HttpAgreement.java: 115)
Caused by: org.apache.http.ProtocolException: The server failed to respond with a valid HTTP response
at org.apache.http. impl.conn.DefaultHttpResponseParser.parseHead (DefaultHttpResponseParser.java: 103)
at
org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead (DefaultHttpResponseParser.java: 62)
at org.apache.http.impl.io.AbstractMessageParser.parse (AbstractMessageParser.java: 254)
at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader (AbstractHttpClientConnection.java: 289)
at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader (DefaultClientConnection.java: 252)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader (ManagedClientConnectionImpl.java: 191)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse (HttpRequestExecutor.java: 300)
at org.apache.http.protocol.HttpRequestExecutor.execute (HttpRequestExecutor.java: 127)
at org.apache.http.impl.client.DefaultRequestDirector.tryExecute (DefaultRequestDirector.java: 712)
at org.apache.http.impl.client.DefaultRequestDirector.execute (DefaultRequestDirector.java: 517)
at org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java: 906)
... 4 more
------ For reference only -------------------------- -------------

   class MyLineParser extends BasicLineParser {
        @Override
        public Header parseHeader(final CharArrayBuffer buffer) {
            try {
                //这行代码没有执行
                return super.parseHeader(buffer);
            } catch (Exception ex) {
                // 压制ParseException异常 也这行代码没有执行
                return new BasicHeader("invalid", buffer.toString());
            }
        }
    }

add breakpoints found that this class inside the code is not executed

------ For reference only ---------------------------------- -----
1) I use 4.2.1httpClient
2) you call the place is really according to the following changed?

ClientConnectionManager cm = new MyBasicClientConnectionManager ();
DefaultHttpClient hc = new DefaultHttpClient ( cm );
HttpResponse response = hc.execute (httpGet);


my local is usable .
------ For reference only -------------------------------------- -
your

HttpResponse response = new DefaultHttpClient().execute(httpGet);


To change

ClientConnectionManager cm = new MyBasicClientConnectionManager();
DefaultHttpClient hc = new DefaultHttpClient(cm);
HttpResponse response = hc.execute(httpGet);


3句.

changed so I can not confirm your right , but I can walk to local execution method in MyLineParser # parseHeader .
------ For reference only -------------------------------------- -

public static String getResultByHttpGet1(String url)
throws ClientProtocolException, IOException
{
try
{
SingleClientConnManager sccm =new SingleClientConnManager(); 
String result = "";
url1 = "http://192.168.1.83/imonitorint.html?op=r&33032=0";
                         
//url2="http://192.168.1.5/web/getwinoptions.php?opt=0.24,&ts=324532589789789767jk";
HttpGet httpGet = new HttpGet(url1);
    ClientConnectionManager cm = new MyBasicClientConnectionManager();
    DefaultHttpClient hc = new DefaultHttpClient(cm);
    HttpResponse response = hc.execute(httpGet);

return result;
} catch (Exception err)
{
err.printStackTrace();
}
return "";
}

certainly changed over the code , I tried to get data correctly url, that can go MyLineParser # parseHeader , going in the right situation, but when using the wrong url , simply do not go MyLineParser # parseHeader , and did not take exception handling part.
------ For reference only -------------------------------------- -
your httpClient is up to date? 4.2.1?
------ For reference only -------------------------------- -------
MyBasicClientConnectionManager I changed , you should should be able to look at the next ~ ~ trouble again .


package sh.pl;

import java.io.IOException;

import org.apache.http.Header;
import org.apache.http.HttpException;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseFactory;
import org.apache.http.HttpVersion;
import org.apache.http.conn.ClientConnectionOperator;
import org.apache.http.conn.OperatedClientConnection;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.conn.BasicClientConnectionManager;
import org.apache.http.impl.conn.DefaultClientConnection;
import org.apache.http.impl.conn.DefaultClientConnectionOperator;
import org.apache.http.impl.conn.DefaultHttpResponseParser;
import org.apache.http.io.HttpMessageParser;
import org.apache.http.io.SessionInputBuffer;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicLineParser;
import org.apache.http.message.BasicStatusLine;
import org.apache.http.message.LineParser;
import org.apache.http.params.HttpParams;
import org.apache.http.util.CharArrayBuffer;

public class MyBasicClientConnectionManager extends
BasicClientConnectionManager {

public MyBasicClientConnectionManager() {
super();
}

@Override
protected ClientConnectionOperator createConnectionOperator(
final SchemeRegistry sr) {
return new MyClientConnectionOperator(sr);
}

class MyLineParser extends BasicLineParser {
@Override
public Header parseHeader(final CharArrayBuffer buffer) {
try {
return super.parseHeader(buffer);
} catch (Exception ex) {
// 压制ParseException异常
return new BasicHeader("invalid", buffer.toString());
}
}
}

class MyClientConnection extends DefaultClientConnection {
@Override
protected HttpMessageParser createResponseParser(
final SessionInputBuffer buffer,
final HttpResponseFactory responseFactory,
final HttpParams params) {
return new MyDefaultHttpResponseParser(buffer, new MyLineParser(),
responseFactory, params);
}
}

class MyDefaultHttpResponseParser extends DefaultHttpResponseParser {
    public MyDefaultHttpResponseParser(SessionInputBuffer buffer,
LineParser parser, HttpResponseFactory responseFactory,
HttpParams params) {
super(buffer, parser, responseFactory, params);
}
@Override
    protected HttpResponse parseHead(
            final SessionInputBuffer sessionBuffer) throws IOException, HttpException {
try {
return super.parseHead(sessionBuffer);
} catch (Exception ex) {
// 压制ParseException异常
return new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, 200, ""));
}
    }
}

class MyClientConnectionOperator extends DefaultClientConnectionOperator {
public MyClientConnectionOperator(final SchemeRegistry sr) {
super(sr);
}

@Override
public OperatedClientConnection createConnection() {
return new MyClientConnection();
}
}

}


------ For reference only ----------------------------------- ----
top
------ For reference only ---------------------------------------


Do not just oh ~ ~ # 13 top floor tried yet ? ?
If there are problems , think

return new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, 200, ""));

phrase how to change .

------ For reference only ---------------------------------- -----
no exception , but it can not read the data , the correct url is also not read the data,
Use url1 = "http://192.168.1.83/imonitorint.html?op=r&33032=0"; , they also did not go MyLineParser # parseHeader exception handling .
------ For reference only -------------------------------------- -


MyDefaultHttpResponseParser # parseHead into the thing ?
And I worry about you and I use httpclient version is not the same.
I use 4.2.1 .

httpclient latest version
http:// mirror.bit.edu.cn / apache / / httpcomponents/httpclient/binary/httpcomponents-client-4.2.1-osgi-bin.zip

httpcore latest version
http:// mirror.bit.edu.cn / apache / / httpcomponents/httpcore/binary/httpcomponents-core-4.2.1-osgi-bin.zip
------ For reference only ---- -----------------------------------
version, I just downloaded is 4.2.1
httpcore did not use the latest version of this , there is no download
Use url2 = "http://192.168.1.5/web/getwinoptions.php?opt=0.24, & ts = 324532589789789767jk";
together when you can get the correct data , you can go MyDefaultHttpResponseParser # parseHead, now you can go MyDefaultHttpResponseParser # parseHead, but the final result is null.

Use url1 = "http://192.168.1.83/imonitorint.html?op=r&33032=0"; previously abnormal , there is no exception , but the result is an empty , did not go into MyDefaultHttpResponseParser # parseHead


------ For reference only ---------------------------------- -----
http://dl.iteye .com/topics/download/1f849e26-6132-3ce6-9e47-ba4cb18ed88f
I wrote the test project , you are free to download , try it .

------ For reference only ---------------------------------- -----
http://goro.iteye.com/admin/blogs/1636275
iteye address downloads may require registration. sorry.
------ For reference only -------------------------------------- -
  This reply was moderator deleted at 2012-08-20 09:37:41

------ For reference only ---------------------------------- -----


If the landlord downloaded this , run my program can achieve baidu return value.
Just try the url into your url try. If you can get to .
So I guess the question is the jar , maybe you used a lot of jar. And some jar contains a httpClient or httpCore old classes.
try to put me to download your latest httpclient and httpcore added buildpath Lane is located in the front , and then try your project .

------ For reference only ---------------------------------- -----
http://192.168.1.83/imonitorint.html?op=r&33032=0
this address with a browser to access normal right ?
------ For reference only -------------------------------------- -
lz get it ? ? Do not forget to get the code and share ~ ~
There knot stickers oh ~ ~ Thank you.
------ For reference only -------------------------------------- -
not solve the problem , do not know is that the code did not write , or the service side of the issue . Thank scbb quiz so many times .
------ For reference only -------------------------------------- -
this problem may be bug, use the version 4.1 and 4.3 do not have this problem, use the 4.2.1 version has this problem.
my test result is this .

没有评论:

发表评论