深入刨析tomcat 之---第2篇,解决第3章bug 页面不显示内容http://localhost:8080/servlet/ModernServlet?userName=zhangyantao&password=1234
writedby 张艳涛7月2日,
在学习第4张的过程中,发现了前一篇文章写的是关于1,2张的bug不用设置response响应头,需要在servlet的service()方法里面写是错误想
servlet是tomcat的容器内的居住者,主要功能在于交互式地浏览和生成数据,生成动态Web内容,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。那么这个servlet实际上是基于http协议的响应体的实现,可以这么说,servlet本质上是对于一个http请求的响应,servlet程序段service()方法,根据http协议来回复客户端的http请求, 对于一个http 请求,回复的内容在哪里? 在response的body里面,如果你是一个网页那么,Content-Type="text/html", response.setContentType("text/html");其实如果你不设置content_type浏览器也能只能的显示为网页;突然发现浏览器很傻_B,如果你返回给浏览器为json格式那么你就给一个Content-Type:
out = new PrintWriter(socket.getOutputStream());
if (filePath.endsWith("jpg") || filePath.endsWith("ico")) {
in = new FileInputStream(filePath);//读图片
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i=0;
while (((i = in.read()) != -1)) {
baos.write(i);
}
byte[] array= baos.toByteArray();
out.println("HTTP/1.1 200 OK");
out.println("Server: Molly");
out.println("Content-Type: image/jpeg");
out.println("Content-Length: "+array.length);
out.println("");
out.flush();
socket.getOutputStream().write(array,0,array.length);//写入图片
System.out.println(Thread.currentThread().getName());
这样子就成功了,
上一篇文章对于response头信息的设置实现
对于xxx.servlet文件中
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
如果out.println("内容"),这个out是socket.getoutputstream的对象,肯定不行,那么就直接发送了,如果保证在头对象之后是这个设计的精髓
这个out对象是
ResponseStream
因为response.getWriter();内容为
HttpResponse类中
@Override
public PrintWriter getWriter() throws IOException {
ResponseStream newStream = new ResponseStream(this);
newStream.setCommit(false);
OutputStreamWriter osr =
new OutputStreamWriter(newStream, getCharacterEncoding());
writer = new ex03.pyrmont.connector.ResponseWriter(osr);
return writer;
}
那么久确定了out.println("内容"),的out是ResponseStream ,那么会通过printwrite调用write()
public void write(byte b[], int off, int len) throws IOException {
if (closed)
throw new IOException("responseStream.write.closed");
int actual = len;
if ((length > 0) && ((count + len) >= length))
actual = length - count;
response.write(b, off, actual);
count += actual;
if (actual < len)
throw new IOException("responseStream.write.count");
}
那么
HttpResponse类中
public void write(int b) throws IOException{
if (bufferCount>=buffer.length) {
flushBuffer();
}
buffer[bufferCount++] = ((byte) b);
contentCount++;
} public void write(byte b[],int off,int len) throws IOException{
if (len==0) {
return;
}
if (len<=buffer.length-bufferCount) {
System.arraycopy(b,off,buffer,bufferCount,len);
bufferCount += len;
contentCount += len;
return;
}
flushBuffer(); /** 将buffercount置为0;清空buffer*/
int iterations= len/buffer.length; /**len太大 看一共有几倍 */
int leftoverStart=iterations*buffer.length;
int leftoverLen = len - leftoverStart;
for (int i = 0; i < iterations; i++) {
write(b, off + (i * buffer.length), buffer.length);
}
if(leftoverLen>0){
write(b, off + leftoverStart, leftoverLen);
}
}
看代码,层层分析之后能发现,最终调用的给buffer数组赋值,只有到flush之后才会发送网络数据,那么,要做的就是先调用sendHeadrs在out.flush();
ServletProcessor类中
servlet = ((Servlet) myClass.newInstance());
HttpRequestFacade httpRequestFacade = new HttpRequestFacade(request);
HttpResponseFacade httpResponseFacade = new HttpResponseFacade(response);
servlet.service(httpRequestFacade,httpResponseFacade);
((HttpResponse) response).finishResponse();
接着
public void finishResponse() throws IOException {
sendHeaders();
if (writer != null) {// writer = new ex03.pyrmont.connector.ResponseWriter(osr);,这里是
writer.flush();
writer.close();
}
}
代码和上面的描述一致的
那么,看sendheaders代码
protected void sendHeaders() throws IOException{
if (isCommitted()) {
return;
}
OutputStreamWriter osr = null;
try {
osr = new OutputStreamWriter(getStream(), getCharacterEncoding());
} catch (UnsupportedEncodingException e) {
osr = new OutputStreamWriter(getStream());
}
final PrintWriter outputWriter = new PrintWriter(osr);
// Send the "Status:" header
outputWriter.print((this.request.getProtocol()));
outputWriter.print(" ");
outputWriter.print(status);
if(message!=null){
outputWriter.print(" ");
outputWriter.print(message);
}
outputWriter.print("\r\n");
if(getContentType()!=null){
outputWriter.print(" ");
outputWriter.print("Content-Type: " + getContentType() + "\r\n");
}
if (getContentLength() >= 0) {
outputWriter.print("Content-Length: " + getContentLength() + "\r\n");
}
synchronized (headers) {
Iterator names = headers.keySet().iterator();
while (names.hasNext()) {
String name = (String) names.next();
ArrayList values = (ArrayList) headers.get(name);
Iterator items = values.iterator();
while (items.hasNext()) {
String value = (String) items.next();
outputWriter.print(name);
outputWriter.print(": ");
outputWriter.print(value);
outputWriter.println("\r\n");
}
}
}
synchronized (cookies) {
Iterator items = cookies.iterator();
while (items.hasNext()) {
Cookie cookie = (Cookie) items.next();
outputWriter.print(CookieTools.getCookieHeaderName(cookie));
outputWriter.print(": ");
outputWriter.print(CookieTools.getCookieHeaderValue(cookie));
outputWriter.print("\r\n");
}
}
outputWriter.print("\r\n");
outputWriter.flush();
committed = true;
}
这个outwriter直接取值socket.getoutputstream方法
以上代码全来深入刨析tocmat第3章
那么第三章的bug是什么呢?,浏览器执行
http://localhost:8080/servlet/ModernServlet?userName=zhangyantao&password=1234
运行程序页面没反应!!!
给程序打断点也发送sendHeaders,这颗怎么办呢?chrome f12 看不出来什么呢,只能看人才的了
package com.zyt.tomcat.ex03.startup; import java.io.*;
import java.net.Socket; public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 8080);
System.out.println(socket);
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
InputStream inputStream = socket.getInputStream(); pw.println("GET /servlet/ModernServlet?userName=zhangyantao&password=1234l HTTP/1.1");
pw.println("Host: localhost:8080");
pw.println("Connection: keep-alive\n" +
"sec-ch-ua: \" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"\n" +
"sec-ch-ua-mobile: ?0\n" +
"Upgrade-Insecure-Requests: 1\n" +
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36\n" +
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\n" +
"Sec-Fetch-Site: none\n" +
"Sec-Fetch-Mode: navigate\n" +
"Sec-Fetch-User: ?1\n" +
"Sec-Fetch-Dest: document\n" +
"Accept-Encoding: gzip, deflate, br\n" +
"Accept-Language: zh,zh-TW;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6\n" +
"Cookie: Webstorm-33fda740=2357c3d1-7421-48dd-b63d-9dfa59664905; Idea-d43876f9=54507cfb-5164-4924-84ad-1ddc6e24306e");
pw.println("\n\r");
pw.flush();
int b;
while ((b=inputStream.read())!=-1){
System.out.print(((char) b));
} }
}
写了一个client,注意必须是\n\r否则不行
打印的内容为
D:\dev\JDK8\bin\java.exe -javaagent:D:\dev\ideaIU-2020.3.1.win\lib\idea_rt.jar=58985:D:\dev\ideaIU-2020.3.1.win\bin -Dfile.encoding=UTF-8 -classpath D:\dev\JDK8\jre\lib\charsets.jar;D:\dev\JDK8\jre\lib\deploy.jar;D:\dev\JDK8\jre\lib\ext\access-bridge-64.jar;D:\dev\JDK8\jre\lib\ext\cldrdata.jar;D:\dev\JDK8\jre\lib\ext\dnsns.jar;D:\dev\JDK8\jre\lib\ext\jaccess.jar;D:\dev\JDK8\jre\lib\ext\jfxrt.jar;D:\dev\JDK8\jre\lib\ext\localedata.jar;D:\dev\JDK8\jre\lib\ext\nashorn.jar;D:\dev\JDK8\jre\lib\ext\sunec.jar;D:\dev\JDK8\jre\lib\ext\sunjce_provider.jar;D:\dev\JDK8\jre\lib\ext\sunmscapi.jar;D:\dev\JDK8\jre\lib\ext\sunpkcs11.jar;D:\dev\JDK8\jre\lib\ext\zipfs.jar;D:\dev\JDK8\jre\lib\javaws.jar;D:\dev\JDK8\jre\lib\jce.jar;D:\dev\JDK8\jre\lib\jfr.jar;D:\dev\JDK8\jre\lib\jfxswt.jar;D:\dev\JDK8\jre\lib\jsse.jar;D:\dev\JDK8\jre\lib\management-agent.jar;D:\dev\JDK8\jre\lib\plugin.jar;D:\dev\JDK8\jre\lib\resources.jar;D:\dev\JDK8\jre\lib\rt.jar;D:\wksp_study\designbook\target\classes;D:\repo\junit\junit\4.11\junit-4.11.jar;D:\repo\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;D:\repo\org\openjdk\jol\jol-core\0.10\jol-core-0.10.jar;D:\repo\javax\servlet\servlet-api\2.3\servlet-api-2.3.jar;D:\wksp_study\designbook\lib\jaas.jar;D:\wksp_study\designbook\lib\jnet.jar;D:\wksp_study\designbook\lib\jsse.jar;D:\wksp_study\designbook\lib\mx4j.jar;D:\wksp_study\designbook\lib\jcert.jar;D:\wksp_study\designbook\lib\servlet.jar;D:\wksp_study\designbook\lib\xercesImpl.jar;D:\wksp_study\designbook\lib\tomcat-util.jar;D:\wksp_study\designbook\lib\naming-common.jar;D:\wksp_study\designbook\lib\xmlParserAPIs.jar;D:\wksp_study\designbook\lib\commons-daemon.jar;D:\wksp_study\designbook\lib\naming-factory.jar;D:\wksp_study\designbook\lib\commons-logging.jar;D:\wksp_study\designbook\lib\commons-modeler.jar;D:\wksp_study\designbook\lib\commons-digester.jar;D:\wksp_study\designbook\lib\naming-resources.jar;D:\wksp_study\designbook\lib\commons-beanutils.jar;D:\wksp_study\designbook\lib\jakarta-regexp-1.2.jar;D:\wksp_study\designbook\lib\commons-collections.jar com.zyt.tomcat.ex03.startup.Client
Socket[addr=localhost/127.0.0.1,port=8080,localport=58988]
<html>
<head>
<title>Modern Servlet</title>
</head>
<body>
<h2>Headers</h2
<br>sec-fetch-mode : navigate
<br>sec-fetch-site : none
<br>accept-language : zh,zh-TW;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6
<br>cookie : Webstorm-33fda740=2357c3d1-7421-48dd-b63d-9dfa59664905; Idea-d43876f9=54507cfb-5164-4924-84ad-1ddc6e24306e
<br>sec-fetch-user : ?1
<br>accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
<br>sec-ch-ua : " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
<br>sec-ch-ua-mobile : ?0
<br>host : localhost:8080
<br>upgrade-insecure-requests : 1
<br>connection : keep-alive
<br>accept-encoding : gzip, deflate, br
<br>user-agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
<br>sec-fetch-dest : document
<br><h2>Method</h2
<br>GET
<br><h2>Parameters</h2
<br>password : 1234l
<br>userName : zhangyantao
HTTP/1.1 200 OK
Server: Pyrmont Servlet Container <br><h2>Query String</h2
<br>userName=zhangyantao&password=1234l
<br><h2>Request URI</h2
<br>/servlet/ModernServlet
</body>
</html> Process finished with exit code 0
发现发送了响应头,但是位置不对,进一步发现是他程序写错了
public void write(byte b[],int off,int len) throws IOException{
if (len==0) {
return;
}
if (len<=buffer.length-bufferCount) {
System.arraycopy(b,off,buffer,bufferCount,len);
bufferCount += len;
contentCount += len;
return;
}
flushBuffer(); /** 将buffercount置为0;清空buffer*/
int iterations= len/buffer.length; /**len太大 看一共有几倍 */
int leftoverStart=iterations*buffer.length;
int leftoverLen = len - leftoverStart;
for (int i = 0; i < iterations; i++) {
write(b, off + (i * buffer.length), buffer.length);
}
if(leftoverLen>0){
write(b, off + leftoverStart, leftoverLen);
}
}
缓存区大小
public class HttpResponse implements HttpServletResponse {
private static final int BUFFER_SIZE=1024;
protected byte[] buffer = new byte[BUFFER_SIZE];
}
如果缓存区满了 ,内容还没写完超过了1024个字节,他就发送了,那么就比响应头的发送提前了,之后才会执行sendheaders和发送后一部分内容
如果你设置 private static final int BUFFER_SIZE=4096;
那么你就获取了一个惊喜
D:\dev\JDK8\bin\java.exe -javaagent:D:\dev\ideaIU-2020.3.1.win\lib\idea_rt.jar=57838:D:\dev\ideaIU-2020.3.1.win\bin -Dfile.encoding=UTF-8 -classpath D:\dev\JDK8\jre\lib\charsets.jar;D:\dev\JDK8\jre\lib\deploy.jar;D:\dev\JDK8\jre\lib\ext\access-bridge-64.jar;D:\dev\JDK8\jre\lib\ext\cldrdata.jar;D:\dev\JDK8\jre\lib\ext\dnsns.jar;D:\dev\JDK8\jre\lib\ext\jaccess.jar;D:\dev\JDK8\jre\lib\ext\jfxrt.jar;D:\dev\JDK8\jre\lib\ext\localedata.jar;D:\dev\JDK8\jre\lib\ext\nashorn.jar;D:\dev\JDK8\jre\lib\ext\sunec.jar;D:\dev\JDK8\jre\lib\ext\sunjce_provider.jar;D:\dev\JDK8\jre\lib\ext\sunmscapi.jar;D:\dev\JDK8\jre\lib\ext\sunpkcs11.jar;D:\dev\JDK8\jre\lib\ext\zipfs.jar;D:\dev\JDK8\jre\lib\javaws.jar;D:\dev\JDK8\jre\lib\jce.jar;D:\dev\JDK8\jre\lib\jfr.jar;D:\dev\JDK8\jre\lib\jfxswt.jar;D:\dev\JDK8\jre\lib\jsse.jar;D:\dev\JDK8\jre\lib\management-agent.jar;D:\dev\JDK8\jre\lib\plugin.jar;D:\dev\JDK8\jre\lib\resources.jar;D:\dev\JDK8\jre\lib\rt.jar;D:\wksp_study\designbook\target\classes;D:\repo\junit\junit\4.11\junit-4.11.jar;D:\repo\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;D:\repo\org\openjdk\jol\jol-core\0.10\jol-core-0.10.jar;D:\repo\javax\servlet\servlet-api\2.3\servlet-api-2.3.jar;D:\wksp_study\designbook\lib\jaas.jar;D:\wksp_study\designbook\lib\jnet.jar;D:\wksp_study\designbook\lib\jsse.jar;D:\wksp_study\designbook\lib\mx4j.jar;D:\wksp_study\designbook\lib\jcert.jar;D:\wksp_study\designbook\lib\servlet.jar;D:\wksp_study\designbook\lib\xercesImpl.jar;D:\wksp_study\designbook\lib\tomcat-util.jar;D:\wksp_study\designbook\lib\naming-common.jar;D:\wksp_study\designbook\lib\xmlParserAPIs.jar;D:\wksp_study\designbook\lib\commons-daemon.jar;D:\wksp_study\designbook\lib\naming-factory.jar;D:\wksp_study\designbook\lib\commons-logging.jar;D:\wksp_study\designbook\lib\commons-modeler.jar;D:\wksp_study\designbook\lib\commons-digester.jar;D:\wksp_study\designbook\lib\naming-resources.jar;D:\wksp_study\designbook\lib\commons-beanutils.jar;D:\wksp_study\designbook\lib\jakarta-regexp-1.2.jar;D:\wksp_study\designbook\lib\commons-collections.jar com.zyt.tomcat.ex03.startup.Client
Socket[addr=localhost/127.0.0.1,port=8080,localport=57842]
HTTP/1.1 200 OK
Server: Pyrmont Servlet Container <html>
<head>
<title>Modern Servlet</title>
</head>
<body>
<h2>Headers</h2
<br>sec-fetch-mode : navigate
<br>sec-fetch-site : none
<br>accept-language : zh,zh-TW;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6
<br>cookie : Webstorm-33fda740=2357c3d1-7421-48dd-b63d-9dfa59664905; Idea-d43876f9=54507cfb-5164-4924-84ad-1ddc6e24306e
<br>sec-fetch-user : ?1
<br>accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
<br>sec-ch-ua : " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
<br>sec-ch-ua-mobile : ?0
<br>host : localhost:8080
<br>upgrade-insecure-requests : 1
<br>connection : keep-alive
<br>accept-encoding : gzip, deflate, br
<br>user-agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
<br>sec-fetch-dest : document
<br><h2>Method</h2
<br>GET
<br><h2>Parameters</h2
<br>password : 1234l
<br>userName : zhangyantao
<br><h2>Query String</h2
<br>userName=zhangyantao&password=1234l
<br><h2>Request URI</h2
<br>/servlet/ModernServlet
</body>
</html> Process finished with exit code 0
浏览器正常显示页面

这书,怎么好呢?解决一个问题太费劲了...一章一个问题,真是费劲呢...,
接下来分析长连接的实现吧,和短链接的区别
深入刨析tomcat 之---第2篇,解决第3章bug 页面不显示内容http://localhost:8080/servlet/ModernServlet?userName=zhangyantao&password=1234的更多相关文章
- 深入刨析tomcat 之---第1篇,解决第1,2章bug 页面不显示内容Hello. Roses are red.
writedby 张艳涛, 第一个问题是不显示index.html网页 19年才开始学java的第二个月,就开始第一遍看这本书,我估计当初,做第一章的一个案例,自己写代码,和验证就得一天吧,当初就发现 ...
- 深入刨析tomcat 之---第8篇 how tomcat works 第11章 11.9应用程序,自定义Filter,及注册
writed by 张艳涛, 标签:全网独一份, 自定义一个Filter 起因:在学习深入刨析tomcat的学习中,第11章,说了调用过滤链的原理,但没有给出实例来,自己经过分析,给出来了一个Filt ...
- 深入刨析tomcat 之---第21篇 tomcat 对jsp页面支持的实现原理
writedby 张艳涛 web技术,以前的动态网页技术多是jsp页面,比如点击一个菜单目录,直接访问了一个LRJSDetailInput.jsp页面,这个页面 有<html><bo ...
- 深入刨析tomcat 之---第15篇 对应20章, myAdmin案例代码
writedby 张艳涛 有没有和我一样做到第20章的?今天基本结束了本书的阅读.最后一个案例没有demo,那我写了一回,如果有需要的可以在本地试试 路径 D:\wksp_study\designbo ...
- 深入刨析tomcat 之---第14篇 对应19章,使用manager管理 web应用
writedby 张艳涛 第19章讲的是管理程序,当一个tomcat启动的时候,能通过远程浏览器能访问tomcat,启动web应用,关闭web应用,查看web应用 怎么实现的呢? 在webapp 文件 ...
- 深入刨析tomcat 之---第10篇 how tomcat works 第13章,Response 发送错误信息 sendError
writedby 张艳涛 在浏览器中发送一个错误应用url 那么tomcat是如何发送错误的呢? 基本上是发送http 的response协议,分为两部分一部分是response设置头信息, 那么先分 ...
- 深入刨析tomcat 之---第12篇 how tomcat works( 第17章 ) 解析catalina.bat 梳理启动流程
我们如何启动tomcat呢? 答案是双击startup.bat文件,这个文件在bin目录下 @echo off 不显示批处理命令 rem Licensed to the Apache Softw ...
- 深入刨析tomcat 之---第23篇 聊一下web容器的filter配置和defaultservet
writedby 张艳涛,在一个webapp应用程序内如何配置filter? <?xml version="1.0" encoding="ISO-8859-1&qu ...
- 深入刨析tomcat 之---第13篇 tomcat的三种部署方法
writedby 张艳涛 一般我们都知道将web 应用打成war包,放到tomcat的webapp目录下,就是部署了,这是部署方法1 第2种部署方法我们也知道,就是讲web应用的文件夹拷贝到webap ...
随机推荐
- csp-s模拟测试52-53
留坑.... 改完题再说吧. 留坑....最近考得什么鬼??模拟53T1 u(差分) 一道差分题????然而考场没有想到如何维护斜率上的差分,事后经miemeng和cyf的生(xuan)动(xue)讲 ...
- 【题解】[LuoguP3503]「BZOJ2086」[POI2010] Blocks
题目描述 给出N个正整数a[1..N],再给出一个正整数k,现在可以进行如下操作:每次选择一个大于k的正整数a[i],将a[i]减去1,选择a[i-1]或a[i+1]中的一个加上1.经过一定次数的操作 ...
- 【codeforces841A】Generous Kefa
原题 A. Generous Kefatime limit per test:2 secondsmemory limit per test:256 megabytes input:standard i ...
- NOIP模拟测试23「mine·water·gcd」
mine 题解 一道比较水的dp 考试因为初始化挂掉了只有$80$分 代码有注释 #include<bits/stdc++.h> using namespace std; //无脑dp # ...
- Golang超时机制--2秒内某个函数没被调用就认为超时
Golang超时机制--2秒内某个函数没被调用就认为超时 需求描述 当一整套流程需要其他程序来调用函数完成时通常需要一个超时机制,防止别人程序故障不调你函数导致你的程序流程卡死 实现demo pack ...
- 在 NUC980 上运行 RT-Thread
NUC980 & RT-Thread (1) NUC980 nuc980 是新塘推出的基于 ARM926EJ-S,集成 64 MB 或 128 MB DDR-II 的处理器,主频可以达到300 ...
- Fiber 树的构建
我们先来看一个简单的 demo: import * as React from 'react'; import * as ReactDOM from 'react-dom'; class App ex ...
- ES6 数组的方法
数组的类 数组的类是Array 数组的定义 var arr=[元素] var arr=new Array(3) 数字3,代表有三个元素或者三个空位 如果数组定义采用 new 实例,类中跟的是一个数字 ...
- C#调用JAVA(一)制作jar包
1 //AndroidJavaClass类可以理解为某一个类 2 //AndroidJavaObject类可以理解为某一个类中的一个对象 打开AS,创建一个空项目 输入项目名,包名,本地路径以及语言之 ...
- 关于 Index '8' specified is out of bounds.
报类似这样的错误暂时我只发现了两个原因: 1, 数组超出了界线,这个自己多多注意,加判断,在循环的时候看看是不是有结束条件 2, 你需要提交的网页不存在.有可能是因为你没有这个文件.可能是你的文件名错 ...