为什么 ModelDriven 在 Struts 2 中停止工作
Why ModelDriven has stopped working in Struts 2
我在 Action
class 中使用了 ModelDriven
,之前它工作正常,现在它停止工作了。
当我在 JSP 中使用 Struts 的 <s:debug>
标签时,我发现以下结果:
Struts ValueStack
调试:
我正在 JSP 页面中访问值:
<s:property value="categoryName"/>
<s:property value="categoryId"/> // I typed here
工作正常,如果我以 :
访问它们
<s:property value="category.categoryName"/>
<s:property value="category.categoryId"/>
我的问题是:
- 为什么我得到了 2 次属性?
- 如何避免它们多次出现?
- 我看到很多人建议避免
ModelDriven
,为什么?
更新:
实际上我得到了3次属性,我忘记强调第3次了。请看我的Action
class.
我的action中没有定义Model
class的单独属性,highlighted by 1,如何设置这些属性?
是任何东西,我在执行ModelDriven
时做错了吗?
这是我在 CategoryAction
中的模型:
public class CategoryAction extends ActionSupport implements ModelDriven<Category>,
Preparable, SessionAware, ServletRequestAware, ServletContextAware {
private static final long serialVersionUID = 1L;
private Category category;
private Category [] categories;
private ServletContext servletContext;
private Map<String, Object> session;
private ServletRequest request;
@Override
public Category getModel() {
return this.category;
}
@Override
public void prepare() throws Exception {
this.category = new Category();
if( this.jmain == null )
this.jmain = new Jmain();
}
public void prepareCrudCategory() throws Exception {
this.categoryService = new CategoryService();
}
@Override
public String execute() throws Exception {
System.out.println("----------CategoryAction#execute()-----------");
if( this.category.getCategoryId() == 0)
this.category = this.jmain.getCategory( 1 ); //Get Main Category
else
this.category = this.jmain.getCategory( this.category.getCategoryId() );
System.out.println(this.category.toString());
return super.execute();
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public Category[] getCategories() {
return categories;
}
public void setCategories(Category[] categories) {
this.categories = categories;
}
}
更新二:
这是我的 JSP 代码片段:
<form action="add-category" id="id-add-id-entry-form" name="addIdEntry" method="post">
<input type="hidden" id="opType" name="opType" value='<s:property value="opType"/>'>
<br /> <br />
<center>
<span id="id-message-span">
<s:if test="hasActionMessages()">
<h3 style="font-size: 22px; color: #FD0006; text-shadow: 2px 2px 3px rgba(255, 255, 255, 0.1); margin-left: 330px;">
<s:actionmessage />
</h3>
</s:if>
<s:if test="hasActionErrors()">
<h3 style="font-size: 16px; color: #FD0006; text-shadow: 2px 2px 3px rgba(255, 255, 255, 0.1); margin-left: 330px;">
<s:actionerror />
</h3>
</s:if>
</span>
<div id="id-id-entry-div" class="class-id-entry-div class-center">
<fieldset style="height: 100%; border-style: solid; border-width: 2px; border-color: #FEC458;"
>
<legend class="PageTitleUpperCase"> Add Category </legend>
<table cellspacing="5" cellpadding="2" border="0" width="65%" class="class-center">
<tr>
<td>
<span style="color: red">*</span>
<label class="Label_Green"> Patent Category Name :</label>
<s:if test=""></s:if>
</td>
<td>
<s:property value="opType"/><br>
<s:property value="categoryId"/>
<s:property value="categoryName"/>
<s:if test="%{opType == 0}">
<%-- <s:property value="categoryName"/> --%>
<input type="hidden" name="parentCategoryId" value='<s:property value="categoryId"/>' >
<label class="Label_Green">
<s:property value="categoryName"/>
</label>
</s:if>
<s:else>
<%-- <s:property value="parentCategoryName"/> --%>
<input type="hidden" name="parentCategoryId" value='<s:property value="parentCategoryId"/>' >
<label class="Label_Green">
<s:property value="parentCategoryName"/>
</label>
</s:else>
</td>
</tr>
<tr>
<td>
<span style="color: red">*</span>
<label class="Label_Green"> Category Name :</label>
<s:if test=""></s:if>
</td>
<td >
<input type="hidden" name="categoryId"
<s:if test="%{opType == 0}">value='0'</s:if>
<s:else>value='<s:property value="categoryId"/>'</s:else>
>
<input id="id-category-name-text" type="text" name="categoryName"
required="required" size="40" placeholder="Enter Category Name Here..."
<s:if test="%{opType == 1}">value='<s:property value="categoryName"/>'</s:if> >
</td>
</tr>
<tr>
<td></td>
<td align="left"><input type="submit" id="submit_img"
<s:if test="opType != 0"> value='Update'</s:if>
<s:else> value='Submit' </s:else> >
</td>
</tr>
</table>
</fieldset>
</div>
<s:debug/>
</center>
</form>
我如何使用调试标记获得 ValueStack
内容:
使用 <s:debug/>
后,我点击它得到 [debug]
link,显示以下值:
<s:debug/>
用于列表类别页面,[debug]
link 单击它,显示以下值:
modelDriven
interceptor 将模型推送到 ValueStack
的 top
,因此您在堆栈中同时拥有模型和动作。
ValueStack
是由 Struts 框架实现的接口,允许在处理请求时操作数据。你可以从 here.
中了解它是如何工作的
可以在ValueStack
的不同层级查找相同name/key的属性,查找顺序为从top
向下栈,直到找到值.
ModelDriven
操作简化了将表单字段映射到模型对象的过程,但是如果您需要对同一操作执行多个模型,您可能会遇到困难 class.
您可能在验证、类型转换以及 Struts 框架与拦截器一起使用的其他功能方面遇到困难。
如果您不能解决问题而不是从实现的接口中删除 ModelDriven
或重新配置拦截器堆栈以禁用 modelDriven
interceptor,那么您可以没有 ModelDriven
。
我在 Action
class 中使用了 ModelDriven
,之前它工作正常,现在它停止工作了。
当我在 JSP 中使用 Struts 的 <s:debug>
标签时,我发现以下结果:
Struts ValueStack
调试:
我正在 JSP 页面中访问值:
<s:property value="categoryName"/>
<s:property value="categoryId"/> // I typed here
工作正常,如果我以 :
访问它们<s:property value="category.categoryName"/>
<s:property value="category.categoryId"/>
我的问题是:
- 为什么我得到了 2 次属性?
- 如何避免它们多次出现?
- 我看到很多人建议避免
ModelDriven
,为什么?
更新:
实际上我得到了3次属性,我忘记强调第3次了。请看我的
Action
class.我的action中没有定义
Model
class的单独属性,highlighted by 1,如何设置这些属性?是任何东西,我在执行
ModelDriven
时做错了吗?
这是我在 CategoryAction
中的模型:
public class CategoryAction extends ActionSupport implements ModelDriven<Category>,
Preparable, SessionAware, ServletRequestAware, ServletContextAware {
private static final long serialVersionUID = 1L;
private Category category;
private Category [] categories;
private ServletContext servletContext;
private Map<String, Object> session;
private ServletRequest request;
@Override
public Category getModel() {
return this.category;
}
@Override
public void prepare() throws Exception {
this.category = new Category();
if( this.jmain == null )
this.jmain = new Jmain();
}
public void prepareCrudCategory() throws Exception {
this.categoryService = new CategoryService();
}
@Override
public String execute() throws Exception {
System.out.println("----------CategoryAction#execute()-----------");
if( this.category.getCategoryId() == 0)
this.category = this.jmain.getCategory( 1 ); //Get Main Category
else
this.category = this.jmain.getCategory( this.category.getCategoryId() );
System.out.println(this.category.toString());
return super.execute();
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public Category[] getCategories() {
return categories;
}
public void setCategories(Category[] categories) {
this.categories = categories;
}
}
更新二:
这是我的 JSP 代码片段:
<form action="add-category" id="id-add-id-entry-form" name="addIdEntry" method="post">
<input type="hidden" id="opType" name="opType" value='<s:property value="opType"/>'>
<br /> <br />
<center>
<span id="id-message-span">
<s:if test="hasActionMessages()">
<h3 style="font-size: 22px; color: #FD0006; text-shadow: 2px 2px 3px rgba(255, 255, 255, 0.1); margin-left: 330px;">
<s:actionmessage />
</h3>
</s:if>
<s:if test="hasActionErrors()">
<h3 style="font-size: 16px; color: #FD0006; text-shadow: 2px 2px 3px rgba(255, 255, 255, 0.1); margin-left: 330px;">
<s:actionerror />
</h3>
</s:if>
</span>
<div id="id-id-entry-div" class="class-id-entry-div class-center">
<fieldset style="height: 100%; border-style: solid; border-width: 2px; border-color: #FEC458;"
>
<legend class="PageTitleUpperCase"> Add Category </legend>
<table cellspacing="5" cellpadding="2" border="0" width="65%" class="class-center">
<tr>
<td>
<span style="color: red">*</span>
<label class="Label_Green"> Patent Category Name :</label>
<s:if test=""></s:if>
</td>
<td>
<s:property value="opType"/><br>
<s:property value="categoryId"/>
<s:property value="categoryName"/>
<s:if test="%{opType == 0}">
<%-- <s:property value="categoryName"/> --%>
<input type="hidden" name="parentCategoryId" value='<s:property value="categoryId"/>' >
<label class="Label_Green">
<s:property value="categoryName"/>
</label>
</s:if>
<s:else>
<%-- <s:property value="parentCategoryName"/> --%>
<input type="hidden" name="parentCategoryId" value='<s:property value="parentCategoryId"/>' >
<label class="Label_Green">
<s:property value="parentCategoryName"/>
</label>
</s:else>
</td>
</tr>
<tr>
<td>
<span style="color: red">*</span>
<label class="Label_Green"> Category Name :</label>
<s:if test=""></s:if>
</td>
<td >
<input type="hidden" name="categoryId"
<s:if test="%{opType == 0}">value='0'</s:if>
<s:else>value='<s:property value="categoryId"/>'</s:else>
>
<input id="id-category-name-text" type="text" name="categoryName"
required="required" size="40" placeholder="Enter Category Name Here..."
<s:if test="%{opType == 1}">value='<s:property value="categoryName"/>'</s:if> >
</td>
</tr>
<tr>
<td></td>
<td align="left"><input type="submit" id="submit_img"
<s:if test="opType != 0"> value='Update'</s:if>
<s:else> value='Submit' </s:else> >
</td>
</tr>
</table>
</fieldset>
</div>
<s:debug/>
</center>
</form>
我如何使用调试标记获得 ValueStack
内容:
使用 <s:debug/>
后,我点击它得到 [debug]
link,显示以下值:
<s:debug/>
用于列表类别页面,[debug]
link 单击它,显示以下值:
modelDriven
interceptor 将模型推送到 ValueStack
的 top
,因此您在堆栈中同时拥有模型和动作。
ValueStack
是由 Struts 框架实现的接口,允许在处理请求时操作数据。你可以从 here.
可以在ValueStack
的不同层级查找相同name/key的属性,查找顺序为从top
向下栈,直到找到值.
ModelDriven
操作简化了将表单字段映射到模型对象的过程,但是如果您需要对同一操作执行多个模型,您可能会遇到困难 class.
您可能在验证、类型转换以及 Struts 框架与拦截器一起使用的其他功能方面遇到困难。
如果您不能解决问题而不是从实现的接口中删除 ModelDriven
或重新配置拦截器堆栈以禁用 modelDriven
interceptor,那么您可以没有 ModelDriven
。