I have been working on struts for a long time.
I am simulating programmatic validations and conversion errors in an application using Struts 2.
In my application I have a model class called Product which is as shown below:
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;
}
}
I have jsp called ProductForm.jsp
where I ask user to enter product info like below:
<%@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>
If user clicks on Add Product
button by giving correct info data will be saved to database according to normal flow which is configured in struts.xml
which is as below:
<!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>
My Action class is ProductAction
which is as shown below:
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;
}
}
If we give invalid data like price less than or equal to zero or productId is empty then validation will be triggered.
If we give alphabets in price field then conversion error will be triggered.
But If I give alphabets in price field then my product
object all variables are becoming nulls while it goes to validate()
method, which is resulting null pointer exception in validate()
method when I try to access productId
from product
object of ProductAction
class.
Here why is my product
object variables of ProductAction
class are becoming null if I give alphabets in price
field in ProductForm.jsp
.
Put the model initialization in the declaration, not in the getter:
private Product product = new Product();
@Override
public Product getModel() {
return product;
}