最近做一个项目需要调用网络上的资料,是别的公司提供的一个url接口。我们只要拼URL,然后去访问就OK了!
看起来很简单的调用,却弄了好长时间也算搞定,但是办法也不是很好!
一开始直接用URLConnection进行读操作。(加上代理)
- System.getProperties().put("proxySet","true");
- System.getProperties().put("proxyHost","IP");
- System.getProperties().put("proxyPort","PORT");
- URLConnection huc = url.openConnection();
- huc.setDoInput(true);
- StringBuffer str = new StringBuffer();
- BufferedReader in=new BufferedReader(new InputStreamReader(huc.getInputStream()));
- String inputLine;
- while((inputLine=in.readLine())!=null)
- str.append(inputLine);
- in.close();
运行发现,验证用户的URL没有问题,但在读用户信息的URL时,却很长时间没有反应,过了大约5分钟左右报502错误
502:是Bad gate way ,应该是网关错误。开始以为是我们的代理不行。然后就用拨号来试。却发现结果是相同的!
还以为是URL错误,然后把URL打在浏览器里进行尝试,却发现成功了。
于是认为是URLConnection这个类的功能不够强大,容错性不行。
并下httpClient来试,(抱怨一声httpClient的版本太多了,还要code一起运行),终于写好了,尝试运行,
- StringBuffer str = new StringBuffer();
- httpclient = new DefaultHttpClient();
- //httpclient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(3,true));
- //代理
- /**HttpHost targetHost = new HttpHost("serverip",server port, "http");
- HttpHost proxy = new HttpHost("IP", port);
- HttpRoute route = new HttpRoute(targetHost, null, proxy, false);
- HttpGet httpget = new HttpGet("/path");
- RoutedRequest routedReq = new RoutedRequest.Impl(httpget, route);
- HttpResponse response = httpclient.execute(routedReq, null);*/
- //不用代理
- HttpGet httpget = new HttpGet(urlStr);
- HttpResponse response = httpclient.execute(httpget);
- HttpEntity entity = response.getEntity();
- if (entity != null) {
- BufferedInputStream bis = new BufferedInputStream(entity.getContent());
- byte[] b = new byte[1024];
- int i=-1;
- while((i=bis.read(b))!=-1){
- str.append(new String(b,0,i));
- }
- }
- if (entity != null) {
- entity.consumeContent();
- }
还是不行,同样的问题
于是想是不是这个接口做了控制,(因为浏览器访问从来都是正确结果的),于是想办法封闭请求,便有了下面的代码
- HttpHost targetHost = new HttpHost("serverip", serverpot, "http");
- HttpHost proxy = new HttpHost("ip", port);
- HttpRoute route = new HttpRoute(targetHost, null, proxy, false);
- HttpGet httpget = new HttpGet("/.......");*/
- httpget.setHeader("Accept","image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*");
- httpget.setHeader("Accept-Language","zh-cn");
- httpget.setHeader("UA-CPU","x86");
- httpget.setHeader("Accept-Encoding","gzip,deflate");
- httpget.setHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");
- httpget.setHeader("Host","serverip:serverpot");
- httpget.setHeader("Proxy-Connection", "Keep-Alive");
- RoutedRequest routedReq = new RoutedRequest.Impl(httpget, route);
便下载了请求的拦截器,拦截请求,使得它发出的请求和浏览器的相同,可结果令人失望。(要绝望了)
这时发现,httpclient的重试功能,第二次重试可以成功访问。但中间的时间却有5分钟之久,于是便想减少超时时间
也许我没找到,或者资料不全,硬是没找到(注:httpcomponents-client-4.0-alpha1-bin,httpcomponents-core-4.0-alpha5-bin用的这两个包来做的)
于是自己创线程20秒访问不了,就关掉上一个线程,再重试,代码下:
- public void run(){
- if(isReader){
- t.cancel();
- }else{
- /**
- * 关闭
- */
- if(httpclient != null){
- httpclient.getConnectionManager().shutdown();
- //System.out.println("关闭连接");
- }
- }
- }
- public void process(){
- try{
- /**
- * 开始连接
- */
- String para = this.getParam(paras);
- if(para.length()!=0){
- urlStr = urlStr + "?" +para;
- }
- //System.out.println(new Date());
- //System.out.println(urlStr);
- StringBuffer str = new StringBuffer();
- httpclient = new DefaultHttpClient();
- //httpclient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(3,true));
- //代理
- /**HttpHost targetHost = new HttpHost("servertip", serverport, "http");
- HttpHost proxy = new HttpHost("ip", port);
- HttpRoute route = new HttpRoute(targetHost, null, proxy, false);
- HttpGet httpget = new HttpGet("/.......");
- RoutedRequest routedReq = new RoutedRequest.Impl(httpget, route);
- HttpResponse response = httpclient.execute(routedReq, null);*/
- //不用代理
- HttpGet httpget = new HttpGet(urlStr);
- HttpResponse response = httpclient.execute(httpget);
- HttpEntity entity = response.getEntity();
- if (entity != null) {
- BufferedInputStream bis = new BufferedInputStream(entity.getContent());
- byte[] b = new byte[1024];
- int i=-1;
- while((i=bis.read(b))!=-1){
- str.append(new String(b,0,i));
- }
- }
- if (entity != null) {
- entity.consumeContent();
- }
- if(str.indexOf("<rawdata></rawdata>")!=-1){
- str.delete(str.indexOf("<rawdata></rawdata>"), str.indexOf("")+"".length());
- }
- String xmlStr = this.toUnicode(str.toString(), "gb2312");
- InputStream sbis = new StringBufferInputStream(xmlStr);
- //System.out.println(xmlStr);
- //System.out.println(new Date());
- DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
- DocumentBuilder db=dbf.newDocumentBuilder();
- doc=db.parse(sbis);
- //is.close();
- sbis.close();
- this.isReader = true;
- }
- catch(Exception e)
- {
- //log.error(e);
- //e.printStackTrace();
- process();
- }
- finally
- {
- }
- }
- public Document processUrl(String urlStr,Map paras){
- this.urlStr = urlStr;
- this.paras = paras;
- t = new Timer();
- t.schedule(this,5000, 5000);
- //this.run();
- this.process();
- t.cancel();
- }
- private String toUnicode(String strText,String code) throws UnsupportedEncodingException{
- char c;
- String strRet = "" ;
- int intAsc;
- String strHex;
- strText = new String(strText.getBytes("gb2312"),code);
- for ( int i = 0; i < strText.length(); i++ ){
- c = strText.charAt(i);
- intAsc = (int)c;
- if(intAsc>128){
- strHex = Integer.toHexString(intAsc);
- strRet = strRet + "&#x" + strHex+";";
- }
- else{
- strRet = strRet + c;
- }
- }
- return strRet ;
- }
运行了一下,结果还行,就是这个办法不规范啊!(最后还有编码问题,郁闷死了)。唉!
还有关于这个问题,我了贴子问问的,可怎么老是被放到入门贴呢,还扣分。呵呵。但问题总算有个说法了!