学习struts2建bbs总结七:extends ActionSupport带来的ClassNotFoundException异常

3 篇文章 0 订阅
3 篇文章 0 订阅

这个问题可说是这次学习遇到的最怪异的问题了,一直在网上询问了一周多直到现在均未得到答案,大概和高手缘分不深。哈哈。

这时我感觉写总结对于学习是很有帮助的,自从写写这些学习总结,回顾的时候,我竟慢慢的发现了很多原来未曾发现的问题,并且都渐渐解决了。例如之前的prototype模式,jquery,等等。趁着有时间,就及时的写出来,一则和遇到类似问题的朋友共享,二则避免自己以后犯同样错误。

事情是这样的:我在编写程序的过程中,一些action我是这样写的:如

public class PostAction implements Action......

也就是说,我实现的是action接口,直到bbs项目结束,那时刚把那个分页的死机问题解决,我测试了整个bbs运行,是可以正常运行的。只是我无意间看到一些说起baseAction的文章,我自己之前的总结也写了,所以我新建了baseAction类,如下:

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionSupport;

public class BaseAction extends ActionSupport implements ServletRequestAware,SessionAware {

	protected HttpServletRequest request;	
	protected Map<String, Object> session;
	
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}
	public void setSession(Map<String, Object> session) {
		this.session = session;
	}

	
}

这个类的目的就是生成session以及request,好处就是避免每个action甚至每个方法都要写上这句

Map session=ActionContext.getContext().getSession();

所以,我就把程序中的action,统统修改为extends BaseAction,但自从修改了这句后,程序遇到postAction发帖操作就报异常,我改为extends ActionSupport也是同样报错,如下:

post.jsp主要代码:

<FORM name="postForm" onSubmit="return check()" action="post.action?page=1" method="POST"> 
	        <INPUT id="a2" type="hidden" name="boardName" value="${fn:substring(bName,0,20)}"/>
		<INPUT id="a3" type="hidden" name="boardId" value=<%= session.getAttribute("boardId")%>/>	
		<DIV class="t">
				<TABLE cellSpacing="0" cellPadding="0" align="center">
				    <TR>
					    <TD class="h" colSpan="3"><B>发表帖子</B></TD>
				    </TR>
	
				    <TR class="tr3">
					    <TH width="20%"><B>标题</B></TH>
					    <TH><INPUT class="input" style="PADDING-LEFT: 2px; FONT: 14px Tahoma" tabIndex="1" size="60" name="title"></TH>
				    </TR>
	
				    <TR class="tr3">
					    <TH vAlign=top>
					      <DIV><B>内容</B></DIV>
					    </TH>
					    <TH colSpan=2>
					        <DIV>	
						        <span><textarea style="WIDTH: 500px;" name="detail" rows="20" cols="90" tabIndex="2" ></textarea></span>
						    </DIV>
					      (不能大于:<FONT color="blue">1000</FONT>字)
					    </TH>
					</TR>
				</TABLE>
			</DIV>		
	
			<DIV style="MARGIN: 15px 0px; TEXT-ALIGN: center">
				<INPUT class="btn" tabIndex="3" type="submit" value="提 交"> 
				<INPUT class="btn" tabIndex="4" type="reset"  value="重 置">
			</DIV>
			<s:token/>
		</FORM>	


异常详细:

java.lang.RuntimeException: Invalid action class configuration that references an unknown class named [postAction]
    org.apache.struts2.convention.ConventionsServiceImpl.determineResultPath(ConventionsServiceImpl.java:100)
    org.apache.struts2.convention.ConventionUnknownHandler.determinePath(ConventionUnknownHandler.java:385)
    org.apache.struts2.convention.ConventionUnknownHandler.handleUnknownResult(ConventionUnknownHandler.java:274)
    com.opensymphony.xwork2.DefaultUnknownHandlerManager.handleUnknownResult(DefaultUnknownHandlerManager.java:87)
    com.opensymphony.xwork2.DefaultActionInvocation.createResult(DefaultActionInvocation.java:226)
    com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:367)
。。。。。。
root cause

java.lang.ClassNotFoundException: postAction
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1680)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1526)
    org.apache.struts2.util.ClassLoaderUtils.loadClass(ClassLoaderUtils.java:111)
    org.apache.struts2.convention.ConventionsServiceImpl.determineResultPath(ConventionsServiceImpl.java:98)
    org.apache.struts2.convention.ConventionUnknownHandler.determinePath(ConventionUnknownHandler.java:385)
    org.apache.struts2.convention.ConventionUnknownHandler.handleUnknownResult(ConventionUnknownHandler.java:274)
    com.opensymphony.xwork2.DefaultUnknownHandlerManager.handleUnknownResult(DefaultUnknownHandlerManager.java:87)
    com.opensymphony.xwork2.DefaultActionInvocation.createResult(DefaultActionInvocation.java:226)
    com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.ja

提示找不到类,一般遇到这个异常,都会认为是spring的配置类名写错了或者路径写错了,在网上很多人也说应该是这样的原因。但在这里显示不可能是这种原因。

因为当我实现action接口,即implements Action的时候可以正常运行,则说明肯定不是配置文件的问题,要不然implements Action的时候就要报错的。事实上是implements Action的时候正常运行。

这个问题困扰我很久,我在网上查了许许多多有关Action以及ActionSupport的区别,几乎异口同声只是说,action只是一个接口,而actionSupport实现了Action接口,并且还提供了许多方法比如效验等,都建议直接继承ActionSupport。似乎ActionSupport可以无条件的取代Action接口。我看到这些文章,自然是解决不了我遇到的问题。

后来,我先不管什么异常,既然继承了ActionSupport,那 配置一下PostAction-post-validation.xml吧,因为post.jsp只有个标题和正文变量,xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.3//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd"> 
<validators>
        <field name="title">
            <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message>不能为空!</message>
        </field-validator>
        <field-validator type="stringlength">
            <param name="trim">true</param>
           	<param name="maxLength">20</param>
			<param name="minLength">4</param>
			<message>要在4--20位!</message>
        </field-validator>
    </field>
    
        <field name="detail">
       <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message>不能为空!</message>
        </field-validator>
        <field-validator type="stringlength">
            <param name="trim">true</param>
           	<param name="maxLength">1000</param>
			<param name="minLength">4</param>
			<message>要在4--1000!</message>
        </field-validator>
    </field>          
</validators>

然后我在strust.xml文件中,定义 了<result name="input">/error.jsp</result>,其中error.jsp加上:<s:fielderror/><s:actionerror/>

因为ActionSupport实现了ValidationAware接口,可以获得或设置字段错误信息、动作错误信息以及动作消息。其中,hasActionErrors方法判断是否存在动作层的错误,getFieldErrors获得字段错误信息(一个Map 对象)。

我的猜测(注意是猜测,我并没有深入研究):如果某个action继承了ActionSupport,则ActionSupport里的方法自然会对相应的jsp文件进行一些字段检测什么的,如果jsp有问题,则上面的hasActionErrors或getFieldErrors则会返回true,这时根据struts.xml返回“input”定义的视图页面。

例如,我上面在post.jsp中点击发帖按钮,程序便应该执行postAction,但执行之前会经过拦截器,以及ActionSupport中的校验(我在这里的测试结果显示,当点击发帖按钮,执行顺序是:过滤器---->拦截器--->ActionSupport的效验,其中过滤器web.xml的位置和url-pattern的路径设置有讲究,如果过滤器放在struts之后,结果大不一样,但拦截器-->ActionSupport校验这个顺序没变),如果定义了效验xml文件以及“input”对应的jsp文件,如这时我在实际测试过程发现页面调转到了error.jsp。如下:

当时我看到这个界面真是太兴奋太高兴了。终于知道程序的问题在哪里。我于是找到post.jsp文件,找到有关boardId字段的信息,发现下面这句

<INPUT id="a3" type="hidden" name="boardId" value=<%= session.getAttribute("boardId")%>/>属性值写错了,action中“session.put("BOARD_ID", boardId);

所以这句代码修改为:

<INPUT id="a3" type="hidden" name="boardId" value=<%= session.getAttribute("BOARD_ID")%>/>


再次运行,终于一切正常了!!看来,<s:fielderror/><s:actionerror/>用处真大呀。由此看出,继承ActionSupport还有个好处,就是它会帮你坚持jsp中每个字段属性,是否有效,如上面的截图,当遇到无效字段时,就直接转入input,不再执行action,从而报出找不到类的异常。而实现Action接口,则不会对jsp文件进行字段检测,所以虽然我的jsp有错误的时候,也一样可以进入action执行。

其实对jsp的相关知识自己也需要加强,例如这次出现的许多多此一举的事情。其中我需要在jsp中截取一个字符串,需要字符串的前20个字符就好,为了这个,我居然用了一段js代码截取,如下:

function SetString(str,len)
 {
  var strlen = 0; 
  var s = "";
  for(var i = 0;i < str.length;i++)
  {
   if(str.charCodeAt(i) > 128){
    strlen += 2;
   }else{ 
    strlen++;
   }
   s += str.charAt(i);
   if(strlen >= len){ 
    return s ;
   }
  }
 return s;
 } 

<script>				 
		document.write(SetString("<%=session.getAttribute("BOARD_NAME").toString().trim()%>",20));
		</script> 

写了这2段代码来实现,可是后来学习了jsp标签,真笑话自己啊。上面的代码在jsp文件其实只需要2句即可,如下:

<c:set var="bName" value="${session.BOARD_NAME}"/>
${fn:substring(bName,0,20)} 
当然需要引用

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>

不过这里我还得提出一个问题,如果上面我用struts2的标签函数substring截取字符串,遇到中文的时候我这里是无法截取的,当时显示的页面上,遇到中文字符串就是空白,英文字符串就可以正常截取。不知道是出了什么问题,这些留待以后研究了。


到这里,这次的总结算是写完了,感觉写学习总结学习到的似乎不比写程序学习到的少。希望各位朋友也多写总结,利人利己,呵呵。


  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Struts2项目需要按照以下步骤进行: 1. 创Maven项目 在命令行中执行以下命令,创一个Maven项目: ``` mvn archetype:generate -DgroupId=com.example -DartifactId=my-struts2-app -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false ``` 其中,`-DgroupId`表示项目的groupId,`-DartifactId`表示项目的artifactId,`-DarchetypeArtifactId`表示使用的模板,这里使用的是maven-archetype-webapp。 2. 添加Struts2依赖 在`pom.xml`文件中添加Struts2依赖: ```xml <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.5.26</version> </dependency> ``` 3. 创Struts2配置文件 在`src/main/resources`目录下创`struts.xml`文件,配置Struts2的基本信息,例如: ```xml <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <package name="default" extends="struts-default"> <action name="hello" class="com.example.MyAction"> <result>/index.jsp</result> </action> </package> </struts> ``` 4. 创Struts2 Action 在`src/main/java`目录下创一个Java类,例如`MyAction.java`,作为Struts2Action,例如: ```java package com.example; import com.opensymphony.xwork2.ActionSupport; public class MyAction extends ActionSupport { private String message; public String execute() { message = "Hello, Struts2!"; return SUCCESS; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } ``` 5. 创JSP页面 在`src/main/webapp`目录下创一个JSP页面,例如`index.jsp`,用于显示Action的返回结果: ```html <html> <head> <title>Struts2 Example</title> </head> <body> <h1>${message}</h1> </body> </html> ``` 6. 运行项目 使用以下命令在Tomcat中运行项目: ``` mvn tomcat7:run ``` 然后在浏览器中访问`http://localhost:8080/my-struts2-app/hello`即可看到页面上显示的内容"Hello, Struts2!"。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值