第1章 Hello World
Hello World
先按照正常方式新建一个 Tomcat Web 应用程序StrutsDemo1(可以用Lomboz之类的工具来创建,不过我不会用它。其实只要用Eclipse新建一个普通的Java Project,并指定 .class 文件的输出路径为StrutsDemo1/WEB-INF/classes/即可。其他的细节可参见我的其它文章)。
然后就是按照Struts的规定进行一些例行公事的配置。这里有一个小窍门:打开“Tomcat Web Application Manager”页面,在页面的最下部有一个“WAR file to deploy”,点击“浏览...”按钮,打开“C:/JavaSoft/Struts/jakarta-struts-1.2.4/webapps/struts-blank.war”,再按“Deploy”按钮,struts-blank Web应用就会被部署到“C:/JavaSoft/Tomcat 5.5/webapps/struts-blank/”。顾名思义,这是一个最简单的Struts应用,但是对于我来说,它还是过于复杂了,所以我的Hello World对它进行了一些简化。具体的细节请看下图:
犯错误
下面我们将每次一个地犯一些错误,以此来观察Struts的行为。
· 打开上一节创建的工程 StrutsDemo1 中的 hello.jsp,把<%@ taglib uri="/tags/struts-bean" prefix="bean" %> 改为<%@ taglib uri="AAA/tags/struts-bean" prefix="bean" %>,结果会抛出异常:“org.apache.jasper.JasperException: File "/AAA/tags/struts-bean" not found”。不过 "/tags/struts-bean" 并不是一个真正的文件喔,这个错误提示有一定的误导性。
· 打开上一节创建的工程 StrutsDemo1 中的 hello.jsp,把
猜想:由于标记的特殊位置,IE浏览器会自动忽略一些错误。
· 打开上一节创建的工程 StrutsDemo1 中的 hello.jsp,把
猜想:为什么会这样就只有问设计IE的程序员了。
· 打开上一节创建的工程 StrutsDemo1 中的 hello.jsp,把
猜想:1. 前缀(prefix="bean")区分大小写。2. Tomcat 会忽略含有未定义前缀的标记。
· 打开上一节创建的工程 StrutsDemo1 中的 hello.jsp,把
· 打开上一节创建的工程 StrutsDemo1 中的 hello.jsp,把
· 把“C:/JavaSoft/Eclipse/workspace/StrutsDemo1/WEB-INF/lib/commons-beanutils.jar”更名为“commons-beanutils.jar.bak”。再访问“http://127.0.0.1:9111/strutsDemo1/hello.jsp”,结果抛出异常:
org.apache.jasper.JasperException
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:245)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
通过这个错误信息无法看出是因为缺少“commons-beanutils.jar”而抛出异常
· 先停掉 Tomcat,然后把“C:/JavaSoft/Eclipse/workspace/StrutsDemo1/WEB-INF/lib/struts.jar”更名为“struts.jar.bak”。启动 Tomcat,访问 hello.jsp,会抛出异常“javax.servlet.ServletException: org.apache.struts.taglib.html.HtmlTag”和“java.lang.NoClassDefFoundError: org.apache.struts.taglib.html.HtmlTag”。同样是看不出因为缺少struts.jar而造成的。
· 先停掉 Tomcat,然后把“C:/JavaSoft/Eclipse/workspace/StrutsDemo1/WEB-INF/lib/commons-collections.jar”更名为“commons-collections.jar.bak”。启动 Tomcat,访问 hello.jsp,页面显示正常。
· 打开上一节创建的工程 StrutsDemo1 中的 WEB-INF/web.xml,把
改为
重起StrutsDemo1 应用,再访问hello.jsp,会抛出异常
org.apache.jasper.JasperException
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:373)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:245)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
· 打开上一节创建的工程 StrutsDemo1 中的 WEB-INF/web.xml,把
改为
重起StrutsDemo1 应用,再访问hello.jsp,结果页面居然能正常显示。
再改为
重起StrutsDemo1 应用,再访问hello.jsp,结果页面还是能正常显示。
再把“C:/JavaSoft/Tomcat 5.5/webapps/struts-blank/WEB-INF/struts-config.xml”重命名为“AAAstruts-config.xml”,页面还是能正常显示。
猜想:真是莫名其妙,难道Tomcat能智能搜索配置文件?
· 打开上一节创建的工程 StrutsDemo1 中的 WEB-INF/struts-config.xml,把
改为
/>
重起StrutsDemo1 应用,会抛出异常
org.apache.jasper.JasperException
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:373
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:245)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
猜想:不能把注释放到标记的里面。
· 打开上一节创建的工程 StrutsDemo1 中的 WEB-INF/web.xml,把
改为
重起StrutsDemo1 应用,会发现 StrutsDemo1 应用无法启动。 访问hello.jsp,会出现如下错误信息:
type Status report
message /strutsDemo1/hello.jsp
description The requested resource (/strutsDemo1/hello.jsp) is not available.
猜想:虽然hello.jsp没有用到Action,可是action节还是要有的呀。
小结:大家都注意到了吧,有时光凭异常信息是很难定位错误的。这里有一个小窍门:可以用IE来帮助我们检查web.xml和struts-config.xml之中的错误。以struts-config.xml为例,用记事本打开struts-config.xml,可以看到
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">
表示此xml文件的文档类型定义(Document Type Definition)文件为http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd,我们可以访问这个网址下载struts-config_1_2.dtd文件,并把它复制到“WEB-INF/”。然后把struts-config.xml改为:
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"./struts-config_1_2.dtd">
然后就可以右击struts-config.xml,打开方式选IE,这样IE就会根据struts-config_1_2.dtd对struts-config.xml的内容进行验证了。