<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Chump+Chief</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Chump+Chief"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Chump_Chief"/>
	<updated>2026-06-02T03:29:57Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28658</id>
		<title>CSC/ECE 517 Fall 2009/wiki3 13 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28658"/>
		<updated>2009-11-18T21:06:42Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* External Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Principle of Explicit Interfaces =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces is proposed by Bertrand Meyer in his book Object-Oriented Software Construction.  It states&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;quot;Whenever two modules A and B communicate, this must be obvious from the text of A or B or both.&amp;quot;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces refers to the attempt to ensure that relationships between separate modules are easily found and understood.  This is important when considering making a change to the code base.  It allows the programmer to quickly see what other modules his work might impact, preventing unintended side effects.&lt;br /&gt;
&lt;br /&gt;
Interaction between modules, either by direct manipulation or by shared data, is an example of [http://en.wikipedia.org/wiki/Coupling_%28computer_science%29 coupling].  Coupling is a trait of object oriented software that should be avoided when possible, but when it is unavoidable the Principle of Explicit Interfaces should be used to make it as apparent as possible.  This helps to reduce the impact that coupling may have.&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
&lt;br /&gt;
One area in which it may be difficult to implement interfaces while adhering to the principle of explicit interfaces is shared data.  Bertrand Meyer recognizes this problem and diagrams it as:&lt;br /&gt;
&lt;br /&gt;
[[Image:Principle_of_Explicit_Interfaces_Data_Sharing.png]]&lt;br /&gt;
&lt;br /&gt;
This illustrates how two modules may interact in an indirect manner.  Although the two modules do not directly interact on each other, by relying on a common resource changes to module A may impact how module B functions.&lt;br /&gt;
&lt;br /&gt;
== Relationship to Design by Contract ==&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Design_by_contract Design by Contract] is another concept pioneered by Bertrand Meyer relating to the concept of having modules which act in well defined and predictable manners.  This allows other modules to interact with them and get the results they expect.&lt;br /&gt;
&lt;br /&gt;
Explicit interfaces is an important part of the contract, since it deals directly with interactions between modules being transparent and easy to spot.  Knowing interactions between modules is essential when making a contract or guarantee for the implementing module's behavior.&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
[http://www.cit.gu.edu.au/~francis/sa2000/unit2.htm#CRITERIA Notes on application architecture] - In addition to a summary of the principle of explicit interfaces, this site has information on Meyer's other principles, and some other important criteria for good application design.&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Object-Oriented_Software_Construction Object-Oriented Software Construction at Wikipedia] - For more information on the text in which the principle was introduced.&lt;br /&gt;
&lt;br /&gt;
[http://se.ethz.ch/~meyer/ Bertrand Meyer's home page] - Find other publications and research by Meyer.&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Design_by_contract Design by Contract at Wikipedia] - Other aspects of Design by Contract outside of the principle of explicit interfaces.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
*Meyer, Bertrand.  Object-Oriented Software Construction, 2nd edition p50.  ISE Inc., Santa Barbara, CA, 1997.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28655</id>
		<title>CSC/ECE 517 Fall 2009/wiki3 13 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28655"/>
		<updated>2009-11-18T21:05:14Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Relationship to Design by Contract */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Principle of Explicit Interfaces =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces is proposed by Bertrand Meyer in his book Object-Oriented Software Construction.  It states&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;quot;Whenever two modules A and B communicate, this must be obvious from the text of A or B or both.&amp;quot;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces refers to the attempt to ensure that relationships between separate modules are easily found and understood.  This is important when considering making a change to the code base.  It allows the programmer to quickly see what other modules his work might impact, preventing unintended side effects.&lt;br /&gt;
&lt;br /&gt;
Interaction between modules, either by direct manipulation or by shared data, is an example of [http://en.wikipedia.org/wiki/Coupling_%28computer_science%29 coupling].  Coupling is a trait of object oriented software that should be avoided when possible, but when it is unavoidable the Principle of Explicit Interfaces should be used to make it as apparent as possible.  This helps to reduce the impact that coupling may have.&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
&lt;br /&gt;
One area in which it may be difficult to implement interfaces while adhering to the principle of explicit interfaces is shared data.  Bertrand Meyer recognizes this problem and diagrams it as:&lt;br /&gt;
&lt;br /&gt;
[[Image:Principle_of_Explicit_Interfaces_Data_Sharing.png]]&lt;br /&gt;
&lt;br /&gt;
This illustrates how two modules may interact in an indirect manner.  Although the two modules do not directly interact on each other, by relying on a common resource changes to module A may impact how module B functions.&lt;br /&gt;
&lt;br /&gt;
== Relationship to Design by Contract ==&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Design_by_contract Design by Contract] is another concept pioneered by Bertrand Meyer relating to the concept of having modules which act in well defined and predictable manners.  This allows other modules to interact with them and get the results they expect.&lt;br /&gt;
&lt;br /&gt;
Explicit interfaces is an important part of the contract, since it deals directly with interactions between modules being transparent and easy to spot.  Knowing interactions between modules is essential when making a contract or guarantee for the implementing module's behavior.&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
[http://www.cit.gu.edu.au/~francis/sa2000/unit2.htm#CRITERIA Notes on application architecture] - In addition to a summary of the principle of explicit interfaces, this site has information on Meyer's other principles, and some other important criteria for good application design.&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Object-Oriented_Software_Construction Object-Oriented Software Construction at Wikipedia] - For more information on the text in which the principle was introduced.&lt;br /&gt;
&lt;br /&gt;
[http://se.ethz.ch/~meyer/ Bertrand Meyer's home page] - Find other publications and research by Meyer.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
*Meyer, Bertrand.  Object-Oriented Software Construction, 2nd edition p50.  ISE Inc., Santa Barbara, CA, 1997.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28624</id>
		<title>CSC/ECE 517 Fall 2009/wiki3 13 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28624"/>
		<updated>2009-11-18T20:51:05Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: added design by contract&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Principle of Explicit Interfaces =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces is proposed by Bertrand Meyer in his book Object-Oriented Software Construction.  It states&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;quot;Whenever two modules A and B communicate, this must be obvious from the text of A or B or both.&amp;quot;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces refers to the attempt to ensure that relationships between separate modules are easily found and understood.  This is important when considering making a change to the code base.  It allows the programmer to quickly see what other modules his work might impact, preventing unintended side effects.&lt;br /&gt;
&lt;br /&gt;
Interaction between modules, either by direct manipulation or by shared data, is an example of [http://en.wikipedia.org/wiki/Coupling_%28computer_science%29 coupling].  Coupling is a trait of object oriented software that should be avoided when possible, but when it is unavoidable the Principle of Explicit Interfaces should be used to make it as apparent as possible.  This helps to reduce the impact that coupling may have.&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
&lt;br /&gt;
One area in which it may be difficult to implement interfaces while adhering to the principle of explicit interfaces is shared data.  Bertrand Meyer recognizes this problem and diagrams it as:&lt;br /&gt;
&lt;br /&gt;
[[Image:Principle_of_Explicit_Interfaces_Data_Sharing.png]]&lt;br /&gt;
&lt;br /&gt;
This illustrates how two modules may interact in an indirect manner.  Although the two modules do not directly interact on each other, by relying on a common resource changes to module A may impact how module B functions.&lt;br /&gt;
&lt;br /&gt;
== Relationship to Design by Contract ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
[http://www.cit.gu.edu.au/~francis/sa2000/unit2.htm#CRITERIA Notes on application architecture] - In addition to a summary of the principle of explicit interfaces, this site has information on Meyer's other principles, and some other important criteria for good application design.&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Object-Oriented_Software_Construction Object-Oriented Software Construction at Wikipedia] - For more information on the text in which the principle was introduced.&lt;br /&gt;
&lt;br /&gt;
[http://se.ethz.ch/~meyer/ Bertrand Meyer's home page] - Find other publications and research by Meyer.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
*Meyer, Bertrand.  Object-Oriented Software Construction, 2nd edition p50.  ISE Inc., Santa Barbara, CA, 1997.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28623</id>
		<title>CSC/ECE 517 Fall 2009/wiki3 13 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28623"/>
		<updated>2009-11-18T20:50:13Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Definition */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Principle of Explicit Interfaces =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces is proposed by Bertrand Meyer in his book Object-Oriented Software Construction.  It states&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;quot;Whenever two modules A and B communicate, this must be obvious from the text of A or B or both.&amp;quot;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces refers to the attempt to ensure that relationships between separate modules are easily found and understood.  This is important when considering making a change to the code base.  It allows the programmer to quickly see what other modules his work might impact, preventing unintended side effects.&lt;br /&gt;
&lt;br /&gt;
Interaction between modules, either by direct manipulation or by shared data, is an example of [http://en.wikipedia.org/wiki/Coupling_%28computer_science%29 coupling].  Coupling is a trait of object oriented software that should be avoided when possible, but when it is unavoidable the Principle of Explicit Interfaces should be used to make it as apparent as possible.  This helps to reduce the impact that coupling may have.&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
&lt;br /&gt;
One area in which it may be difficult to implement interfaces while adhering to the principle of explicit interfaces is shared data.  Bertrand Meyer recognizes this problem and diagrams it as:&lt;br /&gt;
&lt;br /&gt;
[[Image:Principle_of_Explicit_Interfaces_Data_Sharing.png]]&lt;br /&gt;
&lt;br /&gt;
This illustrates how two modules may interact in an indirect manner.  Although the two modules do not directly interact on each other, by relying on a common resource changes to module A may impact how module B functions.&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
[http://www.cit.gu.edu.au/~francis/sa2000/unit2.htm#CRITERIA Notes on application architecture] - In addition to a summary of the principle of explicit interfaces, this site has information on Meyer's other principles, and some other important criteria for good application design.&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Object-Oriented_Software_Construction Object-Oriented Software Construction at Wikipedia] - For more information on the text in which the principle was introduced.&lt;br /&gt;
&lt;br /&gt;
[http://se.ethz.ch/~meyer/ Bertrand Meyer's home page] - Find other publications and research by Meyer.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
*Meyer, Bertrand.  Object-Oriented Software Construction, 2nd edition p50.  ISE Inc., Santa Barbara, CA, 1997.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28607</id>
		<title>CSC/ECE 517 Fall 2009/wiki3 13 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28607"/>
		<updated>2009-11-18T20:36:44Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Motivation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Principle of Explicit Interfaces =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces is proposed by Bertrand Meyer in his book Object-Oriented Software Construction.  It states&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Whenever two modules A and B communicate, this must be obvious from the text of A or B or both.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces refers to the attempt to ensure that relationships between separate modules are easily found and understood.  This is important when considering making a change to the code base.  It allows the programmer to quickly see what other modules his work might impact, preventing unintended side effects.&lt;br /&gt;
&lt;br /&gt;
Interaction between modules, either by direct manipulation or by shared data, is an example of [http://en.wikipedia.org/wiki/Coupling_%28computer_science%29 coupling].  Coupling is a trait of object oriented software that should be avoided when possible, but when it is unavoidable the Principle of Explicit Interfaces should be used to make it as apparent as possible.  This helps to reduce the impact that coupling may have.&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
&lt;br /&gt;
One area in which it may be difficult to implement interfaces while adhering to the principle of explicit interfaces is shared data.  Bertrand Meyer recognizes this problem and diagrams it as:&lt;br /&gt;
&lt;br /&gt;
[[Image:Principle_of_Explicit_Interfaces_Data_Sharing.png]]&lt;br /&gt;
&lt;br /&gt;
This illustrates how two modules may interact in an indirect manner.  Although the two modules do not directly interact on each other, by relying on a common resource changes to module A may impact how module B functions.&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
[http://www.cit.gu.edu.au/~francis/sa2000/unit2.htm#CRITERIA Notes on application architecture] - In addition to a summary of the principle of explicit interfaces, this site has information on Meyer's other principles, and some other important criteria for good application design.&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Object-Oriented_Software_Construction Object-Oriented Software Construction at Wikipedia] - For more information on the text in which the principle was introduced.&lt;br /&gt;
&lt;br /&gt;
[http://se.ethz.ch/~meyer/ Bertrand Meyer's home page] - Find other publications and research by Meyer.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
*Meyer, Bertrand.  Object-Oriented Software Construction, 2nd edition p50.  ISE Inc., Santa Barbara, CA, 1997.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28318</id>
		<title>CSC/ECE 517 Fall 2009/wiki3 13 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28318"/>
		<updated>2009-11-18T09:22:34Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* External Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Principle of Explicit Interfaces =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces is proposed by Bertrand Meyer in his book Object-Oriented Software Construction.  It states&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Whenever two modules A and B communicate, this must be obvious from the text of A or B or both.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces refers to the attempt to ensure that relationships between separate modules are easily found and understood.  This is important when considering making a change to the code base.  It allows the programmer to quickly see what other modules his work might impact, preventing unintended side effects.&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
&lt;br /&gt;
One area in which it may be difficult to implement interfaces while adhering to the principle of explicit interfaces is shared data.  Bertrand Meyer recognizes this problem and diagrams it as:&lt;br /&gt;
&lt;br /&gt;
[[Image:Principle_of_Explicit_Interfaces_Data_Sharing.png]]&lt;br /&gt;
&lt;br /&gt;
This illustrates how two modules may interact in an indirect manner.  Although the two modules do not directly interact on each other, by relying on a common resource changes to module A may impact how module B functions.&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
[http://www.cit.gu.edu.au/~francis/sa2000/unit2.htm#CRITERIA Notes on application architecture] - In addition to a summary of the principle of explicit interfaces, this site has information on Meyer's other principles, and some other important criteria for good application design.&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Object-Oriented_Software_Construction Object-Oriented Software Construction at Wikipedia] - For more information on the text in which the principle was introduced.&lt;br /&gt;
&lt;br /&gt;
[http://se.ethz.ch/~meyer/ Bertrand Meyer's home page] - Find other publications and research by Meyer.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
*Meyer, Bertrand.  Object-Oriented Software Construction, 2nd edition p50.  ISE Inc., Santa Barbara, CA, 1997.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28315</id>
		<title>CSC/ECE 517 Fall 2009/wiki3 13 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28315"/>
		<updated>2009-11-18T09:15:43Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Application */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Principle of Explicit Interfaces =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces is proposed by Bertrand Meyer in his book Object-Oriented Software Construction.  It states&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Whenever two modules A and B communicate, this must be obvious from the text of A or B or both.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces refers to the attempt to ensure that relationships between separate modules are easily found and understood.  This is important when considering making a change to the code base.  It allows the programmer to quickly see what other modules his work might impact, preventing unintended side effects.&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
&lt;br /&gt;
One area in which it may be difficult to implement interfaces while adhering to the principle of explicit interfaces is shared data.  Bertrand Meyer recognizes this problem and diagrams it as:&lt;br /&gt;
&lt;br /&gt;
[[Image:Principle_of_Explicit_Interfaces_Data_Sharing.png]]&lt;br /&gt;
&lt;br /&gt;
This illustrates how two modules may interact in an indirect manner.  Although the two modules do not directly interact on each other, by relying on a common resource changes to module A may impact how module B functions.&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
*Meyer, Bertrand.  Object-Oriented Software Construction, 2nd edition p50.  ISE Inc., Santa Barbara, CA, 1997.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Principle_of_Explicit_Interfaces_Data_Sharing.png&amp;diff=28312</id>
		<title>File:Principle of Explicit Interfaces Data Sharing.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Principle_of_Explicit_Interfaces_Data_Sharing.png&amp;diff=28312"/>
		<updated>2009-11-18T09:11:47Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: Diagram showing the challenge of the Principle of Explicit Interfaces.

Source: Meyer, Bertrand. Object-Oriented Software Construction, 2nd edition p50. ISE Inc., Santa Barbara, CA, 1997.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Diagram showing the challenge of the Principle of Explicit Interfaces.&lt;br /&gt;
&lt;br /&gt;
Source: Meyer, Bertrand. Object-Oriented Software Construction, 2nd edition p50. ISE Inc., Santa Barbara, CA, 1997.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28309</id>
		<title>CSC/ECE 517 Fall 2009/wiki3 13 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28309"/>
		<updated>2009-11-18T09:06:46Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Motivation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Principle of Explicit Interfaces =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces is proposed by Bertrand Meyer in his book Object-Oriented Software Construction.  It states&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Whenever two modules A and B communicate, this must be obvious from the text of A or B or both.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces refers to the attempt to ensure that relationships between separate modules are easily found and understood.  This is important when considering making a change to the code base.  It allows the programmer to quickly see what other modules his work might impact, preventing unintended side effects.&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
*Meyer, Bertrand.  Object-Oriented Software Construction, 2nd edition p50.  ISE Inc., Santa Barbara, CA, 1997.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28279</id>
		<title>CSC/ECE 517 Fall 2009/wiki3 13 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28279"/>
		<updated>2009-11-18T07:50:16Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Sources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Principle of Explicit Interfaces =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces is proposed by Bertrand Meyer in his book Object-Oriented Software Construction.  It states&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Whenever two modules A and B communicate, this must be obvious from the text of A or B or both.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
*Meyer, Bertrand.  Object-Oriented Software Construction, 2nd edition p50.  ISE Inc., Santa Barbara, CA, 1997.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28278</id>
		<title>CSC/ECE 517 Fall 2009/wiki3 13 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28278"/>
		<updated>2009-11-18T07:49:59Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: added definition&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Principle of Explicit Interfaces =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
The Principle of Explicit Interfaces is proposed by Bertrand Meyer in his book Object-Oriented Software Construction.  It states&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Whenever two modules A and B communicate, this must be obvious from the text of A or B or both.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
&lt;br /&gt;
Meyer, Bertrand.  Object-Oriented Software Construction, 2nd edition p50.  ISE Inc., Santa Barbara, CA, 1997.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28272</id>
		<title>CSC/ECE 517 Fall 2009/wiki3 13 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=28272"/>
		<updated>2009-11-18T07:23:29Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: added sections&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Principle of Explicit Interfaces =&lt;br /&gt;
&lt;br /&gt;
== Definition ==&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
&lt;br /&gt;
== Application ==&lt;br /&gt;
&lt;br /&gt;
== External Links ==&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=27233</id>
		<title>CSC/ECE 517 Fall 2009/wiki3 13 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki3_13_b5&amp;diff=27233"/>
		<updated>2009-11-17T05:16:36Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: creating the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Principle of Explicit Interfaces ==&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25376</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25376"/>
		<updated>2009-10-10T02:10:20Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  In this example it might result in the client's account being charged multiple times, or multiple orders being shipped which aren't charged, etc.&lt;br /&gt;
&lt;br /&gt;
A client could also click their back button after submitting the form, or refresh the page.  In addition to the problems caused by multiple clicks, this could also cause an attempt to access data that no longer exists (e.g. credit card number purged from system after transaction completed).  Depending on how robust the system is, this could cause other unpredictable results.&lt;br /&gt;
&lt;br /&gt;
Finally, the client might have malicious intent and be trying to subvert the site.  By exploiting desynchronization between the client and server the client may be able to perform actions they should not.  A good example is an online poll.  By clicking multiple times on a vote button very quickly before the vote is processed, the client may be able to get multiple votes in before the system realizes they are stuffing the ballot box.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
The control flow diagram below depicts the synchronizer token pattern working with a valid token (normal usage):&lt;br /&gt;
&lt;br /&gt;
[[Image:Positive_flow.png]]&lt;br /&gt;
&lt;br /&gt;
The control flow diagram below depicts the synchronizer token pattern working with an invalid token (erroneous usage):&lt;br /&gt;
&lt;br /&gt;
[[Image:Negative_flow.png]]&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
=== Java (with Struts) ===&lt;br /&gt;
&lt;br /&gt;
The key methods in this implementation are saveToken(HttpServletRequest req), isTokenValid(HttpServletRequest req), and reset(HttpServletRequest req) which create, validate, and destroy tokens, respectively.  resetToken(HttpServletRequest req) may also be used to destroy the token.&lt;br /&gt;
&lt;br /&gt;
From [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ruby on Rails ===&lt;br /&gt;
&lt;br /&gt;
A synchronizer token pattern could be easily implemented in Ruby on Rails by using before_filter and after_filter to perform token creation and invalidation at the appropriate times (create token before displaying the form page, invalidate token after taking the submit action).&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
Use of this pattern requires the programmer to consider another alternative flow for if the token is invalid.  Depending on the design decisions made this may complicate the program.  For example, if the user tries to submit a large amount of form data with an invalid token, the designer might want to preserve their entries while issuing a new token.  Failure to preserve entries might cause a user to give up and not follow through with their action on the site.  However, this is an additional feature that must then be designed, added, and tested.&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
The common alternative to the synchronizer token pattern is to simply use Javascript or similar to disable the &amp;quot;submit&amp;quot; button on the client side.  This solves the issue of multiple clicks on the button without the need for an alternative program flow.  However, this is less reliable since the user might still use their back button or a bookmark to revisit the page.&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://www.corej2eepatterns.com/Design/PresoDesign.htm Core J2EE Patterns]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Negative_flow.png&amp;diff=25372</id>
		<title>File:Negative flow.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Negative_flow.png&amp;diff=25372"/>
		<updated>2009-10-10T02:09:40Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: Depicting synchronizer token pattern control flow with an invalid token.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Depicting synchronizer token pattern control flow with an invalid token.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25369</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25369"/>
		<updated>2009-10-10T02:08:48Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  In this example it might result in the client's account being charged multiple times, or multiple orders being shipped which aren't charged, etc.&lt;br /&gt;
&lt;br /&gt;
A client could also click their back button after submitting the form, or refresh the page.  In addition to the problems caused by multiple clicks, this could also cause an attempt to access data that no longer exists (e.g. credit card number purged from system after transaction completed).  Depending on how robust the system is, this could cause other unpredictable results.&lt;br /&gt;
&lt;br /&gt;
Finally, the client might have malicious intent and be trying to subvert the site.  By exploiting desynchronization between the client and server the client may be able to perform actions they should not.  A good example is an online poll.  By clicking multiple times on a vote button very quickly before the vote is processed, the client may be able to get multiple votes in before the system realizes they are stuffing the ballot box.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
The control flow diagram below depicts the synchronizer token pattern working with a valid token (normal usage):&lt;br /&gt;
&lt;br /&gt;
[[Image:Positive_flow.png]]&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
=== Java (with Struts) ===&lt;br /&gt;
&lt;br /&gt;
The key methods in this implementation are saveToken(HttpServletRequest req), isTokenValid(HttpServletRequest req), and reset(HttpServletRequest req) which create, validate, and destroy tokens, respectively.  resetToken(HttpServletRequest req) may also be used to destroy the token.&lt;br /&gt;
&lt;br /&gt;
From [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ruby on Rails ===&lt;br /&gt;
&lt;br /&gt;
A synchronizer token pattern could be easily implemented in Ruby on Rails by using before_filter and after_filter to perform token creation and invalidation at the appropriate times (create token before displaying the form page, invalidate token after taking the submit action).&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
Use of this pattern requires the programmer to consider another alternative flow for if the token is invalid.  Depending on the design decisions made this may complicate the program.  For example, if the user tries to submit a large amount of form data with an invalid token, the designer might want to preserve their entries while issuing a new token.  Failure to preserve entries might cause a user to give up and not follow through with their action on the site.  However, this is an additional feature that must then be designed, added, and tested.&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
The common alternative to the synchronizer token pattern is to simply use Javascript or similar to disable the &amp;quot;submit&amp;quot; button on the client side.  This solves the issue of multiple clicks on the button without the need for an alternative program flow.  However, this is less reliable since the user might still use their back button or a bookmark to revisit the page.&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://www.corej2eepatterns.com/Design/PresoDesign.htm Core J2EE Patterns]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Positive_flow.png&amp;diff=25365</id>
		<title>File:Positive flow.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Positive_flow.png&amp;diff=25365"/>
		<updated>2009-10-10T02:07:05Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: Depicting synchronizer token pattern control flow with a valid token.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Depicting synchronizer token pattern control flow with a valid token.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25328</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25328"/>
		<updated>2009-10-10T01:50:34Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Java (with Struts) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  In this example it might result in the client's account being charged multiple times, or multiple orders being shipped which aren't charged, etc.&lt;br /&gt;
&lt;br /&gt;
A client could also click their back button after submitting the form, or refresh the page.  In addition to the problems caused by multiple clicks, this could also cause an attempt to access data that no longer exists (e.g. credit card number purged from system after transaction completed).  Depending on how robust the system is, this could cause other unpredictable results.&lt;br /&gt;
&lt;br /&gt;
Finally, the client might have malicious intent and be trying to subvert the site.  By exploiting desynchronization between the client and server the client may be able to perform actions they should not.  A good example is an online poll.  By clicking multiple times on a vote button very quickly before the vote is processed, the client may be able to get multiple votes in before the system realizes they are stuffing the ballot box.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
=== Java (with Struts) ===&lt;br /&gt;
&lt;br /&gt;
The key methods in this implementation are saveToken(HttpServletRequest req), isTokenValid(HttpServletRequest req), and reset(HttpServletRequest req) which create, validate, and destroy tokens, respectively.  resetToken(HttpServletRequest req) may also be used to destroy the token.&lt;br /&gt;
&lt;br /&gt;
From [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ruby on Rails ===&lt;br /&gt;
&lt;br /&gt;
A synchronizer token pattern could be easily implemented in Ruby on Rails by using before_filter and after_filter to perform token creation and invalidation at the appropriate times (create token before displaying the form page, invalidate token after taking the submit action).&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
Use of this pattern requires the programmer to consider another alternative flow for if the token is invalid.  Depending on the design decisions made this may complicate the program.  For example, if the user tries to submit a large amount of form data with an invalid token, the designer might want to preserve their entries while issuing a new token.  Failure to preserve entries might cause a user to give up and not follow through with their action on the site.  However, this is an additional feature that must then be designed, added, and tested.&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
The common alternative to the synchronizer token pattern is to simply use Javascript or similar to disable the &amp;quot;submit&amp;quot; button on the client side.  This solves the issue of multiple clicks on the button without the need for an alternative program flow.  However, this is less reliable since the user might still use their back button or a bookmark to revisit the page.&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://www.corej2eepatterns.com/Design/PresoDesign.htm Core J2EE Patterns]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25323</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25323"/>
		<updated>2009-10-10T01:47:13Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Problem summary */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  In this example it might result in the client's account being charged multiple times, or multiple orders being shipped which aren't charged, etc.&lt;br /&gt;
&lt;br /&gt;
A client could also click their back button after submitting the form, or refresh the page.  In addition to the problems caused by multiple clicks, this could also cause an attempt to access data that no longer exists (e.g. credit card number purged from system after transaction completed).  Depending on how robust the system is, this could cause other unpredictable results.&lt;br /&gt;
&lt;br /&gt;
Finally, the client might have malicious intent and be trying to subvert the site.  By exploiting desynchronization between the client and server the client may be able to perform actions they should not.  A good example is an online poll.  By clicking multiple times on a vote button very quickly before the vote is processed, the client may be able to get multiple votes in before the system realizes they are stuffing the ballot box.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
=== Java (with Struts) ===&lt;br /&gt;
&lt;br /&gt;
The key methods in this implementation are saveToken(HttpServletRequest req), isTokenValid(HttpServletRequest req), and resetToken(HttpServletRequest req) which create, validate, and destroy tokens, respectively.&lt;br /&gt;
&lt;br /&gt;
From [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ruby on Rails ===&lt;br /&gt;
&lt;br /&gt;
A synchronizer token pattern could be easily implemented in Ruby on Rails by using before_filter and after_filter to perform token creation and invalidation at the appropriate times (create token before displaying the form page, invalidate token after taking the submit action).&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
Use of this pattern requires the programmer to consider another alternative flow for if the token is invalid.  Depending on the design decisions made this may complicate the program.  For example, if the user tries to submit a large amount of form data with an invalid token, the designer might want to preserve their entries while issuing a new token.  Failure to preserve entries might cause a user to give up and not follow through with their action on the site.  However, this is an additional feature that must then be designed, added, and tested.&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
The common alternative to the synchronizer token pattern is to simply use Javascript or similar to disable the &amp;quot;submit&amp;quot; button on the client side.  This solves the issue of multiple clicks on the button without the need for an alternative program flow.  However, this is less reliable since the user might still use their back button or a bookmark to revisit the page.&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://www.corej2eepatterns.com/Design/PresoDesign.htm Core J2EE Patterns]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25309</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25309"/>
		<updated>2009-10-10T01:37:09Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
=== Java (with Struts) ===&lt;br /&gt;
&lt;br /&gt;
The key methods in this implementation are saveToken(HttpServletRequest req), isTokenValid(HttpServletRequest req), and resetToken(HttpServletRequest req) which create, validate, and destroy tokens, respectively.&lt;br /&gt;
&lt;br /&gt;
From [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ruby on Rails ===&lt;br /&gt;
&lt;br /&gt;
A synchronizer token pattern could be easily implemented in Ruby on Rails by using before_filter and after_filter to perform token creation and invalidation at the appropriate times (create token before displaying the form page, invalidate token after taking the submit action).&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
Use of this pattern requires the programmer to consider another alternative flow for if the token is invalid.  Depending on the design decisions made this may complicate the program.  For example, if the user tries to submit a large amount of form data with an invalid token, the designer might want to preserve their entries while issuing a new token.  Failure to preserve entries might cause a user to give up and not follow through with their action on the site.  However, this is an additional feature that must then be designed, added, and tested.&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
The common alternative to the synchronizer token pattern is to simply use Javascript or similar to disable the &amp;quot;submit&amp;quot; button on the client side.  This solves the issue of multiple clicks on the button without the need for an alternative program flow.  However, this is less reliable since the user might still use their back button or a bookmark to revisit the page.&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://www.corej2eepatterns.com/Design/PresoDesign.htm Core J2EE Patterns]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25308</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25308"/>
		<updated>2009-10-10T01:36:34Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Java (with Struts) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
=== Java (with Struts) ===&lt;br /&gt;
&lt;br /&gt;
The key methods in this implementation are saveToken(HttpServletRequest req), isTokenValid(HttpServletRequest req), and resetToken(HttpServletRequest req) which create, validate, and destroy tokens, respectively.&lt;br /&gt;
&lt;br /&gt;
From [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ruby on Rails ===&lt;br /&gt;
&lt;br /&gt;
A synchronizer token pattern could be easily implemented in Ruby on Rails by using before_filter and after_filter to perform token creation and invalidation at the appropriate times (create token before displaying the form page, invalidate token after taking the submit action).&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
Use of this pattern requires the programmer to consider another alternative flow for if the token is invalid.  Depending on the design decisions made this may complicate the program.  For example, if the user tries to submit a large amount of form data with an invalid token, the designer might want to preserve their entries while issuing a new token.  Failure to preserve entries might cause a user to give up and not follow through with their action on the site.  However, this is an additional feature that must then be designed, added, and tested.&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
The common alternative to the synchronizer token pattern is to simply use Javascript or similar to disable the &amp;quot;submit&amp;quot; button on the client side.  This solves the issue of multiple clicks on the button without the need for an alternative program flow.  However, this is less reliable since the user might still use their back button or a bookmark to revisit the page.&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://www.corej2eepatterns.com/Design/PresoDesign.htm Core J2EE Patterns]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25307</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25307"/>
		<updated>2009-10-10T01:36:26Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Java (with Struts) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
=== Java (with Struts) ===&lt;br /&gt;
&lt;br /&gt;
The key methods in this implementation are saveToken(HttpServletRequest req), isTokenValid(HttpServletRequest req), and resetToken(HttpServletRequest req) which create, validate, and destroy tokens, respectively.&lt;br /&gt;
&lt;br /&gt;
From [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ruby on Rails ===&lt;br /&gt;
&lt;br /&gt;
A synchronizer token pattern could be easily implemented in Ruby on Rails by using before_filter and after_filter to perform token creation and invalidation at the appropriate times (create token before displaying the form page, invalidate token after taking the submit action).&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
Use of this pattern requires the programmer to consider another alternative flow for if the token is invalid.  Depending on the design decisions made this may complicate the program.  For example, if the user tries to submit a large amount of form data with an invalid token, the designer might want to preserve their entries while issuing a new token.  Failure to preserve entries might cause a user to give up and not follow through with their action on the site.  However, this is an additional feature that must then be designed, added, and tested.&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
The common alternative to the synchronizer token pattern is to simply use Javascript or similar to disable the &amp;quot;submit&amp;quot; button on the client side.  This solves the issue of multiple clicks on the button without the need for an alternative program flow.  However, this is less reliable since the user might still use their back button or a bookmark to revisit the page.&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://www.corej2eepatterns.com/Design/PresoDesign.htm Core J2EE Patterns]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25304</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25304"/>
		<updated>2009-10-10T01:35:50Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Example application */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
=== Java (with Struts) ===&lt;br /&gt;
&lt;br /&gt;
From [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The key methods in this implementation are saveToken(HttpServletRequest req), isTokenValid(HttpServletRequest req), and resetToken(HttpServletRequest req) which create, validate, and destroy tokens, respectively.&lt;br /&gt;
&lt;br /&gt;
=== Ruby on Rails ===&lt;br /&gt;
&lt;br /&gt;
A synchronizer token pattern could be easily implemented in Ruby on Rails by using before_filter and after_filter to perform token creation and invalidation at the appropriate times (create token before displaying the form page, invalidate token after taking the submit action).&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
Use of this pattern requires the programmer to consider another alternative flow for if the token is invalid.  Depending on the design decisions made this may complicate the program.  For example, if the user tries to submit a large amount of form data with an invalid token, the designer might want to preserve their entries while issuing a new token.  Failure to preserve entries might cause a user to give up and not follow through with their action on the site.  However, this is an additional feature that must then be designed, added, and tested.&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
The common alternative to the synchronizer token pattern is to simply use Javascript or similar to disable the &amp;quot;submit&amp;quot; button on the client side.  This solves the issue of multiple clicks on the button without the need for an alternative program flow.  However, this is less reliable since the user might still use their back button or a bookmark to revisit the page.&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://www.corej2eepatterns.com/Design/PresoDesign.htm Core J2EE Patterns]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25294</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25294"/>
		<updated>2009-10-10T01:32:44Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Example application */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
Java (with Struts) from [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A synchronizer token pattern could be easily implemented in Ruby on Rails by using before_filter and after_filter to perform token creation and invalidation at the appropriate times (create token before displaying the form page, invalidate token after taking the submit action).&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
Use of this pattern requires the programmer to consider another alternative flow for if the token is invalid.  Depending on the design decisions made this may complicate the program.  For example, if the user tries to submit a large amount of form data with an invalid token, the designer might want to preserve their entries while issuing a new token.  Failure to preserve entries might cause a user to give up and not follow through with their action on the site.  However, this is an additional feature that must then be designed, added, and tested.&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
The common alternative to the synchronizer token pattern is to simply use Javascript or similar to disable the &amp;quot;submit&amp;quot; button on the client side.  This solves the issue of multiple clicks on the button without the need for an alternative program flow.  However, this is less reliable since the user might still use their back button or a bookmark to revisit the page.&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://www.corej2eepatterns.com/Design/PresoDesign.htm Core J2EE Patterns]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25278</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25278"/>
		<updated>2009-10-10T01:28:16Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Example application */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
Java from [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A synchronizer token pattern could be easily implemented in Ruby on Rails by using before_filter and after_filter to perform token creation and invalidation at the appropriate times (create token before displaying the form page, invalidate token after taking the submit action).&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
Use of this pattern requires the programmer to consider another alternative flow for if the token is invalid.  Depending on the design decisions made this may complicate the program.  For example, if the user tries to submit a large amount of form data with an invalid token, the designer might want to preserve their entries while issuing a new token.  Failure to preserve entries might cause a user to give up and not follow through with their action on the site.  However, this is an additional feature that must then be designed, added, and tested.&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
The common alternative to the synchronizer token pattern is to simply use Javascript or similar to disable the &amp;quot;submit&amp;quot; button on the client side.  This solves the issue of multiple clicks on the button without the need for an alternative program flow.  However, this is less reliable since the user might still use their back button or a bookmark to revisit the page.&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://www.corej2eepatterns.com/Design/PresoDesign.htm Core J2EE Patterns]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25265</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25265"/>
		<updated>2009-10-10T01:24:22Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
Java from [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
Use of this pattern requires the programmer to consider another alternative flow for if the token is invalid.  Depending on the design decisions made this may complicate the program.  For example, if the user tries to submit a large amount of form data with an invalid token, the designer might want to preserve their entries while issuing a new token.  Failure to preserve entries might cause a user to give up and not follow through with their action on the site.  However, this is an additional feature that must then be designed, added, and tested.&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
The common alternative to the synchronizer token pattern is to simply use Javascript or similar to disable the &amp;quot;submit&amp;quot; button on the client side.  This solves the issue of multiple clicks on the button without the need for an alternative program flow.  However, this is less reliable since the user might still use their back button or a bookmark to revisit the page.&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://www.corej2eepatterns.com/Design/PresoDesign.htm Core J2EE Patterns]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25252</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25252"/>
		<updated>2009-10-10T01:19:24Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
Java from [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
Use of this pattern requires the programmer to consider another alternative flow for if the token is invalid.  Depending on the design decisions made this may complicate the program.  For example, if the user tries to submit a large amount of form data with an invalid token, the designer might want to preserve their entries while issuing a new token.  Failure to preserve entries might cause a user to give up and not follow through with their action on the site.  However, this is an additional feature that must then be designed, added, and tested.&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
The common alternative to the synchronizer token pattern is to simply use Javascript or similar to disable the &amp;quot;submit&amp;quot; button on the client side.  This solves the issue of multiple clicks on the button without the need for an alternative program flow.  However, this is less reliable since the user might still use their back button or a bookmark to revisit the page.&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25250</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25250"/>
		<updated>2009-10-10T01:18:20Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Critique */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
Java from [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
Use of this pattern requires the programmer to consider another alternative flow for if the token is invalid.  Depending on the design decisions made this may complicate the program.  For example, if the user tries to submit a large amount of form data with an invalid token, the designer might want to preserve their entries while issuing a new token.  Failure to preserve entries might cause a user to give up and not follow through with their action on the site.  However, this is an additional feature that must then be designed, added, and tested.&lt;br /&gt;
&lt;br /&gt;
The common alternative to the synchronizer token pattern is to simply use Javascript or similar to disable the &amp;quot;submit&amp;quot; button on the client side.  This solves the issue of multiple clicks on the button without the need for an alternative program flow.  However, this is less reliable since the user might still use their back button or a bookmark to revisit the page.&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25223</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25223"/>
		<updated>2009-10-10T01:08:20Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Example application */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
Java from [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 Java World]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25222</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25222"/>
		<updated>2009-10-10T01:08:09Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Example application */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
Java from [http://www.javaworld.com/javaworld/javatips/jw-javatip136.html?page=2 JavaWorld]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
public final ActionForward perform(ActionMapping mapping,&lt;br /&gt;
        ActionForm form,&lt;br /&gt;
        HttpServletRequest request,&lt;br /&gt;
        HttpServletResponse response)&lt;br /&gt;
    throws IOException, ServletException {&lt;br /&gt;
    HttpSession session = request.getSession();&lt;br /&gt;
    ActionForward forward = null;&lt;br /&gt;
    if (isTokenValid(request)) {&lt;br /&gt;
        // Reset token and session attributes&lt;br /&gt;
        reset(request);&lt;br /&gt;
        try {&lt;br /&gt;
            // Perform the action and store the results&lt;br /&gt;
            forward = performSynchro(mapping, form, request, response);&lt;br /&gt;
            session.setAttribute(FORM_KEY, form);&lt;br /&gt;
            session.setAttribute(FORWARD_KEY, forward);&lt;br /&gt;
            ActionErrors errors = (ActionErrors) &lt;br /&gt;
                        request.getAttribute(Action.ERROR_KEY);&lt;br /&gt;
            if (errors != null &amp;amp;&amp;amp; !errors.empty()) {&lt;br /&gt;
                saveToken(request);&lt;br /&gt;
            }&lt;br /&gt;
            session.setAttribute(ERRORS_KEY, errors);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
        } catch (IOException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        } catch (ServletException e) {&lt;br /&gt;
            // Store and rethrow the exception&lt;br /&gt;
            session.setAttribute(EXCEPTION_KEY, e);&lt;br /&gt;
            session.setAttribute(COMPLETE_KEY, &amp;quot;true&amp;quot;);&lt;br /&gt;
            throw e;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        // If the action is complete&lt;br /&gt;
        if (&amp;quot;true&amp;quot;.equals(session.getAttribute(COMPLETE_KEY))) {&lt;br /&gt;
            // Obtain the exception from the session&lt;br /&gt;
            Exception e = (Exception) session.getAttribute(EXCEPTION_KEY);&lt;br /&gt;
            // If it is not null, throw it&lt;br /&gt;
            if (e != null) {&lt;br /&gt;
                if (e instanceof IOException) {&lt;br /&gt;
                    throw (IOException) e;&lt;br /&gt;
                } else if (e instanceof ServletException) {&lt;br /&gt;
                    throw (ServletException) e;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain the form from the session&lt;br /&gt;
            ActionForm f = (ActionForm) session.getAttribute(FORM_KEY);&lt;br /&gt;
            // Set it in the appropriate context&lt;br /&gt;
            if (&amp;quot;request&amp;quot;.equals(mapping.getScope())) {&lt;br /&gt;
                request.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            } else {&lt;br /&gt;
                session.setAttribute(mapping.getAttribute(), f);&lt;br /&gt;
            }&lt;br /&gt;
            // Obtain and save the errors from the session&lt;br /&gt;
            saveErrors(request, (ActionErrors)&lt;br /&gt;
                    session.getAttribute(ERRORS_KEY));&lt;br /&gt;
            // Obtain the forward from the session&lt;br /&gt;
            forward = (ActionForward) session.getAttribute(FORWARD_KEY);&lt;br /&gt;
        } else {&lt;br /&gt;
            // Perform the appropriate action in case of token error&lt;br /&gt;
            forward = performInvalidToken(mapping, form, request, response);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return forward;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25209</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25209"/>
		<updated>2009-10-10T01:02:59Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25207</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25207"/>
		<updated>2009-10-10T01:01:33Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://www.coderanch.com/t/51602/Struts/Duplicate-form-submission-Synchronizer-Token Code Ranch]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25205</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25205"/>
		<updated>2009-10-10T01:01:18Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&lt;br /&gt;
[http://www.coderanch.com/t/51602/Struts/Duplicate-form-submission-Synchronizer-Token Code Ranch]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25183</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25183"/>
		<updated>2009-10-10T00:54:00Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Synchronizer Token pattern is a server side solution to this problem.  The concept is fairly simple:  Establish a token on the server side that indicates a valid submission, and give a token signature to the client that corresponds to that token (most likely in a hidden input field).  When the client submits their form, the server validates their token and proceeds.  It then marks the token as invalid so it may not be used again.  The result is that any given form may only be used once and then will not work again.&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25141</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25141"/>
		<updated>2009-10-10T00:45:07Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Problem summary */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
Many websites rely on synchronous activity between the client and server.  This synchronization can be disrupted if the client takes actions in an order not expected by the server.  For instance, when submitting a purchase in an online store, the client might click the &amp;quot;Purchase&amp;quot; button multiple times.  They might hit their browser's back button and take another action while the transaction is still processing.  These types of actions could produce unpredictable results and must be protected against.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25057</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=25057"/>
		<updated>2009-10-10T00:34:07Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
[http://www.javaworld.com/javaworld/javatips/jw-javatip136.html Java World Tip 136]&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=24407</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=24407"/>
		<updated>2009-10-09T20:34:02Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: Possible layout&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;br /&gt;
&lt;br /&gt;
== Problem summary ==&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
== Example application ==&lt;br /&gt;
&lt;br /&gt;
== Critique ==&lt;br /&gt;
&lt;br /&gt;
== Other solutions ==&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=24404</id>
		<title>CSC/ECE 517 Fall 2009/wiki2 3 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki2_3_b5&amp;diff=24404"/>
		<updated>2009-10-09T20:30:26Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: Getting started&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Synchronizer Token Pattern =&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=22131</id>
		<title>CSC/ECE 517 Fall 2009/wiki1b 7 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=22131"/>
		<updated>2009-09-28T02:25:44Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Other Libraries of Interest */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Resources for Ruby (other than IDEs) =&lt;br /&gt;
&lt;br /&gt;
== Language Resources ==&lt;br /&gt;
&lt;br /&gt;
=== [http://www.ruby-lang.org/en/ The Ruby Homepage] ===&lt;br /&gt;
The main page for the Ruby language provides the installation files, documentation, and useful resources.  Also, for any questions not answered by the following resources you can try the Community tab.  There you'll find a list of Ruby community sites where you can get additional support and information.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.sapphiresteel.com/The-Little-Book-Of-Ruby The Little Book of Ruby] ===&lt;br /&gt;
The Little Book of Ruby is an introduction to Ruby that quickly gets you started with Ruby programming.  At only 90 pages (.pdf) and using simple, clear language, it's a very quick read.  It assumes the reader has prior programming experience, though not necessarily in an object oriented language.  All of the code used in the book is also available online.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.zenspider.com/Languages/Ruby/QuickRef.html Ruby QuickRef] ===&lt;br /&gt;
Ruby QuickRef is an excellent resource for quickly looking up Ruby syntax.  Rather than giving paragraphs of explanation and loads of examples, it simply provides the syntax in a well sectioned and easy to read format.  Think of it as a Ruby cheat sheet.&lt;br /&gt;
&lt;br /&gt;
=== [http://rubylearning.com/ RubyLearning] ===&lt;br /&gt;
The tutorial on RubyLearning provides more and larger code samples than the Little Book of Ruby.  It also covers a few more niche topics.  In particular note the &amp;quot;summary&amp;quot; pages, which provide a quick checklist of topics covered in the preceding sections.  Skimming the summary pages will let you quickly decide if there's any new material to learn without having to read the whole thing.  The direct link to the tutorial is [http://rubylearning.com/satishtalim/tutorial.html here].&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
=== [http://cukes.info/ Cucumber] ===&lt;br /&gt;
Cucumber allows black box tests to be written in plain English, making test documentation and comprehension much easier.  It also inherently promotes evaluation of the business value of the things you are testing, which is always a good idea.&lt;br /&gt;
&lt;br /&gt;
=== [http://wtr.rubyforge.org/ Watir] ===&lt;br /&gt;
Watir and its sister projects give you hooks into various web browsers for web based black box testing.  Alternatively, [http://celerity.rubyforge.org/ Celerity] allows testing without requiring a browser, which results in faster, platform independent tests.&lt;br /&gt;
&lt;br /&gt;
== Debugging ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/projects/ruby-debug/ ruby-debug] ===&lt;br /&gt;
ruby-debug allows for easy command line debugging, which is helpful for those of us who still cling to text editors.  The screencast available at [http://brian.maybeyoureinsane.net/blog/2007/05/07/ruby-debug-basics-screencast/ this location] does an excellent overview of what ruby-debug can do.&lt;br /&gt;
&lt;br /&gt;
=== [http://www2.aptana.com/docs/index.php/Ruby_Debugger Aptana] ===&lt;br /&gt;
This is the Aptana documentation on using the ruby-debug-ide gem with Eclipse.  It provides step by step images depicting a debug session.&lt;br /&gt;
&lt;br /&gt;
== Other Libraries of Interest ==&lt;br /&gt;
&lt;br /&gt;
=== [http://hanklords.github.com/flickraw/ Flickraw] ===&lt;br /&gt;
Flickraw provides a Ruby interface to the Flickr API.  The Flickr API allows many operations like search, photo upload, and creation of photosets.&lt;br /&gt;
&lt;br /&gt;
=== [http://twitter.rubyforge.org/ Twitter] ===&lt;br /&gt;
The Twitter Ruby gem provides a Ruby interface to the Ruby API.  Similar to Flickraw, this gem allows the common Twitter operations to be executed in a Ruby environment.&lt;br /&gt;
&lt;br /&gt;
== Ruby Projects ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/ RubyForge] ===&lt;br /&gt;
RubyForge is basically SourceForge for only Ruby based projects.  Learn about Ruby and Ruby development by seeing actual applications of the language, or contribute your own knowledge to a project.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=22126</id>
		<title>CSC/ECE 517 Fall 2009/wiki1b 7 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=22126"/>
		<updated>2009-09-28T01:28:54Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Resources for Ruby (other than IDEs) =&lt;br /&gt;
&lt;br /&gt;
== Language Resources ==&lt;br /&gt;
&lt;br /&gt;
=== [http://www.ruby-lang.org/en/ The Ruby Homepage] ===&lt;br /&gt;
The main page for the Ruby language provides the installation files, documentation, and useful resources.  Also, for any questions not answered by the following resources you can try the Community tab.  There you'll find a list of Ruby community sites where you can get additional support and information.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.sapphiresteel.com/The-Little-Book-Of-Ruby The Little Book of Ruby] ===&lt;br /&gt;
The Little Book of Ruby is an introduction to Ruby that quickly gets you started with Ruby programming.  At only 90 pages (.pdf) and using simple, clear language, it's a very quick read.  It assumes the reader has prior programming experience, though not necessarily in an object oriented language.  All of the code used in the book is also available online.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.zenspider.com/Languages/Ruby/QuickRef.html Ruby QuickRef] ===&lt;br /&gt;
Ruby QuickRef is an excellent resource for quickly looking up Ruby syntax.  Rather than giving paragraphs of explanation and loads of examples, it simply provides the syntax in a well sectioned and easy to read format.  Think of it as a Ruby cheat sheet.&lt;br /&gt;
&lt;br /&gt;
=== [http://rubylearning.com/ RubyLearning] ===&lt;br /&gt;
The tutorial on RubyLearning provides more and larger code samples than the Little Book of Ruby.  It also covers a few more niche topics.  In particular note the &amp;quot;summary&amp;quot; pages, which provide a quick checklist of topics covered in the preceding sections.  Skimming the summary pages will let you quickly decide if there's any new material to learn without having to read the whole thing.  The direct link to the tutorial is [http://rubylearning.com/satishtalim/tutorial.html here].&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
=== [http://cukes.info/ Cucumber] ===&lt;br /&gt;
Cucumber allows black box tests to be written in plain English, making test documentation and comprehension much easier.  It also inherently promotes evaluation of the business value of the things you are testing, which is always a good idea.&lt;br /&gt;
&lt;br /&gt;
=== [http://wtr.rubyforge.org/ Watir] ===&lt;br /&gt;
Watir and its sister projects give you hooks into various web browsers for web based black box testing.  Alternatively, [http://celerity.rubyforge.org/ Celerity] allows testing without requiring a browser, which results in faster, platform independent tests.&lt;br /&gt;
&lt;br /&gt;
== Debugging ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/projects/ruby-debug/ ruby-debug] ===&lt;br /&gt;
ruby-debug allows for easy command line debugging, which is helpful for those of us who still cling to text editors.  The screencast available at [http://brian.maybeyoureinsane.net/blog/2007/05/07/ruby-debug-basics-screencast/ this location] does an excellent overview of what ruby-debug can do.&lt;br /&gt;
&lt;br /&gt;
=== [http://www2.aptana.com/docs/index.php/Ruby_Debugger Aptana] ===&lt;br /&gt;
This is the Aptana documentation on using the ruby-debug-ide gem with Eclipse.  It provides step by step images depicting a debug session.&lt;br /&gt;
&lt;br /&gt;
== Other Libraries of Interest ==&lt;br /&gt;
&lt;br /&gt;
=== [http://hanklords.github.com/flickraw/ Flickraw] ===&lt;br /&gt;
Flickraw provides a Ruby interface to the Flickr API.  The Flickr API allows many operations like search, photo upload, and creation of photosets.&lt;br /&gt;
&lt;br /&gt;
== Ruby Projects ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/ RubyForge] ===&lt;br /&gt;
RubyForge is basically SourceForge for only Ruby based projects.  Learn about Ruby and Ruby development by seeing actual applications of the language, or contribute your own knowledge to a project.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=22103</id>
		<title>CSC/ECE 517 Fall 2009/wiki1b 7 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=22103"/>
		<updated>2009-09-28T00:30:52Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Language Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Resources for Ruby (other than IDEs) =&lt;br /&gt;
&lt;br /&gt;
== Language Resources ==&lt;br /&gt;
&lt;br /&gt;
=== [http://www.ruby-lang.org/en/ The Ruby Homepage] ===&lt;br /&gt;
The main page for the Ruby language provides the installation files, documentation, and useful resources.  Also, for any questions not answered by the following resources you can try the Community tab.  There you'll find a list of Ruby community sites where you can get additional support and information.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.sapphiresteel.com/The-Little-Book-Of-Ruby The Little Book of Ruby] ===&lt;br /&gt;
The Little Book of Ruby is an introduction to Ruby that quickly gets you started with Ruby programming.  At only 90 pages (.pdf) and using simple, clear language, it's a very quick read.  It assumes the reader has prior programming experience, though not necessarily in an object oriented language.  All of the code used in the book is also available online.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.zenspider.com/Languages/Ruby/QuickRef.html Ruby QuickRef] ===&lt;br /&gt;
Ruby QuickRef is an excellent resource for quickly looking up Ruby syntax.  Rather than giving paragraphs of explanation and loads of examples, it simply provides the syntax in a well sectioned and easy to read format.  Think of it as a Ruby cheat sheet.&lt;br /&gt;
&lt;br /&gt;
=== [http://rubylearning.com/ RubyLearning] ===&lt;br /&gt;
The tutorial on RubyLearning provides more and larger code samples than the Little Book of Ruby.  It also covers a few more niche topics.  In particular note the &amp;quot;summary&amp;quot; pages, which provide a quick checklist of topics covered in the preceding sections.  Skimming the summary pages will let you quickly decide if there's any new material to learn without having to read the whole thing.  The direct link to the tutorial is [http://rubylearning.com/satishtalim/tutorial.html here].&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
=== [http://cukes.info/ Cucumber] ===&lt;br /&gt;
Cucumber allows black box tests to be written in plain English, making test documentation and comprehension much easier.  It also inherently promotes evaluation of the business value of the things you are testing, which is always a good idea.&lt;br /&gt;
&lt;br /&gt;
=== [http://wtr.rubyforge.org/ Watir] ===&lt;br /&gt;
Watir and its sister projects give you hooks into various web browsers for web based black box testing.  Alternatively, [http://celerity.rubyforge.org/ Celerity] allows testing without requiring a browser, which results in faster, platform independent tests.&lt;br /&gt;
&lt;br /&gt;
== Debugging ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/projects/ruby-debug/ ruby-debug] ===&lt;br /&gt;
ruby-debug allows for easy command line debugging, which is helpful for those of us who still cling to text editors.  The screencast available at [http://brian.maybeyoureinsane.net/blog/2007/05/07/ruby-debug-basics-screencast/ this location] does an excellent overview of what ruby-debug can do.&lt;br /&gt;
&lt;br /&gt;
=== [http://www2.aptana.com/docs/index.php/Ruby_Debugger Aptana] ===&lt;br /&gt;
This is the Aptana documentation on using the ruby-debug-ide gem with Eclipse.  It provides step by step images depicting a debug session.&lt;br /&gt;
&lt;br /&gt;
== Ruby Projects ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/ RubyForge] ===&lt;br /&gt;
RubyForge is basically SourceForge for only Ruby based projects.  Learn about Ruby and Ruby development by seeing actual applications of the language, or contribute your own knowledge to a project.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20959</id>
		<title>CSC/ECE 517 Fall 2009/wiki1b 7 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20959"/>
		<updated>2009-09-21T07:10:58Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Debugging */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Resources for Ruby (other than IDEs) =&lt;br /&gt;
&lt;br /&gt;
== Language Resources ==&lt;br /&gt;
&lt;br /&gt;
=== [http://www.sapphiresteel.com/The-Little-Book-Of-Ruby The Little Book of Ruby] ===&lt;br /&gt;
The Little Book of Ruby is an introduction to Ruby that quickly gets you started with Ruby programming.  At only 90 pages (.pdf) and using simple, clear language, it's a very quick read.  It assumes the reader has prior programming experience, though not necessarily in an object oriented language.  All of the code used in the book is also available online.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.zenspider.com/Languages/Ruby/QuickRef.html Ruby QuickRef] ===&lt;br /&gt;
Ruby QuickRef is an excellent resource for quickly looking up Ruby syntax.  Rather than giving paragraphs of explanation and loads of examples, it simply provides the syntax in a well sectioned and easy to read format.  Think of it as a Ruby cheat sheet.&lt;br /&gt;
&lt;br /&gt;
=== [http://rubylearning.com/ RubyLearning] ===&lt;br /&gt;
The tutorial on RubyLearning provides more and larger code samples than the Little Book of Ruby.  It also covers a few more niche topics.  In particular note the &amp;quot;summary&amp;quot; pages, which provide a quick checklist of topics covered in the preceding sections.  Skimming the summary pages will let you quickly decide if there's any new material to learn without having to read the whole thing.  The direct link to the tutorial is [http://rubylearning.com/satishtalim/tutorial.html here].&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
=== [http://cukes.info/ Cucumber] ===&lt;br /&gt;
Cucumber allows black box tests to be written in plain English, making test documentation and comprehension much easier.  It also inherently promotes evaluation of the business value of the things you are testing, which is always a good idea.&lt;br /&gt;
&lt;br /&gt;
=== [http://wtr.rubyforge.org/ Watir] ===&lt;br /&gt;
Watir and its sister projects give you hooks into various web browsers for web based black box testing.  Alternatively, [http://celerity.rubyforge.org/ Celerity] allows testing without requiring a browser, which results in faster, platform independent tests.&lt;br /&gt;
&lt;br /&gt;
== Debugging ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/projects/ruby-debug/ ruby-debug] ===&lt;br /&gt;
ruby-debug allows for easy command line debugging, which is helpful for those of us who still cling to text editors.  The screencast available at [http://brian.maybeyoureinsane.net/blog/2007/05/07/ruby-debug-basics-screencast/ this location] does an excellent overview of what ruby-debug can do.&lt;br /&gt;
&lt;br /&gt;
=== [http://www2.aptana.com/docs/index.php/Ruby_Debugger Aptana] ===&lt;br /&gt;
This is the Aptana documentation on using the ruby-debug-ide gem with Eclipse.  It provides step by step images depicting a debug session.&lt;br /&gt;
&lt;br /&gt;
== Ruby Projects ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/ RubyForge] ===&lt;br /&gt;
RubyForge is basically SourceForge for only Ruby based projects.  Learn about Ruby and Ruby development by seeing actual applications of the language, or contribute your own knowledge to a project.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20957</id>
		<title>CSC/ECE 517 Fall 2009/wiki1b 7 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20957"/>
		<updated>2009-09-21T06:59:01Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Resources for Ruby (other than IDEs) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Resources for Ruby (other than IDEs) =&lt;br /&gt;
&lt;br /&gt;
== Language Resources ==&lt;br /&gt;
&lt;br /&gt;
=== [http://www.sapphiresteel.com/The-Little-Book-Of-Ruby The Little Book of Ruby] ===&lt;br /&gt;
The Little Book of Ruby is an introduction to Ruby that quickly gets you started with Ruby programming.  At only 90 pages (.pdf) and using simple, clear language, it's a very quick read.  It assumes the reader has prior programming experience, though not necessarily in an object oriented language.  All of the code used in the book is also available online.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.zenspider.com/Languages/Ruby/QuickRef.html Ruby QuickRef] ===&lt;br /&gt;
Ruby QuickRef is an excellent resource for quickly looking up Ruby syntax.  Rather than giving paragraphs of explanation and loads of examples, it simply provides the syntax in a well sectioned and easy to read format.  Think of it as a Ruby cheat sheet.&lt;br /&gt;
&lt;br /&gt;
=== [http://rubylearning.com/ RubyLearning] ===&lt;br /&gt;
The tutorial on RubyLearning provides more and larger code samples than the Little Book of Ruby.  It also covers a few more niche topics.  In particular note the &amp;quot;summary&amp;quot; pages, which provide a quick checklist of topics covered in the preceding sections.  Skimming the summary pages will let you quickly decide if there's any new material to learn without having to read the whole thing.  The direct link to the tutorial is [http://rubylearning.com/satishtalim/tutorial.html here].&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
=== [http://cukes.info/ Cucumber] ===&lt;br /&gt;
Cucumber allows black box tests to be written in plain English, making test documentation and comprehension much easier.  It also inherently promotes evaluation of the business value of the things you are testing, which is always a good idea.&lt;br /&gt;
&lt;br /&gt;
=== [http://wtr.rubyforge.org/ Watir] ===&lt;br /&gt;
Watir and its sister projects give you hooks into various web browsers for web based black box testing.  Alternatively, [http://celerity.rubyforge.org/ Celerity] allows testing without requiring a browser, which results in faster, platform independent tests.&lt;br /&gt;
&lt;br /&gt;
== Debugging ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/projects/ruby-debug/ ruby-debug] ===&lt;br /&gt;
ruby-debug allows for easy command line debugging, which is helpful for those of us who still cling to text editors.  The screencast available at [http://brian.maybeyoureinsane.net/blog/2007/05/07/ruby-debug-basics-screencast/ this location] does an excellent overview of what ruby-debug can do.&lt;br /&gt;
&lt;br /&gt;
== Ruby Projects ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/ RubyForge] ===&lt;br /&gt;
RubyForge is basically SourceForge for only Ruby based projects.  Learn about Ruby and Ruby development by seeing actual applications of the language, or contribute your own knowledge to a project.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20954</id>
		<title>CSC/ECE 517 Fall 2009/wiki1b 7 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20954"/>
		<updated>2009-09-21T06:45:49Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Useful Gems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Resources for Ruby (other than IDEs) =&lt;br /&gt;
&lt;br /&gt;
== Language Resources ==&lt;br /&gt;
&lt;br /&gt;
=== [http://www.sapphiresteel.com/The-Little-Book-Of-Ruby The Little Book of Ruby] ===&lt;br /&gt;
The Little Book of Ruby is an introduction to Ruby that quickly gets you started with Ruby programming.  At only 90 pages (.pdf) and using simple, clear language, it's a very quick read.  It assumes the reader has prior programming experience, though not necessarily in an object oriented language.  All of the code used in the book is also available online.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.zenspider.com/Languages/Ruby/QuickRef.html Ruby QuickRef] ===&lt;br /&gt;
Ruby QuickRef is an excellent resource for quickly looking up Ruby syntax.  Rather than giving paragraphs of explanation and loads of examples, it simply provides the syntax in a well sectioned and easy to read format.  Think of it as a Ruby cheat sheet.&lt;br /&gt;
&lt;br /&gt;
=== [http://rubylearning.com/ RubyLearning] ===&lt;br /&gt;
The tutorial on RubyLearning provides more and larger code samples than the Little Book of Ruby.  It also covers a few more niche topics.  In particular note the &amp;quot;summary&amp;quot; pages, which provide a quick checklist of topics covered in the preceding sections.  Skimming the summary pages will let you quickly decide if there's any new material to learn without having to read the whole thing.  The direct link to the tutorial is [http://rubylearning.com/satishtalim/tutorial.html here].&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
=== [http://cukes.info/ Cucumber] ===&lt;br /&gt;
Cucumber allows black box tests to be written in plain English, making test documentation and comprehension much easier.  It also inherently promotes evaluation of the business value of the things you are testing, which is always a good idea.&lt;br /&gt;
&lt;br /&gt;
=== [http://wtr.rubyforge.org/ Watir] ===&lt;br /&gt;
Watir and its sister projects give you hooks into various web browsers for web based black box testing.  Alternatively, [http://celerity.rubyforge.org/ Celerity] allows testing without requiring a browser, which results in faster, platform independent tests.&lt;br /&gt;
&lt;br /&gt;
== Ruby Projects ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/ RubyForge] ===&lt;br /&gt;
RubyForge is basically SourceForge for only Ruby based projects.  Learn about Ruby and Ruby development by seeing actual applications of the language, or contribute your own knowledge to a project.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20953</id>
		<title>CSC/ECE 517 Fall 2009/wiki1b 7 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20953"/>
		<updated>2009-09-21T06:41:12Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Useful Gems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Resources for Ruby (other than IDEs) =&lt;br /&gt;
&lt;br /&gt;
== Language Resources ==&lt;br /&gt;
&lt;br /&gt;
=== [http://www.sapphiresteel.com/The-Little-Book-Of-Ruby The Little Book of Ruby] ===&lt;br /&gt;
The Little Book of Ruby is an introduction to Ruby that quickly gets you started with Ruby programming.  At only 90 pages (.pdf) and using simple, clear language, it's a very quick read.  It assumes the reader has prior programming experience, though not necessarily in an object oriented language.  All of the code used in the book is also available online.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.zenspider.com/Languages/Ruby/QuickRef.html Ruby QuickRef] ===&lt;br /&gt;
Ruby QuickRef is an excellent resource for quickly looking up Ruby syntax.  Rather than giving paragraphs of explanation and loads of examples, it simply provides the syntax in a well sectioned and easy to read format.  Think of it as a Ruby cheat sheet.&lt;br /&gt;
&lt;br /&gt;
=== [http://rubylearning.com/ RubyLearning] ===&lt;br /&gt;
The tutorial on RubyLearning provides more and larger code samples than the Little Book of Ruby.  It also covers a few more niche topics.  In particular note the &amp;quot;summary&amp;quot; pages, which provide a quick checklist of topics covered in the preceding sections.  Skimming the summary pages will let you quickly decide if there's any new material to learn without having to read the whole thing.  The direct link to the tutorial is [http://rubylearning.com/satishtalim/tutorial.html here].&lt;br /&gt;
&lt;br /&gt;
== Useful Gems ==&lt;br /&gt;
&lt;br /&gt;
=== [http://cukes.info/ Cucumber] ===&lt;br /&gt;
Cucumber allows black box tests to be written in plain English, making test documentation and comprehension much easier.  It also inherently promotes evaluation of the business value of the things you are testing, which is always a good idea.&lt;br /&gt;
&lt;br /&gt;
== Ruby Projects ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/ RubyForge] ===&lt;br /&gt;
RubyForge is basically SourceForge for only Ruby based projects.  Learn about Ruby and Ruby development by seeing actual applications of the language, or contribute your own knowledge to a project.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20950</id>
		<title>CSC/ECE 517 Fall 2009/wiki1b 7 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20950"/>
		<updated>2009-09-21T06:31:50Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Resources for Ruby (other than IDEs) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Resources for Ruby (other than IDEs) =&lt;br /&gt;
&lt;br /&gt;
== Language Resources ==&lt;br /&gt;
&lt;br /&gt;
=== [http://www.sapphiresteel.com/The-Little-Book-Of-Ruby The Little Book of Ruby] ===&lt;br /&gt;
The Little Book of Ruby is an introduction to Ruby that quickly gets you started with Ruby programming.  At only 90 pages (.pdf) and using simple, clear language, it's a very quick read.  It assumes the reader has prior programming experience, though not necessarily in an object oriented language.  All of the code used in the book is also available online.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.zenspider.com/Languages/Ruby/QuickRef.html Ruby QuickRef] ===&lt;br /&gt;
Ruby QuickRef is an excellent resource for quickly looking up Ruby syntax.  Rather than giving paragraphs of explanation and loads of examples, it simply provides the syntax in a well sectioned and easy to read format.  Think of it as a Ruby cheat sheet.&lt;br /&gt;
&lt;br /&gt;
=== [http://rubylearning.com/ RubyLearning] ===&lt;br /&gt;
The tutorial on RubyLearning provides more and larger code samples than the Little Book of Ruby.  It also covers a few more niche topics.  In particular note the &amp;quot;summary&amp;quot; pages, which provide a quick checklist of topics covered in the preceding sections.  Skimming the summary pages will let you quickly decide if there's any new material to learn without having to read the whole thing.  The direct link to the tutorial is [http://rubylearning.com/satishtalim/tutorial.html here].&lt;br /&gt;
&lt;br /&gt;
== Useful Gems ==&lt;br /&gt;
&lt;br /&gt;
== Ruby Projects ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/ RubyForge] ===&lt;br /&gt;
RubyForge is basically SourceForge for only Ruby based projects.  Learn about Ruby and Ruby development by seeing actual applications of the language, or contribute your own knowledge to a project.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20939</id>
		<title>CSC/ECE 517 Fall 2009/wiki1b 7 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20939"/>
		<updated>2009-09-21T06:10:39Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Plugins */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Resources for Ruby (other than IDEs) =&lt;br /&gt;
&lt;br /&gt;
== Language Resources ==&lt;br /&gt;
&lt;br /&gt;
=== [http://www.sapphiresteel.com/The-Little-Book-Of-Ruby The Little Book of Ruby] ===&lt;br /&gt;
The Little Book of Ruby is an introduction to Ruby that quickly gets you started with Ruby programming.  At only 90 pages (.pdf) and using simple, clear language, it's a very quick read.  It assumes the reader has prior programming experience, though not necessarily in an object oriented language.  All of the code used in the book is also available online.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.zenspider.com/Languages/Ruby/QuickRef.html Ruby QuickRef] ===&lt;br /&gt;
Ruby QuickRef is an excellent resource for quickly looking up Ruby syntax.  Rather than giving paragraphs of explanation and loads of examples, it simply provides the syntax in a well sectioned and easy to read format.  Think of it as a Ruby cheat sheet.&lt;br /&gt;
&lt;br /&gt;
=== [http://rubylearning.com/ RubyLearning] ===&lt;br /&gt;
The tutorial on RubyLearning provides more and larger code samples than the Little Book of Ruby.  It also covers a few more niche topics.  In particular note the &amp;quot;summary&amp;quot; pages, which provide a quick checklist of topics covered in the preceding sections.  Skimming the summary pages will let you quickly decide if there's any new material to learn without having to read the whole thing.  The direct link to the tutorial is [http://rubylearning.com/satishtalim/tutorial.html here].&lt;br /&gt;
&lt;br /&gt;
== Ruby Projects ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/ RubyForge] ===&lt;br /&gt;
RubyForge is basically SourceForge for only Ruby based projects.  Learn about Ruby and Ruby development by seeing actual applications of the language, or contribute your own knowledge to a project.&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20933</id>
		<title>CSC/ECE 517 Fall 2009/wiki1b 7 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20933"/>
		<updated>2009-09-21T06:03:05Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Language Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Resources for Ruby (other than IDEs) =&lt;br /&gt;
&lt;br /&gt;
== Language Resources ==&lt;br /&gt;
&lt;br /&gt;
=== [http://www.sapphiresteel.com/The-Little-Book-Of-Ruby The Little Book of Ruby] ===&lt;br /&gt;
The Little Book of Ruby is an introduction to Ruby that quickly gets you started with Ruby programming.  At only 90 pages (.pdf) and using simple, clear language, it's a very quick read.  It assumes the reader has prior programming experience, though not necessarily in an object oriented language.  All of the code used in the book is also available online.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.zenspider.com/Languages/Ruby/QuickRef.html Ruby QuickRef] ===&lt;br /&gt;
Ruby QuickRef is an excellent resource for quickly looking up Ruby syntax.  Rather than giving paragraphs of explanation and loads of examples, it simply provides the syntax in a well sectioned and easy to read format.  Think of it as a Ruby cheat sheet.&lt;br /&gt;
&lt;br /&gt;
=== [http://rubylearning.com/ RubyLearning] ===&lt;br /&gt;
The tutorial on RubyLearning provides more and larger code samples than the Little Book of Ruby.  It also covers a few more niche topics.  In particular note the &amp;quot;summary&amp;quot; pages, which provide a quick checklist of topics covered in the preceding sections.  Skimming the summary pages will let you quickly decide if there's any new material to learn without having to read the whole thing.  The direct link to the tutorial is [http://rubylearning.com/satishtalim/tutorial.html here].&lt;br /&gt;
&lt;br /&gt;
== Plugins ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/ RubyForge] ===&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20931</id>
		<title>CSC/ECE 517 Fall 2009/wiki1b 7 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20931"/>
		<updated>2009-09-21T05:54:50Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Language Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Resources for Ruby (other than IDEs) =&lt;br /&gt;
&lt;br /&gt;
== Language Resources ==&lt;br /&gt;
&lt;br /&gt;
=== [http://www.sapphiresteel.com/The-Little-Book-Of-Ruby The Little Book of Ruby] ===&lt;br /&gt;
The Little Book of Ruby is an introduction to Ruby that quickly gets you started with Ruby programming.  At only 90 pages (.pdf) and using simple, clear language, it's a very quick read.  It assumes the reader has prior programming experience, though not necessarily in an object oriented language.  All of the code used in the book is also available online.&lt;br /&gt;
&lt;br /&gt;
=== [http://www.zenspider.com/Languages/Ruby/QuickRef.html Ruby QuickRef] ===&lt;br /&gt;
Ruby QuickRef is an excellent resource for quickly looking up Ruby syntax.  Rather than giving paragraphs of explanation and loads of examples, it simply provides the syntax in a well sectioned and easy to read format.  Think of it as a Ruby cheat sheet.&lt;br /&gt;
&lt;br /&gt;
=== [http://rubylearning.com/ RubyLearning] ===&lt;br /&gt;
&lt;br /&gt;
== Plugins ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/ RubyForge] ===&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20926</id>
		<title>CSC/ECE 517 Fall 2009/wiki1b 7 b5</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2009/wiki1b_7_b5&amp;diff=20926"/>
		<updated>2009-09-21T05:44:00Z</updated>

		<summary type="html">&lt;p&gt;Chump Chief: /* Language Resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Resources for Ruby (other than IDEs) =&lt;br /&gt;
&lt;br /&gt;
== Language Resources ==&lt;br /&gt;
&lt;br /&gt;
=== [http://www.sapphiresteel.com/The-Little-Book-Of-Ruby The Little Book of Ruby] ===&lt;br /&gt;
&lt;br /&gt;
=== [http://www.zenspider.com/Languages/Ruby/QuickRef.html Ruby QuickRef] ===&lt;br /&gt;
Ruby QuickRef is an excellent resource for quickly looking up Ruby syntax.  Rather than giving paragraphs of explanation and loads of examples, it simply provides the syntax in a well sectioned and easy to read format.  Think of it as a Ruby cheat sheet.&lt;br /&gt;
&lt;br /&gt;
=== [http://rubylearning.com/ RubyLearning] ===&lt;br /&gt;
&lt;br /&gt;
== Plugins ==&lt;br /&gt;
&lt;br /&gt;
=== [http://rubyforge.org/ RubyForge] ===&lt;/div&gt;</summary>
		<author><name>Chump Chief</name></author>
	</entry>
</feed>