HTTP Request Maps

Introduction

HTTP Request Maps is a framework/utility that provides a structured way to map HTTP Request parameters to Java Beans and get Java Beans and/or Java Bean Collections . It supports the population of

  1. Simple Http request parameters to bean's properties
  2. Simple Http request parameters to bean's nested properties
  3. Indexed Http request parameters to a collection of beans
  4. Indexed Http request parameters to a collection of beans conditionally

Benefits/Advantages

Setting up Request Maps

  1. Download Request Maps Binary Distribution
  2. Copy http-request-maps.jar file to WEB-INF/lib. (Since, Request Maps uses Log4j, you will have to include log4j in WEB-INF/lib)
  3. Create a Request map config file (ex: http-request-maps.xml) and place it in WEB-INF
  4. Configure Request Map Filter in web.xml and set the config parameter to reference Request Map config file

How it works

HTTP Request Maps transforms Http Request Parameters to Java Beans based on the HTTP Request Parameters-to-Java Bean mapping defined in the Request Map configuration file. The transformation can be done at different stages in Request-Response life cycle. HTTP Request Maps implements this transformation when the request arrives to the web container and before it is handed over to the respective servlet or a framework's servlet. HTTP Request Maps utilises Java Servlet Technology's Filter mechanism to intercept and transform the request data.

Configuring Request Map Filter

HTTP Request Maps Filter is configured in web.xml as follows
<filter>
 <filter-name>requestMapFilter</filter-name>
 <filter-class>com.mrkuchipudi.requestmaps.processor.RequestMapFilter</filter-class>
 <init-param>
  <param-name>config</param-name>
  <param-value>/WEB-INF/request-maps.xml</param-value>
 </init-param>
</filter>
<filter-mapping>
 <filter-name>requestMapFilter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>
  
The config parameter specifies the location of Request Map file.

Configuring Request Maps

The request maps are configured in Request Map configuration file. Here is the skeleton of Request Map Configuration file.
<?xml version="1.0" encoding="UTF-8"?>
 <request-maps>
  <map id=" ">
  <map id=" ">
  </map>
 </request-maps>
		 
Request map processor finds the request map based on an unique id. The id is the uri of the request. The uri starts with </.../remaining path info>
There are four types of request maps.They are:
  1. Simple Request Map
  2. Nested Request Map
  3. Collection Request Map
  4. Conditional Collection Request Map
1.Simple Request Map
Simple Request map specifies how to map simple http parameters to simple bean properties based on html parameter name vis-a-vis bean property.
Structure:
<map id="/hrmexamples/simpleBeanAction">
   <bean id="billInfo"
   type="com.mrkuchipudi.requestmaps.examples.BillInfo"/>
</map>
   	     
Http form:
<form name="billForm" method="POST" action="simpleBeanAction">
 Bill Date : <input type="textbox" name="billDate" value="01/12/2005">
 Bill Amount : <input type="textbox" name="billAmount" value="60.00">
 <input type="submit" value="Submit">
 <input type="submit" value="Reset">
</form>
    
Billinfo.java:
public class BillInfo {

	private String billDate;
	private Double billAmount;
	/**
	 * @return Returns the billDate.
	 */
	public String getBillDate() {
		return billDate;
	}
	/**
	 * @param billDate The billDate to set.
	 */
	public void setBillDate(String billDate) {
		this.billDate = billDate;
	}
	/**
	 * @return Returns the billAmount.
	 */
	public Double getBillAmount() {
		return billAmount;
	}
	/**
	 * @param billAmount The billAmount to set.
	 */
	public void setBillAmount(Double billAmount) {
		this.billAmount = billAmount;
	}
}
Here the Request Map processor searches for a match of the id which is billInfo. Then it populates the http form's parameters namely billDate and billAmount by using billInfo bean's properties billDate and billAmount,which is a simple one-to-one mapping
2.Nested Request Map
Nested Request map specifies how to map http parameters to nested bean properties ie a bean which contains other beans as properties.
Structure:
<map id="/hrmexamples/nestedBeanAction">
   <bean id="billInfo"
   <type="com.mrkuchipudi.requestmaps.examples.BillInfo"/>
   <bean id="billInfo.billId"
   <type="com.mrkuchipudi.requestmaps.examples.BillId"/>
</map>
          
Html form
<form name="billForm" method="POST" action="nestedBeanAction">
 Bill Date : <input type="textbox" name="billDate" value="01/12/2005">
 Bill Amount : <input type="textbox" name="billAmount" value="23.56">
 Bill # : <input type="textbox" name="billNumber" value="3">
 <input type="submit" value="Submit">
 <input type="submit" value="Reset">
</form>
    
BillInfo.java:
  public class BillInfo {

	private BillId billId;
	private String billDate;
	private Double billAmount;
	
	
	/**
	 * @return Returns the billDate.
	 */
	public String getBillDate() {
		return billDate;
	}
	/**
	 * @param billDate The billDate to set.
	 */
	public void setBillDate(String billDate) {
		this.billDate = billDate;
	}

	/**
	 * @return Returns the billId.
	 */
	public BillId getBillId() {
		return billId;
	}
	/**
	 * @param billId The billId to set.
	 */
	public void setBillId(BillId billId) {
		this.billId = billId;
	}
	/**
	 * @return Returns the billAmount.
	 */
	public Double getBillAmount() {
		return billAmount;
	}
	/**
	 * @param billAmount The billAmount to set.
	 */
	public void setBillAmount(Double billAmount) {
		this.billAmount = billAmount;
	}
}
   
BillId.java:

public class BillId {

	private Long billNumber;
	/**
	 * @return Returns the billNumber.
	 */
	public Long getBillNumber() {
		return billNumber;
	}
	/**
	 * @param billNumber The billNumber to set.
	 */
	public void setBillNumber(Long billNumber) {
		this.billNumber = billNumber;
	}
}
   
In the above example, the bean BillInfo contains a property billId of type BillId. To populate the properties in BillId we use Nested Request Map.
3.Collection Request Map
Collection Request map specifies how to map indexed request parameters to a collection of beans.
The structure of Collection Request Map is as follows:
  
<map id="/hrmexamples/beanCollectionAction">
  <bean id="billInfo"
  type="com.mrkuchipudi.requestmaps.examples.BillInfo"/>   	
  <bean id="billInfo.billItems" mode="LIST"
  type="com.mrkuchipudi.requestmaps.examples.BillItemInfo"
  params="itemId,itemName,quantity,amount"
  fields="itemId,itemName,quantity,amount"/>
</map>
Html form:
  
<form name="billForm" method="POST" action="beanCollectionAction">
 Bill Date : <input type="textbox" name="billDate" value="test">
 Bill Amount : <input type="textbox" name="billAmount" value="23.56">
 Bill # : <input type="textbox" name="billNumber" value="3">
     	
 <input type="textbox" name="itemId" value="1"><input type="textbox" name="itemName" value="coke">&l;tinput type="textbox" name="quantity" value="23232"><input type="textbox" name="amount" value="23232.33">
 <input type="textbox" name="itemId" value="2"><input type="textbox" name="itemName" value="pepsi"><input type="textbox" name="quantity" value="1212"><input type="textbox" name="amount" value="23232.23">
 <input type="submit" value="Submit">
 <input type="submit" value="Reset">
 </form>
   	
BillInfo.java:
  
 public class BillInfo {

	private BillId billId;
	private String billDate;
	private Collection billItems;
	private Double billAmount;
	
	
	/**
	 * @return Returns the billDate.
	 */
	public String getBillDate() {
		return billDate;
	}
	/**
	 * @param billDate The billDate to set.
	 */
	public void setBillDate(String billDate) {
		this.billDate = billDate;
	}

	/**
	 * @return Returns the billId.
	 */
	public BillId getBillId() {
		return billId;
	}
	/**
	 * @param billId The billId to set.
	 */
	public void setBillId(BillId billId) {
		this.billId = billId;
	}
	/**
	 * @return Returns the billItems.
	 */
	public Collection getBillItems() {
		return billItems;
	}
	/**
	 * @param billItems The billItems to set.
	 */
	public void setBillItems(Collection billItems) {
		this.billItems = billItems;
	}
	/**
	 * @return Returns the billAmount.
	 */
BillItemInfo.java:
  

public class BillItemInfo {

	private String itemId;
	private String itemName;
	private Double quantity;
	private Double amount;
	/**
	 * @return Returns the itemId.
	 */
	public String getItemId() {
		return itemId;
	}
	/**
	 * @param itemId The itemId to set.
	 */
	public void setItemId(String itemId) {
		this.itemId = itemId;
	}
	/**
	 * @return Returns the itemName.
	 */
	public String getItemName() {
		return itemName;
	}
	/**
	 * @param itemName The itemName to set.
	 */
	public void setItemName(String itemName) {
		this.itemName = itemName;
	}
	/**
	 * @return Returns the amount.
	 */
	public Double getAmount() {
		return amount;
	}
	/**
	 * @param amount The amount to set.
	 */
	public void setAmount(Double amount) {
		this.amount = amount;
	}
	/**
	 * @return Returns the quantity.
	 */
	public Double getQuantity() {
		return quantity;
	}
	/**
	 * @param quantity The quantity to set.
	 */
	public void setQuantity(Double quantity) {
		this.quantity = quantity;
	}
}
	
Web container creates string array (indexed from 0 to n) whenever it finds multiple values for the same form element name. In the above example, Web container creates arrays (indexed from 0 to 1) for input form elements itemId, itemName, quantity, amount. Http Request Maps creates a bean for elements at each index.

Important Note: All the properties defined in the map must have the same index. For example, HTTP Request Maps returns null if there are 3 itemId text boxes and 2 itemName textboxes.
4.Conditional Collection Request Map
Collection Conditional Request map specifies how to map a set of Http request parameters to a collection of beans conditionally.
The structure of a Conditional Collection Request Map is as follows
  
<map id="/hrmexamples/beanCollectionConditionalAction">
 <bean id="billInfo"
 type="com.mrkuchipudi.requestmaps.examples.BillInfo"/>
 <bean id="billInfo.billItems" mode="LIST"                    
 type="com.mrkuchipudi.requestmaps.examples.BillItemInfo"
 params="quantity,amount"
 fields="quantity,amount"
 paramsOptional="itemId,itemName"
 fieldsOptional="itemId,itemName"/>
</map>
	   

Html Form:

  
<form name="billForm" method="POST" action="beanCollectionAction">
 Bill Date : <input type="textbox" name="billDate" value="test">
 Bill Amount : <input type="textbox" name="billAmount" value="23.56">
 Bill # : <input type="textbox" name="billNumber" value="3">
     	
 <input type="textbox" name="itemId" value="1"><input type="textbox" name="itemName" value="coke">&l;tinput type="textbox" name="quantity" value="23232"><input type="textbox" name="amount" value="23232.33">
 <input type="textbox" name="itemId" value="2"><input type="textbox" name="itemName" value="pepsi"><input type="textbox" name="quantity" value="1212"><input type="textbox" name="amount" value="23232.23">
 <input type="submit" value="Submit">
 <input type="submit" value="Reset">
 </form>
   	
BillInfo.java:
  
 public class BillInfo {

	private BillId billId;
	private String billDate;
	private Collection billItems;
	private Double billAmount;
	
	
	/**
	 * @return Returns the billDate.
	 */
	public String getBillDate() {
		return billDate;
	}
	/**
	 * @param billDate The billDate to set.
	 */
	public void setBillDate(String billDate) {
		this.billDate = billDate;
	}

	/**
	 * @return Returns the billId.
	 */
	public BillId getBillId() {
		return billId;
	}
	/**
	 * @param billId The billId to set.
	 */
	public void setBillId(BillId billId) {
		this.billId = billId;
	}
	/**
	 * @return Returns the billItems.
	 */
	public Collection getBillItems() {
		return billItems;
	}
	/**
	 * @param billItems The billItems to set.
	 */
	public void setBillItems(Collection billItems) {
		this.billItems = billItems;
	}
	/**
	 * @return Returns the billAmount.
	 */
BillItemInfo.java:
  

public class BillItemInfo {

	private String itemId;
	private String itemName;
	private Double quantity;
	private Double amount;
	/**
	 * @return Returns the itemId.
	 */
	public String getItemId() {
		return itemId;
	}
	/**
	 * @param itemId The itemId to set.
	 */
	public void setItemId(String itemId) {
		this.itemId = itemId;
	}
	/**
	 * @return Returns the itemName.
	 */
	public String getItemName() {
		return itemName;
	}
	/**
	 * @param itemName The itemName to set.
	 */
	public void setItemName(String itemName) {
		this.itemName = itemName;
	}
	/**
	 * @return Returns the amount.
	 */
	public Double getAmount() {
		return amount;
	}
	/**
	 * @param amount The amount to set.
	 */
	public void setAmount(Double amount) {
		this.amount = amount;
	}
	/**
	 * @return Returns the quantity.
	 */
	public Double getQuantity() {
		return quantity;
	}
	/**
	 * @param quantity The quantity to set.
	 */
	public void setQuantity(Double quantity) {
		this.quantity = quantity;
	}
}
	
The above example is same as Collection Request Map except the fact that it creates the bean only when all the required fields have values.