现在在做一个新的项目,开始用传说中的struts2.0。由于用惯了struts1了,所以改用2的时候有点
不适应。
我在jsp页面中生成下拉列表的时候,程序一直报错,提示是由于list为空的原因。可是我明明在Action
初始化值了。
在struts1中,struts可以根据类似<s:form action="nextapply" method="post">的自动根据action="nextapply"
然后通过struts-config.xml中的匹配路径,找到一个与之对应的ActionForm,并构造ActionForm。
然而struts2中没有了ActionForm,所以我们通过一个jsp的路径,如: [url]http://localhost:8080/pics/app/appinfo.jsp[/url]
就会报错。list是放到了Action中,此时我们访问的时候Action还没有被构造,也就没有所谓的Action里的list
(类似这样的路径: [url]http://localhost:8080/pics/app/nextapply.action[/url]就不会有上面的错误,因为这样的访问
会去构造Action)。
由于有上面的原因,我在jsp页面中用了<s:action name="apply" id="apply" />
这个标签会声明一个Action并构造。解决了上面的问题。
================================================================================
另一个问题:
Action代码:
---------------------------------------------------------
/*
* @(#)AppAction.java
*
* 系统名称:
* 版本号:
*
* Copyright (c) vansky.cn
* All right reserved.
*
* 作者: majie
* 创建日期: 2007-11-7
*
* 功能描述:
* 公用方法描述:
*
* 修改人:
* 修改日期:
* 修改原因:
*
*/
package com.vansky.pics.web.struts.app;
import com.vansky.framework.web.BaseAction;
import java.util.*;
import com.vansky.pics.domain.app.AppInfo;
import com.vansky.pics.domain.sys.Dictionaries;
import com.vansky.pics.service.app.IAppService;
/**
* @author majie
*
*/
public class AppAction extends BaseAction<AppInfo,IAppService>{
private AppInfo appInfo;
private List credentialTypeList = new ArrayList();
private String credential;
/**
* @return the appInfo
*/
public AppInfo getAppInfo() {
return appInfo;
}
/**
* @param appInfo the appInfo to set
*/
public void setAppInfo(AppInfo appInfo) {
this.appInfo = appInfo;
}
/**
* @return the credentialTypeList
*/
public List getCredentialTypeList() {
System.out.println("=============================init====================================");
Dictionaries dic1 = new Dictionaries();
dic1.setName("身份证");
dic1.setValue("shenfenzheng");
credentialTypeList.add(dic1);
Dictionaries dic2 = new Dictionaries();
dic2.setName("警官证");
dic2.setValue("jingguanzheng");
credentialTypeList.add(dic2);
Dictionaries dic3 = new Dictionaries();
dic3.setName("其他");
dic3.setValue("qita");
credentialTypeList.add(dic3);
System.out.println(credentialTypeList.size());
return credentialTypeList;
}
/**
* @param credentialTypeList the credentialTypeList to set
*/
public void setCredentialTypeList(List credentialTypeList) {
this.credentialTypeList = credentialTypeList;
}
public AppAction(){
System.out.println("Action");
}
public String upward(){
return "upward";
}
public String next(){
return "next";
}
public String execute(){
return SUCCESS;
}
@Override
protected Class getEntityClass() {
return AppInfo.class;
}
/**
* @return the credential
*/
public String getCredential() {
return credential;
}
/**
* @param credential the credential to set
*/
public void setCredential(String credential) {
this.credential = credential;
}
}
-------------------------------------------------------
appinfo.jsp页面:
------------------------------------------------------
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head></head>
<body>
<s:action name="apply" id="apply" />
<s:form action="nextapply" method="post">
<s:textfield label="中文姓名" name="appInfo.mainInfo.chinaName" />
<s:textfield label="拼音" name="appInfo.mainInfo.charName" />
<s:select list="#apply.credentialTypeList" listKey="value" listValue="name" name="credential"/>
<s:textfield label="其他请注明" name="appInfo.mainInfo.other" />
<s:textfield label="证件号码" name="appInfo.mainInfo.credentialNumber"/>
<s:submit value="下一步" />
</s:form>
</body>
</html>
---------------------------------------------------------
next.jsp页面:
---------------------------------------------------------
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head></head>
<body>
<s:form action="upwardapply" method="post">
<s:textfield label="中文姓名" name="appInfo.mainInfo.chinaName" />
<s:textfield label="拼音" name="appInfo.mainInfo.charName" />
<s:select list="credentialTypeList" listKey="value" listValue="name" name="credential"/>
<s:submit value="上一步"/>
</s:form>
</body>
</html>
------------------------------------------------------------------
struts.xml:
-------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!--
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation/DTD Struts Configuration 2.0//EN"
" [url]http://struts.apache.org/dtds/struts-2.0.dtd[/url]">
-->
<!DOCTYPE struts SYSTEM "struts-2.0.dtd">
<struts>
<!--
<constant name="struts.objectFactory" value="spring"></constant>
-->
<package name="user" extends="struts-default">
<action name="initLogin" class="com.vansky.framework.web.user.LoginAction" method="init">
<result>/WEB-INF/jsp/user/login.jsp</result>
</action>
<action name="login" class="com.vansky.framework.web.user.LoginAction">
<result>/WEB-INF/jsp/user/index.jsp</result>
</action>
<action name="captcha" class="com.vansky.framework.web.user.LoginAction" method="captcha"/>
</package>
<package name="appInfo" extends="struts-default">
<action name="*apply" class="com.vansky.pics.web.struts.app.AppAction" method="{1}">
<result name="next">/app/next.jsp</result>
<result name="upward">/app/appinfo.jsp</result>
</action>
</package>
</struts>
---------------------------------------------------------------------
问题:
当在第一次进入appinfo.jsp中的时候,下拉列表显示正确。下一步,到next.jsp的时候也正确,
但是在next.jsp中点上一步的时候,返回appinfo.jsp时下拉列表的list出现了两个身份证,警官证
,其他。再点下一步到next.jsp还是正确的list。
------------------------------------------------------
首先,由于struts2.0的Action其实每次都会重新构造,主要是为了线程的安全。即使我们把Action声明放到
Session中,也仅仅是把我们需要传递的参数Session了,Action没有Session。
我们从next.jsp中上一步到appinfo.jsp的时候,因为有
<s:action name="apply" id="apply" />
<s:form action="nextapply" method="post">
这两条语句,Action会被构造2次,但2次构造的都是同一个对象。
在<s:select list="#apply.credentialTypeList" listKey="value" listValue="name" name="credential"/>的时候
会被<s:action name="apply" id="apply" />构造的Action调用一次,
虽然,<s:select list="#apply.credentialTypeList" listKey="value" listValue="name" name="credential"/>里的
list="#apply.credentialTypeList" 指的是<s:action name="apply" id="apply" />构造的Action
但是由于<s:form action="nextapply" method="post">和<s:action name="apply" id="apply" />
构造的是同一个对象,所以<s:select list="#apply.credentialTypeList" listKey="value" listValue="name" name="credential"/>
会被再次调用,也就有了list里的重复的元素。
---------------------------------------------------------------
声明:本篇文章仅仅是个人学习的一个笔记,可能存在个人的一些误解,写的也很罗嗦。