首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2ME开发 >

,为何J2ME中通过HttpConnection读取HTML页面在真机下始终无法读取完整的HTML内容

2012-12-25 
高手指点,为何J2ME中通过HttpConnection读取HTML页面在真机上始终无法读取完整的HTML内容?高手指点,为何J2

高手指点,为何J2ME中通过HttpConnection读取HTML页面在真机上始终无法读取完整的HTML内容?
高手指点,为何J2ME中通过HttpConnection读取HTML页面在真机上始终无法读取完整的HTML内容?
我的代码片段如下: 
public class HtmlGetThread extends ThreadWrapper implements Runnable {

private HttpConnection c = null;
private String url = null;
private Vector listeners = new Vector();

public static final int MAX_LENGTH = 1024;

public HtmlGetThread(String url) {
this.url = url;

}

public String getHtmlViaURL() {
initConnection();
return getHtml();
}

private void initConnection() {
try {
c = (HttpConnection) Connector.open(url);
c.setRequestMethod(HttpConnection.GET);
} catch (IOException e) {
e.printStackTrace();
c = null;
}
}

private String getHtml() {
DataInputStream input = null;
byte[] buffer;
StringBuffer sb = new StringBuffer();
String ret = "";
try {
int code = c.getResponseCode();

if (code != HttpConnection.HTTP_OK) {
// listener.onError(code, hc.getResponseMessage());
return "";
}

input = c.openDataInputStream();

int index = 0; // buffer index
int reads; // each byte

while (true) {
buffer = new byte[MAX_LENGTH];
reads = input.read(buffer, 0, MAX_LENGTH);
if (reads <= 0)
break;

index += reads;
notifyBytesReceived(index);

String s = new String(buffer, "gb2312");
sb.append(s);
}

/*
 * if (input.available() > 0) // 缓冲区已满,无法继续读取 return "";
 */

} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
if (input != null)
try {
input.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}

return ret;

}

public void run() {
String html = getHtmlViaURL();
HtmlGetEvent e = new HtmlGetEvent(HtmlGetEvent.STATUS_OK, html);
notifyHtmlGet(e);
}

public void addHtmlGetListener(IHtmlGetListener l) {
listeners.addElement(l);
}

public void notifyHtmlGet(HtmlGetEvent e) {
Enumeration enum = listeners.elements();
while (enum.hasMoreElements()) {
Object o = enum.nextElement();
if (o instanceof IHtmlGetListener) {
IHtmlGetListener l = (IHtmlGetListener) o;
l.onHtmlGet(e);
}
}
}

public void notifyBytesReceived(int size) {
Enumeration enum = listeners.elements();
while (enum.hasMoreElements()) {
Object o = enum.nextElement();
if (o instanceof IHtmlGetListener) {
IHtmlGetListener l = (IHtmlGetListener) o;
l.onBytesReceived(size);
}
}
}
}

真机测试发现始终无法完整读取内容。
------最佳解决方案--------------------


kjava在传输字符串的过程中,对字符串的长度是有限制的. 在nokia6300上面,一次性传输大概在300个字符左右.大于这个值后面的字符串读取不到了.建议你对字符串进行分割,然后分段传输,在获取.
[其他解释]
把<=0改为<0试试。


while (true) { 
buffer = new byte[MAX_LENGTH]; 
reads = input.read(buffer, 0, MAX_LENGTH); 
if (reads < 0) 
break; 

index += reads; 
notifyBytesReceived(index); 

String s = new String(buffer, "gb2312"); 
sb.append(s); 




[其他解释]
public static final int MAX_LENGTH = 1024; 
while (true) { 
buffer = new byte[MAX_LENGTH]; 
reads = input.read(buffer, 0, MAX_LENGTH); 
if (reads <= 0) 
break; 
这个值是不是有点小?设置大些4096 试试
[其他解释]
我测试了。还是不行。
IHtmlGetListener的定义如下: 
public interface IHtmlGetListener {
public void onHtmlGet(HtmlGetEvent e);
public void onBytesReceived(int size);
}

有兴趣的高手可以实现一个MIDlet测试下这个HtmlGetThread类,
ThreadWrapper定义如下:

public class ThreadWrapper {

public void launchTread() {
if (this instanceof Runnable) {
Runnable r = (Runnable) this;
Thread t = new Thread(r);
t.start();
}
}
}

测试结果是public void onBytesReceived(int size);这里在通知监听者,监听者会在接收到一定数量的数据后就接收不到数据了,现象上就好像是数据一直都读不完,线程一直没有完成工作。
[其他解释]
引用:
public static final int MAX_LENGTH = 1024;
 while (true) {
 buffer = new byte[MAX_LENGTH];
 reads = input.read(buffer, 0, MAX_LENGTH);
 if (reads  <= 0)
 break;
 这个值是不是有点小?设置大些4096 试试


应该不是这个问题,这个值我反复设置过测试过,问题依然存在。
[其他解释]
input = c.openDataInputStream(); 

int index = 0; // buffer index 
int reads; // each byte 

while (true) { 
buffer = new byte[MAX_LENGTH]; 
reads = input.read(buffer, 0, MAX_LENGTH); 
if (reads <= 0) 
break; 


你把reads 返回的字节 
再控制台一字符串的形式输出一下看下完整不?
InputStream in=c.openInputStream();
DataInputStream dis=new DataInputStream(in);
byte buf[]=new byte[in.available()];
in.read(buf);
result=new String(buf,"utf-8");     
System.out.println(result);
[其他解释]
while (true) { 
buffer = new byte[MAX_LENGTH]; 
reads = input.read(buffer, 0, MAX_LENGTH); 
if (reads <= 0) 
break; 

index += reads; 
notifyBytesReceived(index); 

String s = new String(buffer, "gb2312"); 
sb.append(s); 




改成这样试试:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b1 = new byte[MAX_LENGTH];
int i;

while ((i = is.read(b1)) != -1) {
baos.write(b1, 0, i);
index += reads; 
notifyBytesReceived(index); 
}
b = baos.toByteArray();
String s = new String(b, "gb2312"); 
sb.append(s); 

baos.close();
baos = null;
[其他解释]

引用:
Java codeinput= c.openDataInputStream();int index=0;// buffer indexint reads;// each bytewhile (true) { 
buffer=newbyte[MAX_LENGTH]; 
reads= input.read(buffer,0, MAX_LENGTH);if (reads<=0)break;

 你把reads 返回的字节
 再控制台一字符串的形式输出一下看下完整不?
 InputStream in=c.openInputStream();
 DataInputStream dis=new DataInputStream(in);
 byte buf[]=new byte[in.available()];
 in.read(buf);
 result=new String(buf,"utf-8");
 System.out.println(result);


在模拟器上是可以正常工作的,能够把数据完整读回。在手机上测试就不行
[其他解释]
引用:
while (true) {
 buffer = new byte[MAX_LENGTH];
 reads = input.read(buffer, 0, MAX_LENGTH);
 if (reads  <= 0)
 break;

 index += reads;
 notifyBytesReceived(index);

 String s = new String(buffer, "gb2312");
 sb.append(s);
 }

 改成这样试试:
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 byte[] b1 = new byte[MAX_LENGTH];
 int i;

 while ((i = is.read(b1)) != -1) {
 baos.write(b1, 0, i);
 index += reads;
 notifyBytesReceived(index);
 }
 b = baos.toByteArray();
 String s = new String(b, "gb2312");
 sb.append(s);

 baos.close();
 baos = null;


这个代码写法我测试过了。还是不行
[其他解释]
这样应该是可以的 我这样读取图片都能读取出来的啊  public Image loadImage(String url) throws IOException {
HttpConnection hpc = null;
DataInputStream dis = null;
try {
mainForm.append("                                                          " +
"                                                               " +
"                                                  " +


"                                                   "+
"         图片读取中请稍候...");

hpc = (HttpConnection) Connector.open(url);
 hpc.setRequestProperty("X-Online-Host", "s602.cn:8118");

int code = hpc.getResponseCode();

if (code == 200) {
String contentType = hpc.getHeaderField("Content-Type");
if (contentType.indexOf("wml") != -1) {
return loadImage(url);
}
}

dis = new DataInputStream(hpc.openInputStream());
ByteArrayOutputStream dos = null;
byte[] downim;
int ch = (int) hpc.getLength();
if (ch != -1) {
downim = new byte[ch];
dis.readFully(downim);
} else {
dos = new ByteArrayOutputStream();
int hh;
while ((hh = dis.read()) != -1) {

dos.write(hh);
}
downim = dos.toByteArray();

}
return Image.createImage(downim, 0, downim.length);


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

}catch (SecurityException s){
s.printStackTrace();


}finally {
if (hpc != null)
hpc.close();
if (dis != null)
dis.close();
}
return null;
}
[其他解释]

引用:
这样应该是可以的 我这样读取图片都能读取出来的啊? public Image loadImage(String url) throws IOException {
 HttpConnection hpc = null;
 DataInputStream dis = null;
 try {
 mainForm.append("? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " +
 "? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  " +
 "? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " +
 "? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  "+
 "? ? ? ?  图片读取中请稍候...");

 hpc = (HttpConnection) Connector.open(url);
  hpc.setRequestProperty("X-Online-Host", "s602.cn:8118");

 int code = hpc.getResponseCode();

 if (code == 200) {
 String contentType = hpc.getHeaderField("Content-Type");
 if (contentType.indexOf("wml") != -1) {
 return loadImage(url);
 }
 }

 dis = new DataInputStream(hpc.openInputStream());


 ByteArrayOutputStream dos = null;
 byte[] downim;
 int ch = (int) hpc.getLength();
 if (ch != -1) {
 downim = new byte[ch];
 dis.readFully(downim);
 } else {
 dos = new ByteArrayOutputStream();
 int hh;
 while ((hh = dis.read()) != -1) {

 dos.write(hh);
 }
 downim = dos.toByteArray();

 }
 return Image.createImage(downim, 0, downim.length);


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

 }catch (SecurityException s){
 s.printStackTrace();


 }finally {
 if (hpc != null)
 hpc.close();
 if (dis != null)
 dis.close();
 }
 return null;
 }



你打开的图片有多大?
[其他解释]
都是几十k的吧

[其他解释]
我看了下至少在15k以上

[其他解释]
我测试过,我的程序有时读到9k的时候就不动了,有时读到34k的时候不动了。手机上又很难调试。。。。
[其他解释]
引用:
kjava在传输字符串的过程中,对字符串的长度是有限制的. 在nokia6300上面,一次性传输大概在300个字符左右.大于这个值后面的字符串读取不到了.建议你对字符串进行分割,然后分段传输,在获取.


能不能请你详细介绍下这个限制?我也很怀疑是某些限制导致的问题。你说的这个传输字符串是怎么一回事?是在InputStream上read的长度有限制?还是说StringBuffer上append字符有限制?谢谢
[其他解释]
限制是在手机上面.

分割字符串传输,就是在服务器端.

手机客户服端,接收完字符串后,在拼接.
[其他解释]
http://blog.csdn.net/kf156/archive/2009/11/02/4757919.aspx
用这例子测下看行不行。
[其他解释]
引用:
限制是在手机上面.

 分割字符串传输,就是在服务器端.

 手机客户服端,接收完字符串后,在拼接.


服务器端是不是就是所谓的chunked。手机客户端需要怎么做?
[其他解释]
while (true) {
  buffer = new byte[1024];
  Log.error("To read");
  reads = input.read(buffer, 0, 1024);
  Log.error("Read");
  if (reads < 0)
    break;
  index += reads;

  notifyBytesReceived(index);

  Log.error(String.valueOf(index) + "bytes received");
  /*String s = new String(buffer);
  sb.append(s);*/

  buffer = null;
}

通过添加日志调试发现卡住的时候日志里只打了To read。后面那句Read的日志就没有了。
应该是堵塞在input.read上了。
这是为什么呢?
[其他解释]
个人感觉还是在读数据的地方出问题了,你可以试试catch的地方换成Throwable试试,我觉得在new String的时候会报一个编码异常。。
[其他解释]
引用:
再重新new 个线程试试……

怎么new 线程?不是太懂你的意思。谢谢

我目前这段创建链接读取html就是在线程里完成的。跟UI是分开的。



[其他解释]
再重新new 个线程试试……
[其他解释]
亚日升分真快

http://blog.csdn.net/kf156/archive/2009/11/02/4757919.aspx 
[其他解释]
try{
reads = input.read(buffer, 0, 1024); 
}catch(){
 //输出日志
}

看看是不是有什么异常了。
[其他解释]

引用:
亚日升分真快


都是J2ME版得来的辛苦分



引用:
没有异常,while循环是包在try{}catch(Exception e){}里的。应该只要有异常就捕获了。

一进while就卡在这了?那是否有把这异常输出日志呢?
[其他解释]
引用:
try{
 reads = input.read(buffer, 0, 1024);
 }catch(){
  //输出日志
 }

 看看是不是有什么异常了。


没有异常,while循环是包在try{}catch(Exception e){}里的。应该只要有异常就捕获了。
[其他解释]
String s = new String(buffer, "gb2312");
sb.append(s); 
这个地方有问题,你是截断流来创建字符串的,但是你不能保证你截断的地方正好是一个字符编码的末尾,有可能你截了一半,然后想创建字符串,就会失败抛出异常了,也许就导致了以无法读取完整的编码。按基本的网络连接获取数据的代码来看没什么问题。
[其他解释]
引用:
引用:
 亚日升分真快



 都是J2ME版得来的辛苦分


引用:

 没有异常,while循环是包在try{}catch(Exception e){}里的。应该只要有异常就捕获了。

 一进while就卡在这了?那是否有把这异常输出日志呢?


不是。notifyBytesReceived(index); 这句会通知监听者进度。
目前的测试看会读到165k的时候卡住。换个http地址读取的话又会在15k的时候卡住。看起来似乎没有什么规律。但不是进去就卡住
[其他解释]
就那么10几k的字符串,不用拆分吧?难道还是低端手机?
[其他解释]
又看了一下,你这个地方没有捕获异常,捕获的只是io异常,创建字符串的异常捕获不到,所以可能断了也不会通知你的。
[其他解释]
关注
[其他解释]

buffer = new byte[1024]; 
这句放到while的外面去看看
[其他解释]
想问一下怎么解决的

热点排行