第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,把 <html:html locale="true"> 改为 <HTML:html locale="true">。访问“http://127.0.0.1:9111/strutsDemo1/hello.jsp”,将抛出异常“org.apache.jasper.JasperException: /hello.jsp(12,0) The end tag "</html:html" is unbalanced”。既然是 “unbalanced”,那么让我们把最后一行</html:html> 改为 </HTML:html>,结果页面显示正常。如果把它们改为<aaa:html> 和 <aaa:html> 的话页面也会正常显示。
猜想:由于<html></html>标记的特殊位置,IE浏览器会自动忽略一些错误。
· 打开上一节创建的工程 StrutsDemo1 中的 hello.jsp,把 <html:html locale="true"> 改为 <HTML:html locale="true">。访问“http://127.0.0.1:9111/strutsDemo1/hello.jsp”,将抛出异常“org.apache.jasper.JasperException: /hello.jsp(12,0) The end tag "</html:html" is unbalanced”。这时静待几秒钟,按一下IE的刷新按钮,就会显示正常;再静待几秒钟,按一下IE的刷新按钮,又会抛出异常;再刷新又正常;再刷又异常...如此往复。
猜想:为什么会这样就只有问设计IE的程序员了。
· 打开上一节创建的工程 StrutsDemo1 中的 hello.jsp,把<bean:message key="index.jsp.abc" /> 改为 <BEAN:message key="index.jsp.abc" />,结果“Hello!”没有显示出来。而且也没有抛出异常。页面为空白。
猜想:1. 前缀(prefix="bean")区分大小写。2. Tomcat 会忽略含有未定义前缀的标记。
· 打开上一节创建的工程 StrutsDemo1 中的 hello.jsp,把<bean:message key="index.jsp.abc" /> 改为 <bean:message key="index.jsp.abc" >,结果会抛出异常:“org.apache.jasper.JasperException: /hello.jsp(10,5) According to TLD, tag bean:message must be empty, but is not”。这个错误信息有一定的误导性。
· 打开上一节创建的工程 StrutsDemo1 中的 hello.jsp,把<bean:message key="index.jsp.abc" /> 改为 <bean:message key="Index.jsp.abc" />,结果会抛出异常:“javax.servlet.ServletException: Missing message for key "Index.jsp.abc”。
· 把“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,把
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
改为
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/AAAstruts-config.xml</param-value>
</init-param>
重起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,把
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
改为
<init-param>
<param-name>AAAconfig</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
重起StrutsDemo1 应用,再访问hello.jsp,结果页面居然能正常显示。
再改为
<init-param>
<param-name>AAAconfig</param-name>
<param-value>/WEB-INF/AAAstruts-config.xml</param-value>
</init-param>
重起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,把
<message-resources parameter="resource.app-args"/>
改为
<message-resources parameter="resource.app-args" <!-- a comment -->
/>
重起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,把
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
改为
<servlet-mapping>
<servlet-name>AAAaction</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
重起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,可以看到
<!DOCTYPE struts-config PUBLIC
"-//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改为:
<!DOCTYPE struts-config PUBLIC
"-//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的内容进行验证了。