我照书上写了一个关于将英文网页翻译为简单pig latin文网页的例子,程序结构很简单,一个简单的jsp,和一个被jsp调用的java类,以下是代码:
translate.jsp
<%@page import = "ly.Translate" %>
<% if (request.getParameter("url") == null) 
{%>
<html>
<head>
<title>Translate</title>
</head>
<body>
<h1>Translate to Pig Latin</h1>
<form method = "get">
Select a URL ro translate to Pig Latin: <input type = text name = url value = "http://www.yahoo.com/" size = "50">
<input type = "submit" value = "Translate">
</form>
</body>
</html>
<%
}
else
{
try
{
String str = Translate.translate(request.getParameter("url"),"translate.jsp?url=");
out.println(str);
}
catch (Exception e)
{
out.println("Error: " + e);
}
}
%>
Translate.java
package ly;import java.util.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import com.heaton.bot.*;public class Translate extends HTMLEditorKit.ParserCallback { protected String _buffer = "";
protected String _base;
protected String _reflect;

Translate(String t,String reflect)
{
_base = t;
_reflect = reflect;
}

public String getBuffer()
{
return _buffer;
}

public void handleComment(char[] data,int pos)
{
_buffer += "<!--";
_buffer += new String(data);
_buffer += " -->";
}

protected void attributes(AttributeSet attributes)
{
Enumeration e = attributes.getAttributeNames();
while (e.hasMoreElements())
{
Object name = e.nextElement();
String value = (String)attributes.getAttribute(name);

if (name == HTML.Attribute.HREF)
value = _reflect + URLUtility.resolveBase(_base,value);
else
if (name == HTML.Attribute.SRC ||
name == HTML.Attribute.LOWSRC)
value = URLUtility.resolveBase(_base, value);
_buffer += " " + name + "=\"" + value + "\" ";
}
}

public void handleStartTag(HTML.Tag t, MutableAttributeSet a,int pos)
{
_buffer += "<" + t;
attributes(a);
if (t == HTML.Tag.APPLET && a.getAttribute(HTML.Attribute.CODEBASE) == null)
{
String codebase = _base;
if (codebase.toUpperCase().endsWith(".HTM") ||
codebase.toUpperCase().endsWith(".HTML"))
codebase = codebase.substring(0,codebase.lastIndexOf('/'));
}
_buffer += ">";
}

public void handleEndTag(HTML.Tag t, int pos)
{
_buffer += "</" + t + ">";
}

public void handleSimpleTag(HTML.Tag t,MutableAttributeSet a,int pos)
{
if ((t.toString()).startsWith("__"))
return;
_buffer += "<";
if (a.getAttribute(HTML.Attribute.ENDTAG) != null)
_buffer += "/" + t;
else
{
_buffer += t;
attributes(a);
}
_buffer += ">";
}

public void handleText(char[] data ,int pos)
{
_buffer += pigLatin(new String(data));
}

protected String pigLatin(String english)
{
String pigWord;
String pigLatin;
String temp;
int mode;
StringTokenizer englishWords = new StringTokenizer(english);
pigLatin = "";

while (englishWords.hasMoreTokens())
{
temp = new String (englishWords.nextToken());
if ((temp.charAt(0) >= 'A' && temp.charAt(0) <= 'Z') &&
(temp.charAt(1) >= 'A' && temp.charAt(1) <= 'Z'))
mode = 2;
else if ((temp.charAt(0) >= 'A' && temp.charAt(0) <= 'Z') &&
(temp.charAt(1) >= 'a' && temp.charAt(1) <= 'z'))
mode = 1;
else
mode = 0;

if (temp.length() > 1)
{
String start = new String(firstVowel(temp));
pigWord = new String(start + "ay");
}
else
pigWord = temp + "ay";
if (pigWord.trim().length() > 0)
{
if (pigLatin.length() > 0)
pigLatin += " ";
switch (mode)
{
case 0:
pigLatin += pigWord.toLowerCase();
break;
case 1:
pigLatin += pigWord.substring(0,1).toUpperCase();
pigLatin += pigWord.substring(1).toLowerCase();
break;
case 2:
pigLatin += pigWord.toUpperCase();
break;
}
}
}
return pigLatin;
}

protected String firstVowel(String s)
{
String consonants = new String();
String remain = new String();
String newWord = "";
int letterIndex = 0;

while (letterIndex < s.length())
{
if ((s.charAt(letterIndex) != 'a') &&
(s.charAt(letterIndex) != 'A') &&
(s.charAt(letterIndex) != 'e') &&
(s.charAt(letterIndex) != 'E') &&
(s.charAt(letterIndex) != 'i') &&
(s.charAt(letterIndex) != 'I') &&
(s.charAt(letterIndex) != 'o') &&
(s.charAt(letterIndex) != 'O') &&
(s.charAt(letterIndex) != 'u') &&
(s.charAt(letterIndex) != 'U')  )
{
consonants += s.substring(letterIndex,(letterIndex + 1));
letterIndex++;
}
else
{
remain += s.substring(letterIndex,s.length());
letterIndex = s.length();
}
}
if (consonants != "")
{
newWord = remain + consonants;
}
else
{
newWord = remain;
}
return newWord;
}

public static String translate(String url,String callback) 
throws java.io.IOException,javax.swing.text.BadLocationException
{
Translate trans = new Translate(url,callback);
HTMLPage page = new HTMLPage(new HTTPSocket());
page.open(url, trans);
return trans.getBuffer();
}
}假设translate.jsp同目录下有ly目录,ly下有Translate.java,编译通过,运行时会出现Error: java.lang.ClassCastException: java.lang.Boolean
令我百思不得其解的是我没有尝试去对Boolean型对象作类型转换啊,怎么会出现这个错误呢?  请指教

解决方案 »

  1.   

    Translate 类里面的条件语句很多,建议对每个函数进行测试!
      

  2.   

    log有一大堆的数据,我怎样才能找到由我的项目所引发的错误或异常的数据呢?
      

  3.   

    wildnesswolf  你说的测试是指用junit测试吗,我现在还不会啊
      

  4.   

    我用printStackTrace()方法,获得它出错的栈的数据了
    java.lang.ClassCastException: java.lang.Boolean
    at ly.Translate.attributes(Translate.java:38)
    at ly.Translate.handleStartTag(Translate.java:53)
    at javax.swing.text.html.parser.DocumentParser.handleStartTag(DocumentParser.java:140)
    at javax.swing.text.html.parser.Parser.startTag(Parser.java:417)
    at javax.swing.text.html.parser.Parser.legalElementContext(Parser.java:512)
    at javax.swing.text.html.parser.Parser.errorContext(Parser.java:731)
    at javax.swing.text.html.parser.Parser.parse(Parser.java:2118)
    at javax.swing.text.html.parser.DocumentParser.parse(DocumentParser.java:105)
    at javax.swing.text.html.parser.ParserDelegator.parse(ParserDelegator.java:73)
    at com.heaton.bot.HTMLPage.processPage(HTMLPage.java:95)
    at com.heaton.bot.HTMLPage.open(HTMLPage.java:76)
    at ly.Translate.translate(Translate.java:184)
    at org.apache.jsp.translate_jsp._jspService(translate_jsp.java:66)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:94)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:324)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
    at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
    at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
    at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
    at java.lang.Thread.run(Thread.java:595)
      

  5.   

    (translate_jsp.java:66)你找找这句指的是什么
      

  6.   

    回nanjg,translate_jsp.java我不知道是什么文件,但其他出错代码行如下:
    at ly.Translate.attributes(Translate.java:38)->  String value = (String)attributes.getAttribute(name);
    at ly.Translate.handleStartTag(Translate.java:53) ->attributes(a);  handleStartTag方法里面的
    at ly.Translate.translate(Translate.java:184) ->page.open(url, trans);  translate方法里面的我觉得第一条是主要原因,我查了一下javadoc,对于ClassCastException有这样一个例子
    Object x = new Integer(0);
    System.out.println((String)x);
    这时会抛出ClassCastException这是由于Object向其子类String转型时,转为一个没有实例的子类对象,也就是(String)x对象,然后我改了一下Object x = new Integer(0);
    String str = (String)x;
    System.out.println(str);
    这个时候有子类实例对象了吧,可是还是错,为什么?弄懂这个问题我就能解决上面的这个了,另外这个小例子中错误提示是java.lang.Integer,那上面那个我想应该是java.lang.String才对,怎么会是java.lang.Boolean呢?是不是name == HTML.Attribute.HREF的问题?
      

  7.   

    你主要调试一下,下面这段代码?看是不是问题。    protected void attributes(AttributeSet attributes)
        {
            Enumeration e = attributes.getAttributeNames();
            while (e.hasMoreElements())
            {
                Object name = e.nextElement();
                String value = (String)attributes.getAttribute(name);
                
                if (name == HTML.Attribute.HREF)
                    value = _reflect + URLUtility.resolveBase(_base,value);
                else
                    if (name == HTML.Attribute.SRC ||
                            name == HTML.Attribute.LOWSRC)
                        value = URLUtility.resolveBase(_base, value);
                _buffer += " " + name + "=\"" + value + "\" ";
            }
        }
    at ly.Translate.attributes(Translate.java:38) 38行有问题。
      

  8.   

    主要在String value = (String)attributes.getAttribute(name);
    父类对象要转为子类的对象,而子类对象value又没有实例化(我是这么想的)造成的错误,所以我改为
    String value = new String(attributes.getAttribute(name).toString());就没有ClassCastException了,但再运行又抛出javax.swing.text.ChangedCharSetException
    at javax.swing.text.html.parser.DocumentParser.handleEmptyTag(DocumentParser.java:172)
    at javax.swing.text.html.parser.Parser.startTag(Parser.java:409)
    at javax.swing.text.html.parser.Parser.parseTag(Parser.java:1905)
    at javax.swing.text.html.parser.Parser.parseContent(Parser.java:1940)
    at javax.swing.text.html.parser.Parser.parse(Parser.java:2107)
    at javax.swing.text.html.parser.DocumentParser.parse(DocumentParser.java:105)
    at javax.swing.text.html.parser.ParserDelegator.parse(ParserDelegator.java:73)
    at com.heaton.bot.HTMLPage.processPage(HTMLPage.java:95)
    at com.heaton.bot.HTMLPage.open(HTMLPage.java:76)
    at ly.Translate.translate(Translate.java:184)
            at org.apache.jsp.translate_jsp._jspService(translate_jsp.java:66)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:94)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:324)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
    at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
    at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
    at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
    at java.lang.Thread.run(Thread.java:595)问题出在Translate.java:184 page.open(url, trans); 然后找HTMLPage类open方法原型:
      public void open(String url,
                       HTMLEditorKit.ParserCallback callback)
      throws IOException,BadLocationException
      {
        http.send(url,null);
       base = url;
        processPage(callback);  //问题在这 HTMLPage.java:76
      }
    然后再看HTMLPage类的processPage方法原型:  protected void processPage(HTMLEditorKit.ParserCallback callback)
      throws IOException
      {
        StringReader r = new StringReader(http.getBody());
        HTMLEditorKit.Parser parse = new HTMLParse().getParser();    if ( callback==null ) {
          HTMLPage.Parser p=new HTMLPage.Parser();
          parse.parse(r,p,true);
        } else
          parse.parse(r,callback,false);    //问题在这 HTMLPage.java:95  }
    同样再追溯到HTMLEditorKit.Parser的parse方法,原型:
    public abstract void parse(Reader r, ParserCallback cb, boolean ignoreCharSet) throws IOException;
    抽象函数!!!我就不明白那javax.swing.text.html.HTMLEditorKit.Parser怎么处理HTML数据的。