Concept of Struts Token :
Struts has 3 methods use for the token, saveToken(), isTokenValid() and resetToken().
saveToken() - generate the token key and save to request/session attribute.
isTokenValid() - validate submitted token key against the 1 store in request/session.
resetToken() - reset the token key
Example :
Step 1.
Action Class where saveToken() before JSP Page.
First saveToken() then forward to your jsp.
Upon loading the form, invokes saveToken() on the action class to create and store the token key. Struts will store the generated key in request/session.
public class LoadAction extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)
{ ActionForward forward;
forward=mapping.findForward("FirstPage");// this is the jsp page where you want to struts tokens.
saveToken(request);
return forward;
}
}
Step 2.
If the token successfully created, when view source on the browser you will see the token, the token key is stored as a hidden field:
In jsp page :
<%@ page import="org.apache.struts.action.Action"%>
<%@ page import="org.apache.struts.taglib.html.Constants"%>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<html>
<head> <title> First Page </title> </head>
<body>
<form name="MyForm" method="post" action="/dpsubm/getForm/submit.do">
<input type="text" name="name" >
<input type="hidden" name="<%= Constants.TOKEN_KEY %>"
value="<%= session.getAttribute(Action.TRANSACTION_TOKEN_KEY) %>" >
<input type="submit" value="submit">
</form>
</body>
</html>
Step 3. Your logic
Once the form submitted, invokes isTokenValid() on the action class, it will validate the submitted token key(hidden field) with the token key stored previously on request/session. If match, it will return true.
public class SubmitAction extends Action
{
public ActionForward execute(ActionMapping mapping ,ActionForm form ,HttpServletRequest request,HttpServletResponse response)
{
ActionForward forward=mapping.findForward("submitForm");
DupSubmitForm frm=(DupSubmitForm)form;
if(isTokenValid(request))
{
System.out.println("frm.getName()"+frm.getName());
resetToken(request);
}
else
{
System.out.println("frm.getName()"+frm.getName());
System.out.println("Duplicate Submission of the form");
}
return forward;
}
}
---------------------------------------------------------------------------------
Duplicate form submissions are acceptable in some cases. Such scenarios are called idempotent transitions. When multiple submissions of data are not critical enough to impact the behavior of the application, duplicate form submissions do not pose a threat.
They can cause a lot of grief if for instance you are buying from an online store and accidentally press refresh on the page where you are charged. If storefront is smart enough, it will recognize duplicate submissions and handle it graciously without charging you twice.
Duplicate form submissions can occur in many ways
Using Refresh button
Using the browser back button to traverse back and resubmit form
Using Browser history feature and re-submit form.
Malicious submissions to adversely impact the server or personal gains
Clicking more than once on a transaction that take longer than usual
Why is the form submitted again after all, when the refresh button is pressed? The answer lies in the URL seen in the URL bar of your browser after the form submission. Consider a form as: <form name=CustomerForm” action=”/App1/submitCustomerForm.do”>. The above form is submitted with the URL /App1/submitCustomerForm.do and the same URL is shown in the URL bar. On the back end, Struts selects the action mapping associated with submitCustomerForm and executes the action instance. When you press refresh, the same URL is submitted and the same action instance is executed again. The easy solution to this problem is to use HTTP redirect after the form submission. Suppose that the CustomerForm submission results in showing a page called Success.jsp. When HTTP redirect is used, the URL in the URL bar becomes /App1/Success.jsp instead of /App1/submitCustomerForm.do. When the page refreshed, it is the Success.jsp that is loaded again instead of /App1/submitCustomerForm.do. Hence the form is not submitted again. To use the HTTP redirect feature, the forward is set as follows:
<forward name=”success” path=”/Success.jsp” redirect=”true” />
However there is one catch. With the above setting, the actual JSP name is shown in the URL. Whenever the JSP name appears in the URL bar, it is a candidate for ForwardAction. Hence change the above forward to be as follows:
<forward name=”success” path=”/GotoSuccess.do” redirect=”true” />
where GotoSuccess.do is another action mapping using ForwardAction as follows:
<action path=”/GotoSuccess”
type=”org.apache.struts.actions.ForwardAction”
parameter=”/Success.jsp”
validate=”false” />
Now, you have now addressed the duplicate submission due to accidental refreshing by the customer. It does not prevent you from intentionally going back in the browser history and submitting the form again. Malicious users might attempt this if the form submissions benefit them or adversely impact the server.
Struts provides you with the next level of defense: Synchronizer Token. To understand how the Synchronizer Token works, some background about built-in functionalities in the Action class is required. The Action class has a method called saveToken() whose logic is as follows:
HttpSession session = request.getSession();
String token = generateToken(request);
if (token != null) {
session.setAttribute(Globals.TRANSACTION_TOKEN_KEY, token);
}
The method generates a random token using session id, current time and a MessageDigest and stores it in the session using a key name org.apache.struts.action.TOKEN (This is the value of the static variable TRANSACTION_TOKEN_KEY in org.apache.struts.Globals class.
The Action class that renders the form invokes the saveToken() method to create a session attribute with the above name. In the JSP, you have to use the token as a hidden form field as follows:
<input type="hidden"
name="<%=org.apache.struts.taglib.html.Constants.TOKEN_KEY%>"
value="<bean:write name="<%=Globals.TRANSACTION_TOKEN_KEY%>"/>">
The embedded <bean:write> tag shown above, looks for a bean named org.apache.struts.action.TOKEN (which is the the value of Globals. TRANSACTION_TOKEN_KEY ) in session scope and renders its value as the value attribute of the hidden input variable. The name of the hidden input variable is org.apache.struts.taglib.html.TOKEN (This is nothing but the value of the static variable TOKEN_KEY in the class org.apache.struts.taglib.html.Constants).
When the client submits the form, the hidden field is also submitted. In the Action that handles the form submission (which most likely is different from the Action that rendered the form), the token in the form submission is compared with the token in the session by using the isTokenValid() method. The method compares the two tokens and returns a true if both are same. Be sure to pass reset=”true” in the isTokenValid() method to clear the token from session after comparison. If the two tokens are equal, the form was submitted for the first time. However, if the two tokens do not match or if there is no token in the session, then it is a duplicate submission and handle it in the manner
acceptable to your users.
NOTE: We could also have chosen to have the synchronizer token as an ActionForm attribute. In that case, the <html:hidden> tag could have been used instead of the above <input type=”hidden”> tag (which looks complicated at the first sight). However we have not chosen to go down this path since protection from duplicate submission is not a characteristic of the form and it does not logically fit there very well.
Although the above approach is good, it requires you as a application developer to add the token checking method pair – saveToken() and isTokenValid() in methods rendering and submitting the sensitive forms respectively. Since the two tasks are generally performed by two different Actions, you have to identify the pairs and add them manually. You can use the same approach for sensitive hyperlink navigations. Just set the tranaction attribute in <html:link> to true and use the same logic in the Action classes to track the duplicate hyperlink navigations.
The reset argument of the isTokenValid() is useful for multi-page form scenario. Consider a form that spans across multiple pages. The form is submitted every time the user traverses from one page to another. You definitely want to validate token on every page submission. However you also want to allow the user to traverse back and forth using the browser back button until the point of final submission. If the token is reset on every page submission, the possibility of back and forth traversal using the browser button is ruled out. The solution is not disabling back button (using JavaScript hacks) but to handle the token intelligently. This is where the reset argument is useful. The token is initially set before showing the first page of the form. The reset argument is
false for all the isTokenValid() invocations except in the Action for the last page. The last page uses a true value for the reset argument and hence the token is reset in the isTokenValid() method. From this point onwards you cannot use back button to traverse to the earlier form pages and successfully submit the form.
shabarishTutorial
Friday 11 January 2013
How to avoid duplicate submitions in struts
Thursday 15 December 2011
Example of volatile keyword in Java:
To Understand example of volatile keyword in java let’s go back to Singleton pattern in Java and see double checked locking in Singleton with Volatile and without volatile keyword in java.
public class Singleton{
private static volatile Singleton _instance;
public static Singleton getInstance(){
if(_instance == null){
synchronized(Singleton.class){
if(_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
If you look at the code carefully you will be able to figure out:
1) We are only creating instance one time
2) We are creating instance lazily at the time of first request comes.
If we do not make _instance variable volatile then Thread which is creating instance of Singleton is not able to communicate other thread, that instance has been created until it comes out of the Singleton block, so if Thread A is creating Singleton instance and just after creation lost the CPU, all other thread will not be able to see value of _instance as not null and they will believe its still null.
Why because reader threads are not doing any locking and until writer thread comes out of synchronized block, memory will not be synchronized and value of _instance will not be updated in main memory. With Volatile keyword in Java this is handled by Java himself and such updates will be visible by all reader threads.
So in Summary apart from synchronized keyword in java, volatile keyword is also used to communicate content of memory between threads.
Let’s see another example of volatile keyword in Java:
most of the time while writing game we use a variable bExist to check whether user has pressed exit button or not, value of this variable is updated in event thread and checked in game thread , So if we don't use volatile keyword with this variable , Game Thread might miss update from event handler thread if its not synchronized in java already. volatile keyword in java guarantees that value of volatile variable will always be read from main memory and "happens-before" relationship in Java Memory model will ensure that content of memory will be communicated to different threads.
boolean bExit;
while(!bExit) {
checkUserPosition();
updateUserPosition();
}
In this code example One Thread (Game Thread) can cache the value of "bExit" instead of getting it from main memory every time and if in between any other thread (Event handler Thread) changes the value; it would not be visible to this thread. Making boolean variable "bExit" as volatile in java ensures this will not happen.
Important points on Volatile keyword in Java
1. Volatile keyword in Java is only application to variable and using volatile keyword with class and method is illegal.
2. Volatile keyword in Java guarantees that value of volatile variable will always be read from main memory and not from Thread's local cache.
3. In Java reads and writes are atomic for all variables declared using java volatile keyword (including long and double variables).
4. Using Volatile keyword in Java on variables reduces the risk of memory consistency errors, because any write to a volatile variable in Java establishes a happens-before relationship with subsequent reads of that same variable.
5. From Java 5 changes to a volatile variable are always visible to other threads. What’s more it also means that when a thread reads a volatile variable in java, it sees not just the latest change to the volatile variable but also the side effects of the code that led up the change.
6. Reads and writes are atomic for reference variables are for most primitive variables (all types except long and double) even without use of volatile keyword in Java.
7. An access to a volatile variable in Java never has chance to block, since we are only doing a simple read or write, so unlike a synchronized block we will never hold on to any lock or wait for any lock.
8. A java volatile variable that is an object reference may be null.
9. Java volatile keyword doesn't means atomic, its common misconception that after declaring volatile ++ will be atomic, to make the operation atomic you still need to ensure exclusive access using synchronized method or block in Java.
10. If a variable is not shared between multiple threads no need to use volatile keyword with that variable.
Difference between synchronized and volatile keyword in Java
1. Volatile keyword in java is a field modifier, while synchronized modifies code blocks and methods.
2. Synchronized obtains and releases lock on monitor’s java volatile keyword doesn't require that.
3. Threads in Java can be blocked for waiting any monitor in case of synchronized, that is not the case with volatile keyword in Java.
4. Synchronized method affects performance more than volatile keyword in Java.
5. Since volatile keyword in Java only synchronizes the value of one variable between Thread memory and "main" memory while synchronized synchronizes the value of all variable between thread memory and "main" memory and locks and releases a monitor to boot. Due to this reason synchronized keyword in Java is likely to have more overhead than volatile.
6. You can not synchronize on null object but your volatile variable in java could be null.
7. From Java 5 Writing into a volatile field has the same memory effect as a monitor release, and reading from a volatile field has the same memory effect as a monitor acquire
7. From Java 5 Writing into a volatile field has the same memory effect as a monitor release, and reading from a volatile field has the same memory effect as a monitor acquire
In Summary volatile keyword in Java is not a replacement of synchronized block or method but in some situation is very handy and can save performance overhead which comes with use of synchronization in java
Difference Between hashtable and hashmap
1) hashtable extends Dictionary interface which is quite old while hashmap extends Map interface.
2) hashtalbe doesn't have counterpart like ConcurrentHashMap.
3) another important difference between hashtable and hashmap is , hashtable is less secure than hashmap because of Enumeration it uses. while hashmap uses iterator which prevents Concurrent Modification of HashMap, which is not possible in case of hashtable.
4) stay out of hashtable use hashmap instead.
2) hashtalbe doesn't have counterpart like ConcurrentHashMap.
3) another important difference between hashtable and hashmap is , hashtable is less secure than hashmap because of Enumeration it uses. while hashmap uses iterator which prevents Concurrent Modification of HashMap, which is not possible in case of hashtable.
4) stay out of hashtable use hashmap instead.
HashMap
HashMap accept null while hashtable doesn't , HashMap is not synchronized, hashMap is fast and so on along with basics like its stores key and value pairs etc.
1. The HashMap class is roughly equivalent to Hashtable, except that it is non synchronized and permits nulls. (HashMap allows null values as key and value whereas Hashtable doesn't allow nulls).
2. HashMap does not guarantee that the order of the map will remain constant over time.
3. HashMap is non synchronized whereas Hashtable is synchronized.
4. Iterator in the HashMap is fail-fast while the enumerator for the Hashtable is not and throw ConcurrentModificationException if any other Thread modifies the map structurally by adding or removing any element except Iterator's own remove() method. But this is not a guaranteed behavior and will be done by JVM on best effort.
Note on Some Important Terms
1)Synchronized means only one thread can modify a hash table at one point of time. Basically, it means that any thread before performing an update on a hashtable will have to acquire a lock on the object while others will wait for lock to be released.
2)Fail-safe is relevant from the context of iterators. If an iterator has been created on a collection object and some other thread tries to modify the collection object "structurally", a concurrent modification exception wjavascript:void(0)ill be thrown. It is possible for other threads though to invoke "set" method since it doesn't modify the collection "structurally". However, if prior to calling "set", the collection has been modified structurally, "IllegalArgumentException" will be thrown.
3)Structurally modification means deleting or inserting element which could effectively change the structure of map.
HashMap can be synchronized by
Map m = Collections.synchronizeMap(hashMap);
Hope this will be useful.
Monday 30 May 2011
Reading an XML document using JDOM
ReadingxmlusingJdom.java
/*
* @Program to read an XML document using JDOM?
* ReadingxmlusingJdom.java
* Author:-RoseIndia Team
* Date:-10-Jun-2008
*/
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import java.io.ByteArrayInputStream;
import java.util.List;
public class ReadingxmlusingJdom {
public static void main(String[] args) throws Exception {
String data =
"<root>" +
"<Companyname>" +
"<Employee name=\"Girish\" Age=\"25\">Developer</Employee>" +
"</Companyname>" +
"<Companyname>" +
"<Employee name=\"Komal\" Age=\"25\">Administrator</Employee>" +
"</Companyname>" +
"</root>";
SAXBuilder builder = new SAXBuilder();
Document document = builder.build(
new ByteArrayInputStream(data.getBytes()));
Element root = document.getRootElement();
List row = root.getChildren("Companyname");
for (int i = 0; i < row.size(); i++) {
Element Companyname = (Element) row.get(i);
List column = Companyname.getChildren("Employee");
for (int j = 0; j < column.size(); j++) {
Element Employee = (Element) column.get(j);
String name = Employee.getAttribute("name").getValue();
String value = Employee.getText();
int length = Employee.getAttribute("Age").getIntValue();
System.out.println("Name = " + name);
System.out.println("Profile = " + value);
System.out.println("Age = " + length);
}
}
}
}
Output of the program:-
Name = Girish
Profile = Developer
Age = 25
Name = Komal
Profile = Administrator
Age = 25
/*
* @Program to read an XML document using JDOM?
* ReadingxmlusingJdom.java
* Author:-RoseIndia Team
* Date:-10-Jun-2008
*/
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import java.io.ByteArrayInputStream;
import java.util.List;
public class ReadingxmlusingJdom {
public static void main(String[] args) throws Exception {
String data =
"<root>" +
"<Companyname>" +
"<Employee name=\"Girish\" Age=\"25\">Developer</Employee>" +
"</Companyname>" +
"<Companyname>" +
"<Employee name=\"Komal\" Age=\"25\">Administrator</Employee>" +
"</Companyname>" +
"</root>";
SAXBuilder builder = new SAXBuilder();
Document document = builder.build(
new ByteArrayInputStream(data.getBytes()));
Element root = document.getRootElement();
List row = root.getChildren("Companyname");
for (int i = 0; i < row.size(); i++) {
Element Companyname = (Element) row.get(i);
List column = Companyname.getChildren("Employee");
for (int j = 0; j < column.size(); j++) {
Element Employee = (Element) column.get(j);
String name = Employee.getAttribute("name").getValue();
String value = Employee.getText();
int length = Employee.getAttribute("Age").getIntValue();
System.out.println("Name = " + name);
System.out.println("Profile = " + value);
System.out.println("Age = " + length);
}
}
}
}
Output of the program:-
Name = Girish
Profile = Developer
Age = 25
Name = Komal
Profile = Administrator
Age = 25
Storing xml data into the database
I have to store this file into database
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="cdcatalog.xsl"?>
<entertainment category="video">
<movie genre="hollywood">
<title>Ironman2</title>
<artist >
<male>Robert Downing Junior</male>
<female>gwyneth paltrow</female>
</artist>
<country>USA</country>
<company>Columbia pictures</company>
<cost>1000 million</cost>
<release>2010 7 may</release>
</movie>
<movie genre="bollywood">
<title>Kites</title>
<artist >
<male>Hrithik Roshan</male>
<female>barbara mori</female>
</artist>
<country>India</country>
<company>FilmKraft India</company>
<cost>500 million</cost>
<release>2010 17 may</release>
</movie>
</entertainment>
import javax.xml.parsers.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.sql.*;
public class xml{
public static void main(String[] args) {
try{
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/register";, "root", "root");
Statement st=connection.createStatement();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse("movie.xml");
NodeList n1= doc.getElementsByTagName("title");
NodeList n2= doc.getElementsByTagName("male");
NodeList n3= doc.getElementsByTagName("female");
NodeList n4= doc.getElementsByTagName("country");
NodeList n5= doc.getElementsByTagName("company");
NodeList n6= doc.getElementsByTagName("cost");
NodeList n7= doc.getElementsByTagName("release");
for(int i=0;i<n1.getLength();i++){
String st1= n1.item(i).getFirstChild().getNodeValue();
String st2= n2.item(i).getFirstChild().getNodeValue();
String st3= n3.item(i).getFirstChild().getNodeValue();
String st4= n4.item(i).getFirstChild().getNodeValue();
String st5= n5.item(i).getFirstChild().getNodeValue();
String st6= n6.item(i).getFirstChild().getNodeValue();
String st7= n7.item(i).getFirstChild().getNodeValue();
System.out.println(st1+" "+st2+" "+st3+" "+st4+" "+st5+" "+st6+" "+st7);
st.executeUpdate("insert into movie(title,male,female,country,company,cost,movierelease) values('"+st1+"','"+st2+"','"+st3+"','"+st4+"','"+st5+"','"+st6+"','"+st7+"')");
}
}
catch(Exception e){
e.printStackTrace();
}
}
}
For the above code, we have created following database table:
CREATE TABLE `movie` (
`id` bigint(255) NOT NULL auto_increment,
`title` varchar(255) default NULL,
`male` varchar(255) default NULL,
`female` varchar(255) default NULL,
`country` varchar(255) default NULL,
`company` varchar(255) default NULL,
`cost` varchar(255) default NULL,
`movierelease` varchar(255) default NULL,
PRIMARY KEY (`id`)
)
Code To check the Range of Ip Address
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class IpRange {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String str1="192.168.1.101";
String str2="192.168.1.199";
int[] p1 = new int[4];
int[] p2 = new int[4];
int[] p3 = new int[4];
System.out.println("Enter valid ip address");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String str3=br.readLine();
String[] s1 =str1.toString().split("\\.");
String[] s2 =str2.toString().split("\\.");
String[] s3 =str3.toString().split("\\.");
// p1[0] = Integer.parseInt(s1[0]);
//
// p1[1] = Integer.parseInt(s1[1]);
p1[2] = Integer.parseInt(s1[2]);
p1[3] = Integer.parseInt(s1[3]);
// p2[0] = Integer.parseInt(s2[0]);
//
// p2[1] = Integer.parseInt(s2[1]);
p2[2] = Integer.parseInt(s2[2]);
p2[3] = Integer.parseInt(s2[3]);
// p3[0] = Integer.parseInt(s3[0]);
//
// p3[1] = Integer.parseInt(s3[1]);
p3[2] = Integer.parseInt(s3[2]);
p3[3] = Integer.parseInt(s3[3]);
if ((p1[2] < p3[2] && p2[2] > p3[2])&&(p1[3] < p3[3] && p2[3] > p3[3]) )
{
System.out.println("valid ip address");
}
else
{
System.out.println("invalid ip address");
}
}
}
import java.io.IOException;
import java.io.InputStreamReader;
public class IpRange {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String str1="192.168.1.101";
String str2="192.168.1.199";
int[] p1 = new int[4];
int[] p2 = new int[4];
int[] p3 = new int[4];
System.out.println("Enter valid ip address");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String str3=br.readLine();
String[] s1 =str1.toString().split("\\.");
String[] s2 =str2.toString().split("\\.");
String[] s3 =str3.toString().split("\\.");
// p1[0] = Integer.parseInt(s1[0]);
//
// p1[1] = Integer.parseInt(s1[1]);
p1[2] = Integer.parseInt(s1[2]);
p1[3] = Integer.parseInt(s1[3]);
// p2[0] = Integer.parseInt(s2[0]);
//
// p2[1] = Integer.parseInt(s2[1]);
p2[2] = Integer.parseInt(s2[2]);
p2[3] = Integer.parseInt(s2[3]);
// p3[0] = Integer.parseInt(s3[0]);
//
// p3[1] = Integer.parseInt(s3[1]);
p3[2] = Integer.parseInt(s3[2]);
p3[3] = Integer.parseInt(s3[3]);
if ((p1[2] < p3[2] && p2[2] > p3[2])&&(p1[3] < p3[3] && p2[3] > p3[3]) )
{
System.out.println("valid ip address");
}
else
{
System.out.println("invalid ip address");
}
}
}
Subscribe to:
Posts (Atom)