【问题标题】:Conversion and validation issue in Struts2Struts2 中的转换和验证问题
【发布时间】:2015-09-11 08:02:47
【问题描述】:

我从事 struts 工作很长时间了。

我正在使用 Struts 2 在应用程序中模拟程序验证和转换错误。

在我的应用程序中,我有一个名为 Product 的模型类,如下所示:

public class Product {

private String productId;
private String productName;
private int price;

public Product() {}

public Product(String productId, String productName, int price) {
    this.productId = productId;
    this.productName = productName;
    this.price = price;
}

public String getProductId() {
    return productId;
}

public void setProductId(String productId) {
    System.out.println("Product.setProductId() : '"+productId+"'");
    this.productId = productId;
    System.out.println("This.pid : "+this.productId);
}

public String getProductName() {
    return productName;
}

public void setProductName(String productName) {
    System.out.println("Product.setProductName() : '"+productName+"'");
    this.productName = productName;
}

public int getPrice() {
    return price;
}

public void setPrice(int price) {
    System.out.println("Product.setPrice() : '"+price+"'");
    this.price = price;
}

}

我有一个名为 ProductForm.jsp 的 jsp,我要求用户输入如下产品信息:

<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
    <title>Add Product Form</title>
    <style type="text/css">@import url(css/main.css);</style>
</head>
<body>
    <div id="global">
        <h3>Add a product</h3>
        <s:form method="post" action="Product_Save.action">
            <s:textfield label="Id" key="productId"/>
            <s:textfield label="Name" key="productName"/>
            <s:textfield label="Price" key="price"/>
            <s:submit value="Add Product"/>
        </s:form>
        <s:debug/>
    </div>
</body>
</html>

如果用户通过提供正确的信息点击Add Product按钮,数据将按照struts.xml中配置的正常流程保存到数据库,如下所示:

<!DOCTYPE struts PUBLIC 
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="product_module" extends="struts-default">

    <action name="Product_Input">
        <result>/jsp/ProductForm.jsp</result>
    </action>

    <action name="Product_Save" class="com.way2learnonline.ui.ProductAction">
        <result name="success">/jsp/ProductDetails.jsp</result>
        <result name="input">/jsp/ProductForm.jsp</result>
        <param name="test">MyTest</param>
    </action>

</package>

</struts>

我的Action类是ProductAction,如下图:

public class ProductAction extends ActionSupport implements ModelDriven<Product>{

private static final long serialVersionUID = 1L;

private Product product;

private String test;

public ProductAction() {}

public String execute(){
    DatabaseManager databaseManager=new DatabaseManager();
    databaseManager.write(product);
    return Action.SUCCESS;
}

@Override
public void validate() {

    System.out.println("p : "+product.getProductId());
    if(product.getProductId().trim().equals("")){
        addFieldError("productId", "Product Id should be present");
    }
    if(product.getPrice()<=0){
        addFieldError("price", getText("price.negative"));
    }
}

@Override
public Product getModel() {
    product=new Product();
    return product;
}

public void setTest(String test) {
    this.test = test;
}

public String getTest() {
    return test;
}
}

如果我们提供了无效数据,例如价格小于或等于零或 productId 为空,则将触发验证。

如果我们在价格字段中输入字母,则会触发转换错误。

但是,如果我在价格字段中输入字母,那么我的 product 对象在转到 validate() 方法时所有变量都将变为空值,这会在我尝试访问 productId 时导致 validate() 方法中出现空指针异常来自ProductAction 类的product 对象。

如果我在ProductForm.jspprice 字段中给出字母,为什么我的ProductAction 类的product 对象变量会变为空。

【问题讨论】:

  • 根据this,它不应该。这里一定发生了一些非常奇怪的事情。哪个S2版本?您可以尝试删除带参数的构造函数吗?好问题顺便说一句
  • @Aleksandr M 我无法理解您所说的“我怀疑这段代码在
    中有 action="Product_Save.action" 时完全可以工作”
  • 嗯,它似乎确实有效,但如果您使用 S2 标签,最好不要将扩展名 .action 添加到操作名称。
  • @ Aleksandr M
    没有问题,因为即使根据您进行了更改,同样的空指针异常也即将到来
  • @All 我在这里得到了问题的答案,事情是 Struts2 在转换错误之前和验证之前调用 getModel() 方法。在我的获取模型方法中,我每次都返回 new Product() 对象。所以我的数据被填充到 Product 对象中。然后 Struts2 在验证之前再次调用 getModel() 方法,我再次返回 new Product() ,因此验证发生在没有数据集的第二个产品对象上。感谢所有感谢您为我提供的宝贵时间。无论如何,祝你们好运。

标签: java validation struts2 struts-validation interceptorstack


【解决方案1】:

将模型初始化放在声明中,而不是在getter中:

private Product product = new Product();

@Override
public Product getModel() {
    return product;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-08
    • 1970-01-01
    • 2013-11-14
    • 1970-01-01
    相关资源
    最近更新 更多