<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>The Rogue Coder</title>
	<atom:link href="http://roguecoder.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://roguecoder.wordpress.com</link>
	<description></description>
	<lastBuildDate>Tue, 17 Jan 2012 13:57:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='roguecoder.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>The Rogue Coder</title>
		<link>http://roguecoder.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://roguecoder.wordpress.com/osd.xml" title="The Rogue Coder" />
	<atom:link rel='hub' href='http://roguecoder.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Mule 2.2.1 Request to Web Service with CXF</title>
		<link>http://roguecoder.wordpress.com/2011/06/04/mule-2-2-1-request-to-web-service-with-cxf/</link>
		<comments>http://roguecoder.wordpress.com/2011/06/04/mule-2-2-1-request-to-web-service-with-cxf/#comments</comments>
		<pubDate>Sat, 04 Jun 2011 16:31:06 +0000</pubDate>
		<dc:creator>roguecoder</dc:creator>
				<category><![CDATA[Mule]]></category>

		<guid isPermaLink="false">http://roguecoder.wordpress.com/?p=466</guid>
		<description><![CDATA[This a simple Mule 2.2.1 configuration to demonstrate calling a remote web service.  This article is not an in-depth discussion of mule and will not contain complete code examples. The intended purpose is a quick and simple demonstration.  To learn more about Mule visit http://mulesoft.org. On a side note, there is a Mule plugin for [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=466&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This a simple Mule 2.2.1 configuration to demonstrate calling a remote web service.  This article is not an in-depth discussion of mule and will not contain complete code examples. The intended purpose is a quick and simple demonstration.  To learn more about Mule visit <a href="http://mulesoft.org">http://mulesoft.org</a>.</p>
<p>On a side note, there is a Mule plugin for Eclipse available <a href="http://www.mulesoft.org/documentation/display/MULEIDE/Mule+IDE+2.0+Installation+Guide">here</a>.  The plugin allows you to create a Mule project in Eclipse which adds all of the Mule libraries to your project class path, adds your project to Mule&#8217;s runtime classpath and allows you to right click your Mule configuration file then select Run As/Debug As -&gt; Mule Server.  Running Mule from Eclipse gives you the ability to add break points to any of your supporting classes such as custom transformers or Mule components.</p>
<p>Our fictional web service will be a weather service that returns the weather for a supplied ZIP code.  The weather service endpoint interface (SEI) has a method with the following signature: public Weather getWeather(String zipCode).  By accepting a String this can be easily tested using the Mule standard IO connector without any data type transformers.</p>
<p>To run this example you will need to create a simple contrived web service with the getWeather method and a client using Apache CXF.  Your generated client must be on Mule&#8217;s runtime class path.  You can put the client on Mule&#8217;s classpath by creating a jar file and dropping it in $MULE_HOME/lib/user or, for testing purposes, make your generated client part of your Mule project in Eclipse.  To run Mule with your configuration file run the command $MULE_HOME/bin/mule -config /path/to/my/mule/config.xml or from Eclipse right click your Mule config file then click Run As -&gt; Mule Server.</p>
<p>Here is the Mule 2.2.1 configuration to take in a ZIP code from the console, call the web service with the supplied input and print the result back to the console.</p>
<p>Note: In a real life scenario you would not be using the Mule standard input connector to get the input.  You would be using something like an http, jms, or one of Mule&#8217;s many other available connectors depending on your system. The Mule standard IO connector is only useful for testing your Mule configuration.</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;mule xmlns=&quot;http://www.mulesource.org/schema/mule/core/2.2&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:spring=&quot;http://www.springframework.org/schema/beans&quot;
    xmlns:stdio=&quot;http://www.mulesource.org/schema/mule/stdio/2.2&quot; xmlns:vm=&quot;http://www.mulesource.org/schema/mule/vm/2.2&quot;
    xmlns:cxf=&quot;http://www.mulesource.org/schema/mule/cxf/2.2&quot;
    xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
    xsi:schemaLocation=&quot;
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.mulesource.org/schema/mule/core/2.2 http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
       http://www.mulesource.org/schema/mule/stdio/2.2 http://www.mulesource.org/schema/mule/stdio/2.2/mule-stdio.xsd
       http://www.mulesource.org/schema/mule/vm/2.2 http://www.mulesource.org/schema/mule/vm/2.2/mule-vm.xsd
       http://www.mulesource.org/schema/mule/cxf/2.2 http://www.mulesource.org/schema/mule/cxf/2.2/mule-cxf.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd&quot;&gt;

    &lt;!-- This connector will be used to accept our input from the console.
         It will output a prompt after a 1 second delay. --&gt;
    &lt;stdio:connector name=&quot;SystemStreamConnector&quot;
        promptMessage=&quot;Enter a ZIP Code: &quot; messageDelayTime=&quot;1000&quot; /&gt;

    &lt;model name=&quot;webServiceSample&quot;&gt;
        &lt;service name=&quot;SimpleWeatherService&quot;&gt;
            &lt;!-- any number of endpoints can be added to an inbound router --&gt;
            &lt;inbound&gt;
                &lt;!--  Our inbound endpoint is setup to use the stdio:connector
                      defined earlier.  The endpoint is also marked as
                      synchronous which meas it will wait on the result. --&gt;
                &lt;stdio:inbound-endpoint system=&quot;IN&quot; synchronous=&quot;true&quot;/&gt;
            &lt;/inbound&gt;
            &lt;!-- Once our input has been read it is sent to the outbound router.
                 At this point our Mule message payload is the String read from
                 the console. --&gt;
            &lt;outbound&gt;
                &lt;!-- Here we will use a chaining router.  A chaining router
                    processes each endpoint in sequence with the result of the first
                    outbound enpoint being sent as input to the next endpoint.
                    This is kind of analogous to a Unix pipe. --&gt;
                &lt;chaining-router&gt;
                    &lt;!-- Send our input to an in memory endpoint that will make
                         the call to the Weather web service. --&gt;
                    &lt;vm:outbound-endpoint path=&quot;weather.endpoint&quot; synchronous=&quot;true&quot; /&gt;

                    &lt;!--  Send the result of the first outbound endpoint which is
                          the Weather object returned by the web service call to
                          another in memory endpoint that will output the result. --&gt;
                    &lt;vm:outbound-endpoint path=&quot;echo.endpoint&quot; synchronous=&quot;true&quot; /&gt;
                &lt;/chaining-router&gt;
            &lt;/outbound&gt;
        &lt;/service&gt;

        &lt;!--  This service will handle the call to the remote weather service. --&gt;
        &lt;service name=&quot;WeatherProxyService&quot;&gt;
            &lt;!-- Accepts the String input then sends it to the remote weather service
                 via a CXF outbound endpoint. --&gt;
            &lt;inbound&gt;
                &lt;vm:inbound-endpoint name=&quot;weatherEndpoint&quot; path=&quot;weather.endpoint&quot; /&gt;
            &lt;/inbound&gt;
            &lt;outbound&gt;
                &lt;!-- A pass through router simply routes the message straight to
                     the enpoint. --&gt;
                &lt;pass-through-router&gt;
                    &lt;!-- Mule's built-in CXF outbound endpoint will call the remote
                         web service.  The service returns a Weather object which
                         will be returned back to the calling service component,
                         &quot;SimpleWeatherService&quot; in this case.

                         The parameters to the cxf endpoint are:
                         address - The address of the remote web service including
                                   the port name as defined in the WSDL
                         clientClass - The client class generated by CXF.
                         wsdlPort - The port name you want to call defined in the WSDL.
                         operation - The method to call on the web service. Note:
                                     the payload of the Mule message at this point will
                                     be sent as the argument to the web service method.
                                     In our case it is simply a String. Normally
                                     you would have a Mule transformer to
                                     transform your input object
                                     into the object type expected by the remote service.
                      --&gt;
                    &lt;cxf:outbound-endpoint
                        address=&quot;http://localhost:8080/weatherService/services/WeatherServiceImplPort&quot;
                        clientClass=&quot;cxf.mike.WeatherService_Service&quot;
                        wsdlPort=&quot;WeatherServiceImplPort&quot;
                        wsdlLocation=&quot;http://localhost:8080/weatherService/services/WeatherServiceImplPort?wsdl&quot;
                        operation=&quot;getWeather&quot; /&gt;
                &lt;/pass-through-router&gt;
            &lt;/outbound&gt;
        &lt;/service&gt;

        &lt;service name=&quot;EchoService&quot;&gt;
            &lt;inbound&gt;
                &lt;vm:inbound-endpoint name=&quot;echoEndpoint&quot; path=&quot;echo.endpoint&quot; /&gt;
            &lt;/inbound&gt;
            &lt;!-- The mule echo component simply outputs the Mule messagae payload
                 to the console. --&gt;
            &lt;echo-component /&gt;
        &lt;/service&gt;
    &lt;/model&gt;
&lt;/mule&gt;

</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/roguecoder.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/roguecoder.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/roguecoder.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/roguecoder.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/roguecoder.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/roguecoder.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/roguecoder.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/roguecoder.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/roguecoder.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/roguecoder.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/roguecoder.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/roguecoder.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/roguecoder.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/roguecoder.wordpress.com/466/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=466&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://roguecoder.wordpress.com/2011/06/04/mule-2-2-1-request-to-web-service-with-cxf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/70f14d7cfe282c558d45a6ec0dba9f05?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">roguecoder</media:title>
		</media:content>
	</item>
		<item>
		<title>Struts 2 Dojo Datetimepicker Change Event</title>
		<link>http://roguecoder.wordpress.com/2010/07/13/struts-2-dojo-datetimepicker-change-event/</link>
		<comments>http://roguecoder.wordpress.com/2010/07/13/struts-2-dojo-datetimepicker-change-event/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 16:35:36 +0000</pubDate>
		<dc:creator>roguecoder</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Struts 2]]></category>
		<category><![CDATA[Dojo]]></category>

		<guid isPermaLink="false">http://roguecoder.wordpress.com/?p=309</guid>
		<description><![CDATA[Writing an event handler for the Struts 2/Dojo datetimepicker widget requires  a little more work than simply adding an onchange property to the widget&#8217;s tag.  Conventional wisdom might lead you to try this: &#60;sx:datetimepicker id="datepicker" name="date" onchange="myCallback();" displayFormat="yyyyMMdd"/&#62; However, you will quickly discover that this does not fire an event when the value of the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=309&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Writing an event handler for the Struts 2/Dojo datetimepicker widget requires  a little more work than simply adding an onchange property to the widget&#8217;s tag.  Conventional wisdom might lead you to try this:</p>
<p><code> &lt;sx:datetimepicker id="datepicker" name="date" <strong>onchange="myCallback();"</strong> displayFormat="yyyyMMdd"/&gt;<br />
</code></p>
<p>However, you will quickly discover that this does not fire an event when the value of the widget changes.</p>
<p>There are 2 steps involved in registering an event listener with the widget.</p>
<div>
<ol>
<li>Call the dojo.addOnLoad() function.</li>
<li>Register your callback function to fire on the onValueChanged event.</li>
</ol>
</div>
<p><strong>Call the dojo.addOnLoad() Function</strong></p>
<p>The dojo.addOnLoad() function takes a function as an argument and will automatically fire after all the dojo widgets in your form have been initialized.</p>
<p><pre class="brush: jscript;">
dojo.addOnLoad(initDatetimePicker);
</pre></p>
<p>Your callback function will be registered in the function passed to addOnLoad();</p>
<p>One note of caution if you are using JQuery.  I tried to bypass the dojo.addOnLoad() function call by calling initDatetimepicker() in the $(&#8216;document&#8217;).ready construct like so:</p>
<p><pre class="brush: jscript;">$('document').ready(function() { initDatetimePicker(); });</pre></p>
<p>However, this will not work because the $(&#8216;document&#8217;).ready function actually fires before all of the dojo widgets are initialized.</p>
<p><strong>Register Your Callback Function to Fire on the onValueChanged Event</strong></p>
<p>Inside the function you passed to dojo.addOnLoad()  in the previous step is where you will register your callback function with the datetimepicker widget.  Here is the code:</p>
<p><pre class="brush: jscript;">
function initDatetimePicker() {
    var datepicker = dojo.widget.byId(&quot;datepicker&quot;);
    dojo.event.connect(datepicker, &quot;onValueChanged&quot;, myCallback );
}
</pre></p>
<p>Calling the dojo.event.connect() function will register your call back function with the appropriate event, onValueChanged in this case.  The connect() function takes three arguments: a reference to the datetimepicker widget, the event you want to listen for, and your callback function.</p>
<p><strong>Accessing the Selected Date in the Callback Function</strong></p>
<p>To access the the date selected by the user in your callback function you simply call the getDate() function on the datetimepicker widget.</p>
<p><pre class="brush: xml;"> var date = dojo.widget.byId(&quot;datepicker&quot;).getDate();
</pre></p>
<p><strong>Full Code Example</strong></p>
<p>Here is the full working code snippet:</p>
<p><pre class="brush: xml;">
&lt;%@taglib prefix=&quot;s&quot; uri=&quot;/struts-tags&quot;&gt;
&lt;%@taglib prefix=&quot;sx&quot; uri=&quot;/struts-dojo-tags&quot;&gt;

&lt;s:head /&gt;
&lt;sx:head debug=&quot;false&quot; cache=&quot;true&quot; /&gt;

&lt;script type=&quot;text/javascript&quot;&gt;

function initDatetimePicker() {
    var datepicker = dojo.widget.byId(&quot;datepicker&quot;);
    dojo.event.connect(datepicker, &quot;onValueChanged&quot;, myCallback );
}

function myCallback()  {
    var date = dojo.widget.byId(&quot;datepicker&quot;).getDate();
    alert(date);
}

dojo.addOnLoad(initDatetimePicker);

&lt;/script&gt;

&lt;s:form theme=&quot;simple&quot; action=&quot;someAction&quot;&gt;
    &lt;sx:datetimepicker id=&quot;datepicker&quot; name=&quot;date&quot; displayFormat=&quot;yyyyMMdd&quot; /&gt;
&lt;/s:form&gt;
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/roguecoder.wordpress.com/309/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/roguecoder.wordpress.com/309/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/roguecoder.wordpress.com/309/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/roguecoder.wordpress.com/309/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/roguecoder.wordpress.com/309/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/roguecoder.wordpress.com/309/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/roguecoder.wordpress.com/309/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/roguecoder.wordpress.com/309/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/roguecoder.wordpress.com/309/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/roguecoder.wordpress.com/309/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/roguecoder.wordpress.com/309/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/roguecoder.wordpress.com/309/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/roguecoder.wordpress.com/309/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/roguecoder.wordpress.com/309/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=309&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://roguecoder.wordpress.com/2010/07/13/struts-2-dojo-datetimepicker-change-event/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/70f14d7cfe282c558d45a6ec0dba9f05?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">roguecoder</media:title>
		</media:content>
	</item>
		<item>
		<title>Jasig CAS Authentication Steps</title>
		<link>http://roguecoder.wordpress.com/2010/05/18/jasig-cas-authentication-flow/</link>
		<comments>http://roguecoder.wordpress.com/2010/05/18/jasig-cas-authentication-flow/#comments</comments>
		<pubDate>Tue, 18 May 2010 18:12:31 +0000</pubDate>
		<dc:creator>roguecoder</dc:creator>
				<category><![CDATA[Jasig CAS]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[CAS]]></category>
		<category><![CDATA[Central Authentication Service]]></category>
		<category><![CDATA[Jasig]]></category>
		<category><![CDATA[SSO]]></category>

		<guid isPermaLink="false">http://roguecoder.wordpress.com/?p=215</guid>
		<description><![CDATA[This is a reference document to outline the steps involved in authentication using Jasig CAS.  I will also briefly explain the SSL portion with regards to the ticket validation step.  At the end of the article I will post the code for a sample client meant only to demonstrate the work flow through code.   [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=215&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is a reference document to outline the steps involved in authentication using <a href="http://www.ja-sig.org/wiki/display/CASUM/Home">Jasig CAS</a>.  I will also briefly explain the SSL portion with regards to the ticket validation step.  At the end of the article I will post the code for a sample client meant only to demonstrate the work flow through code.   Sometimes things are best understood by looking at a simple code sample.</p>
<p><strong>Steps in CAS Authentication</strong></p>
<p><strong>1.</strong> CAS client application redirects to the CAS server&#8217;s login URL with the client application&#8217;s URL set as the value of the <em>service</em> request parameter.</p>
<p>Example URL:  https://cas.mydomain.com/login?service=https://myapp.mydomian.com</p>
<p><strong>2</strong>.  CAS will look for a cookie in the current browser session to determine if the user is authenticated.  If the user has not yet authenticated to CAS via another CAS client, CAS will display the CAS login screen.  If the user is already authenticated via another CAS client, CAS proceeds to the next step without presenting the user with the login screen.</p>
<p><strong>3.</strong> Upon successful authentication CAS will redirect back to your client application with a service ticket set as a request parameter on the URL.</p>
<p><strong>4.</strong> The CAS client programatically opens an SSL connection back to the CAS server to validate the issued service ticket.</p>
<p>This step is where most people have trouble.  The CAS client JVM must trust the CAS server&#8217;s SSL certificate in order for this step to work.  Note that I&#8217;m not talking about the client&#8217;s application server, but the clients JVM environment. If the client JVM does not trust the CAS server&#8217;s certificate, an exception will be thrown.</p>
<p>You must import the CAS server&#8217;s SSL certificate into the client JVM&#8217;s trusted store.</p>
<p>The global trust store can be found at <em>$JAVA_HOME/jre/lib/security/cacerts</em>.</p>
<p>Note that the global trust store comes with the root certificates of most of the well known certificate authorities installed, so if your certificate has been signed by a CA, you might not need to import anything.</p>
<p>You can use the following keytool command to import the CAS server&#8217;s certificate into the global trust store:</p>
<p><em>keytool -import -alias cas_server -keystore $JAVA_HOME/jre/lib/security/cacerts -file cas_server_cert_file.cer. </em></p>
<p><em></em>See the <a href="http://java.sun.com/j2se/1.3/docs/tooldocs/win32/keytool.html">keytool documentation</a> for more about how to export and import certificates.</p>
<p><strong>5.</strong> If the service ticket validation is successful the CAS client will set the user principal in the client application.</p>
<p><strong>Sample Client</strong></p>
<p>Here is a sample Java client implemented as a servlet filter to demonstrate the exact flow between the CAS server and client.  This client is a very quick and dirty example meant for demo purposes only, please don&#8217;t try to use this code in any sort of production environment.</p>
<p><pre class="brush: java;">
package com.mycompany.cas.client.test;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.authentication.AttributePrincipalImpl;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.AssertionImpl;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;

public class CasTestClient implements Filter {
    private final String CAS_LOGIN_URL = &quot;https://cas.mydomain.com/cas/login&quot;;
    private final String CAS_VALIDATE_URL = &quot;https://cas.mydomain.com/cas/serviceValidate&quot;;
    private final String THIS_APPS_URL = &quot;http://mydomain/cas-testing/&quot;;

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) req;
        HttpServletResponse httpResponse = (HttpServletResponse) resp;

        // If the user principal is not null the user has been authenticated
        // by this application so just continue on to the next filter in the
        // request chain.
        if (httpRequest.getSession().getAttribute(&quot;_const_cas_assertion_&quot;) != null) {
            chain.doFilter(req, resp);
            return;
        }

        // User is NOT authenticated to this application, so we must query the
        // CAS server to authenticate.

        // If the user has already authenticated to CAS via another application,
        // CAS will simply redirect back to this application with a
        // service ticket set as a request parameter without displaying the
        // login screen.  If the user hasn't authenticated to CAS via another application,
        // CAS will display the login screen then redirect back to this application
        // with a service ticket after successfully authenticating.

        // Get the service ticket.
        String serviceTicket = req.getParameter(&quot;ticket&quot;);

        // If there is no service ticket parameter then redirect to the CAS
        // login URL to get one.
        if (serviceTicket == null || serviceTicket.length() &lt; 1) {
            String redirectURL = CAS_LOGIN_URL + &quot;?service=&quot; + THIS_APPS_URL;
            httpResponse.sendRedirect(redirectURL);
            return;
        }

        // Since we have a service ticket from CAS, validate the ticket by opening
        // an SSL connection to the server and reading the response.
        String urlString = CAS_VALIDATE_URL + &quot;?ticket=&quot; + serviceTicket + &quot;&amp;service=&quot; +
            THIS_APPS_URL;

        URL url = new URL(urlString);
        URLConnection connection = url.openConnection();

        BufferedReader in =
            new BufferedReader(new InputStreamReader(connection.getInputStream()));

        String xmlResponse = &quot;&quot;;
        String line = &quot;&quot;;
        while ((line = in.readLine()) != null) {
            System.out.println(line);
            xmlResponse += line;
        }
        in.close();

        String userData = null;

        // Parse the xml response
        try {
            Namespace namespace = Namespace.getNamespace(&quot;cas&quot;, &quot;http://www.yale.edu/tp/cas&quot;);
            SAXBuilder builder = new SAXBuilder();
            Document xmlDoc =
                builder.build(new ByteArrayInputStream(xmlResponse.getBytes(&quot;UTF-8&quot;)));
            Element rootElement = xmlDoc.detachRootElement();

            Element successElement = rootElement.getChild(&quot;authenticationSuccess&quot;,
                    namespace);

            // if the user element is null there was an error validating
            // the service ticket, so redirect to an error page.
            if (successElement == null) {
                System.err.print(&quot;Error validating CAS ticket.&quot;);
                httpResponse.sendRedirect(&quot;error_page.jsp&quot;);
                return;
            }

            Element userElement = successElement.getChild(&quot;user&quot;, namespace);
            userData = userElement.getText();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // If user data is null or empty redirect to an error page.
        if (userData == null || userData.length() &lt; 0) {
            System.err.print(&quot;Error getting user data.&quot;);
            httpResponse.sendRedirect(&quot;error_page.jsp&quot;);
            return;
        }

        // Create a principal and assertion object and set in the session
        AttributePrincipal principal = new AttributePrincipalImpl(userData);
        Assertion assertion = new AssertionImpl(principal);
        httpRequest.getSession().setAttribute(&quot;_const_cas_assertion_&quot;, assertion);
        chain.doFilter(req, resp);

    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }
}

</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/roguecoder.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/roguecoder.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/roguecoder.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/roguecoder.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/roguecoder.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/roguecoder.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/roguecoder.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/roguecoder.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/roguecoder.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/roguecoder.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/roguecoder.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/roguecoder.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/roguecoder.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/roguecoder.wordpress.com/215/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=215&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://roguecoder.wordpress.com/2010/05/18/jasig-cas-authentication-flow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/70f14d7cfe282c558d45a6ec0dba9f05?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">roguecoder</media:title>
		</media:content>
	</item>
		<item>
		<title>Jasig CAS, Spring Security, and Bookmarking</title>
		<link>http://roguecoder.wordpress.com/2010/05/14/jasig-cas-spring-security-and-bookmarking/</link>
		<comments>http://roguecoder.wordpress.com/2010/05/14/jasig-cas-spring-security-and-bookmarking/#comments</comments>
		<pubDate>Fri, 14 May 2010 18:15:33 +0000</pubDate>
		<dc:creator>roguecoder</dc:creator>
				<category><![CDATA[Jasig CAS]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[CAS]]></category>
		<category><![CDATA[Central Authentication Service]]></category>
		<category><![CDATA[Jasig]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SSO]]></category>

		<guid isPermaLink="false">http://roguecoder.wordpress.com/?p=145</guid>
		<description><![CDATA[Update: Thanks to Bob Short who commented below &#8212;  here is a better way to get the same effect without modifying any code.   I couldn&#8217;t find any documentation on this when I did the implementation, but I should have read the Spring Security API documentation better before modifying code.  After Bob&#8217;s suggestion I simply [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=145&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>Update:</strong></p>
<p><strong>Thanks to Bob Short who commented below &#8212;  here is a better way to get the same effect without modifying any code.   I couldn&#8217;t find any documentation on this when I did the implementation, but I should have read the Spring Security API documentation better before modifying code.  After Bob&#8217;s suggestion I simply changed my CAS/Spring Security configuration as listed below and everything worked great.</strong></p>
<p><strong>The only change from the Spring Security CAS sample application is the authenticationSuccessHandler property of the CASAuthenticationFilter bean.</strong></p>
<p><strong>Instead of using SimpleURLAuthenticationSuccess hander use SavedRequestAwareAuthenticationSuccessHandler.</strong></p>
<p><pre class="brush: xml;">
&lt;bean id=&quot;casAuthenticationFilter&quot; class=&quot;org.springframework.security.cas.web.CasAuthenticationFilter&quot;&gt;
        &lt;property name=&quot;authenticationManager&quot; ref=&quot;authenticationManager&quot;/&gt;
        &lt;property name=&quot;authenticationFailureHandler&quot;&gt;
            &lt;bean class=&quot;org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler&quot;&gt;
                &lt;property name=&quot;defaultFailureUrl&quot; value=&quot;/casfailed.jsp&quot;/&gt;
            &lt;/bean&gt;
        &lt;/property&gt;
        &lt;property name=&quot;authenticationSuccessHandler&quot;&gt;
            &lt;bean class=&quot;org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler&quot;&gt;
                &lt;property name=&quot;defaultTargetUrl&quot; value=&quot;/&quot;/&gt;
            &lt;/bean&gt;
        &lt;/property&gt;
    &lt;/bean&gt;
</pre></pre>
<p><strong>--  Original Article  --</strong></p>
<p>I recently implemented single sign-on within our corporate web world using <a href="http://www.jasig.org/cas">Jasig CAS</a> and <a href="http://static.springsource.org/spring-security/site/index.html">Spring Security</a>.  Everything worked as expected except for direct access to a URL within the web site.  I needed to find a solution to this problem if possible because our users were accustomed to bookmarking specific pages within the website.  Below is an in depth description of the problem and the solution I used to resolve it.</p>
<p><strong>The Problem</strong></p>
<p>If a user tried to access a page within the website such as, http://www.mysite.com/my_webapp/foo/some_page.jsp, without first being authenticated the user would be redirected to the site's home page after logging in through CAS.  It was easy to see why this was happening by observing the URL parameters during the redirects between CAS and the web application.</p>
<p>Here are the steps:</p>
<p>The unauthenticated user tries to access a web page:</p>
<p>http://www.mysite.com/my_webapp/foo/some_page.jsp.</p>
<p>Spring Security intercepts the request and redirects to the CAS server for authentication. The resulting CAS URL would be something like:</p>
<p>https://cas.mydomain.com/cas/login?service=http://www.mysite.com/my_webapp<strong>/j_spring_cas_security_check</strong></p>
<p>Note: The service URL is defined in the service properties bean of your Spring Security configuration like so:</p>
<p><pre class="brush: xml;">
&lt;bean id=&quot;serviceProperties&quot; class=&quot;org.springframework.security.cas.ServiceProperties&quot;&gt;
        &lt;property name=&quot;service&quot; value=&quot;http://www.mysite.com/my_webapp/j_spring_cas_security_check&quot;/&gt;
        &lt;property name=&quot;sendRenew&quot; value=&quot;false&quot;/&gt;
    &lt;/bean&gt;
</pre></p>
<p>Notice that the service URL does not contain any information regarding the original page requested by the user.</p>
<p>After successful authentication CAS will redirect the user back to the URL /j_spring_cas_security_check.  Spring will then direct the user to the page defined by the property <em>defaultTargetUrl </em>set on the Spring authentication success hander bean:</p>
<p><pre class="brush: xml;">
&lt;property name=&quot;authenticationSuccessHandler&quot;&gt;
            &lt;bean class=&quot;org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler&quot;&gt;
                &lt;property name=&quot;defaultTargetUrl&quot; value=&quot;/&quot;/&gt;
            &lt;/bean&gt;
        &lt;/property&gt;
</pre></p>
<p>The / value defined in the example above simply refers to the root of the web application which should be used in most cases.</p>
<p><strong>The Solution</strong></p>
<p>It was obvious at this point that the originally requested URL needed to be part of the service request parameter sent to the CAS server and also be available to the Spring CAS client filter on the redirect from CAS back to our web application.</p>
<p>The final solution resulted in the Spring CAS client forming a CAS redirect URL like this:</p>
<p><span style="color:#333300;">https://cas.mydomain.com/cas/login?service=https://www.mydomain.com/my_webapp/j_spring_cas_security_check</span><strong><span style="color:#333300;">?spring-security-redirect=/content/some_page.jsp</span></strong></p>
<p>Notice the new request parameter, <em>spring-security-redirect</em>, tacked onto the service URL parameter in bold.  This is the originally requested URL relative to the root of the web application.</p>
<p>In order to generate the above URL and have Spring security redirect to the path defined by <em>spring-security-redirect </em>we must make some slight changes to the Spring security CAS source code and the Spring configuration XML file.</p>
<p>The classes that I modified are:</p>
<p>org.springframework.security.cas.web.CasAuthenticationFilter</p>
<p>org.springframework.security.cas.web.CasAuthenticationEntryPoint</p>
<p><span style="color:#333300;">The CasAuthenticationEntryPoint class is responsible for generating the CAS redirect URL, so that is where we will add our new request parameter.</span></p>
<p><span style="color:#333300;">The CasAuthenticationFilter is where the redirect back from the CAS server is handled, so this is where we handle getting the user to the page they requested.</span></p>
<p><strong>Modified org.springframework.security.cas.web.CasAuthenticationEntryPoint</strong></p>
<p>In the custom CasAuthenticationEntry point class we simply extend the original class and override certain methods.  The main method of concern here is the createSerivceUrl method.  Our custom method adds the  spring-security-redirect request parameter to the service parameter URL sent to CAS.  See the commented code below.</p>
<p><pre class="brush: java;">
package com.mycompany.spring.security;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jasig.cas.client.util.CommonUtils;
import org.springframework.security.cas.web.CasAuthenticationEntryPoint;
import org.springframework.security.core.AuthenticationException;

public class CustomCasAuthenticationEntryPoint extends
        CasAuthenticationEntryPoint {

    @Override
    public final void commence(final HttpServletRequest servletRequest,
            final HttpServletResponse response,
            final AuthenticationException authenticationException)
            throws IOException, ServletException {

        final String urlEncodedService = createServiceUrl(servletRequest, response);
        final String redirectUrl = createRedirectUrl(urlEncodedService);

        response.sendRedirect(redirectUrl);
    }

    /**
     * Constructs a new Service Url.  The default implementation relies on the CAS client to do the bulk of the work.
     * @param request the HttpServletRequest
     * @param response the HttpServlet Response
     * @return the constructed service url.  CANNOT be NULL.
     */
    protected String createServiceUrl(final HttpServletRequest request,
            final HttpServletResponse response) {
        // get the request URI minus the leading &quot;/&quot;
        String url = request.getRequestURI().substring(1);
        String queryString = request.getQueryString();

        // If the request URI had a query string, append it
        // to the URL we're building.
        if (queryString != null &amp;&amp; queryString.length() &gt; 0) {
            url += &quot;?&quot; + queryString;
        }

        // Chop off the web app portion of the URL.
        // If your web app is the ROOT web app, you won't need this line.
        url = url.substring(url.indexOf(&quot;/&quot;));

        // Return a service URL with the value of the request parameter
        // spring-security-redirect set to the URL we just built.
        return CommonUtils.constructServiceUrl(null,
                response,
                this.getServiceProperties().getService() + &quot;?spring-security-redirect=&quot; + url,
                null,
                this.getServiceProperties().getArtifactParameter(),
                true);
    }

    /**
     * Constructs the Url for Redirection to the CAS server.  Default implementation relies on the CAS client to do the bulk of the work.
     *
     * @param serviceUrl the service url that should be included.
     * @return the redirect url.  CANNOT be NULL.
     */
    protected String createRedirectUrl(final String serviceUrl) {
        return CommonUtils.constructRedirectUrl(this.getLoginUrl(),
                this.getServiceProperties().getServiceParameter(),
                serviceUrl,
                this.getServiceProperties().isSendRenew(), false);
    }

}
</pre></p>
<p><strong>Modified org.springframework.security.cas.web.CasAuthenticationFilter</strong></p>
<p><pre class="brush: java;">
package com.mycompany.spring.security;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.validation.TicketValidator;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.cas.ServiceProperties;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;

/**
* Processes a CAS service ticket.
* &lt;p&gt;
* A service ticket consists of an opaque ticket string. It arrives at this filter by the user's browser successfully
* authenticating using CAS, and then receiving a HTTP redirect to a &lt;code&gt;service&lt;/code&gt;. The opaque ticket string is
* presented in the &lt;code&gt;ticket&lt;/code&gt; request parameter. This filter monitors the &lt;code&gt;service&lt;/code&gt; URL so it can
* receive the service ticket and process it. The CAS server knows which &lt;code&gt;service&lt;/code&gt; URL to use via the
* {@link ServiceProperties#getService()} method.
* &lt;p&gt;
* Processing the service ticket involves creating a &lt;code&gt;UsernamePasswordAuthenticationToken&lt;/code&gt; which
* uses {@link #CAS_STATEFUL_IDENTIFIER} for the &lt;code&gt;principal&lt;/code&gt; and the opaque ticket string as the
* &lt;code&gt;credentials&lt;/code&gt;.
* &lt;p&gt;
* The configured &lt;code&gt;AuthenticationManager&lt;/code&gt; is expected to provide a provider that can recognise
* &lt;code&gt;UsernamePasswordAuthenticationToken&lt;/code&gt;s containing this special &lt;code&gt;principal&lt;/code&gt; name, and process
* them accordingly by validation with the CAS server.
* &lt;p&gt;
* By configuring a shared {@link ProxyGrantingTicketStorage} between the {@link TicketValidator} and the
* CasAuthenticationFilter one can have the CasAuthenticationFilter handle the proxying requirements for CAS. In addition, the
* URI endpoint for the proxying would also need to be configured (i.e. the part after protocol, hostname, and port).
* &lt;p&gt;
* By default this filter processes the URL &lt;tt&gt;/j_spring_cas_security_check&lt;/tt&gt;.
*
* @author Ben Alex
* @version $Id$
*/
public class CustomCasAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
   //~ Static fields/initializers ==========================================================

   /** Used to identify a CAS request for a stateful user agent, such as a web browser. */
   public static final String CAS_STATEFUL_IDENTIFIER = &quot;_cas_stateful_&quot;;

   /**
    * Used to identify a CAS request for a stateless user agent, such as a remoting protocol client (e.g.
    * Hessian, Burlap, SOAP etc). Results in a more aggressive caching strategy being used, as the absence of a
    * &lt;code&gt;HttpSession&lt;/code&gt; will result in a new authentication attempt on every request.
    */
   public static final String CAS_STATELESS_IDENTIFIER = &quot;_cas_stateless_&quot;;

   /**
    * The last portion of the receptor url, i.e. /proxy/receptor
    */
   private String proxyReceptorUrl;

   /**
    * The backing storage to store ProxyGrantingTicket requests.
    */
   private ProxyGrantingTicketStorage proxyGrantingTicketStorage;

   private String artifactParameter = ServiceProperties.DEFAULT_CAS_ARTIFACT_PARAMETER;

   private ServiceProperties serviceProperties;

   //~ Constructors ====================================================================

   public CustomCasAuthenticationFilter() {
       super(&quot;/j_spring_cas_security_check&quot;);
   }

   //~ Methods ================================================================

   public Authentication attemptAuthentication(final HttpServletRequest request, final HttpServletResponse response)
           throws AuthenticationException {
       final String username = CAS_STATEFUL_IDENTIFIER;
       String targetUrl = request.getParameter(&quot;spring-security-redirect&quot;);
       String password = request.getParameter(this.artifactParameter);

       if (password == null) {
           password = &quot;&quot;;
       }

       final UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);

       authRequest.setDetails(authenticationDetailsSource.buildDetails(request));

       CasAuthenticationProvider provider = null;
       for (AuthenticationProvider ap :
           ((ProviderManager) this.getAuthenticationManager()).getProviders()) {
           if (ap instanceof org.springframework.security.cas.authentication.CasAuthenticationProvider) {
               provider = (CasAuthenticationProvider) ap;
               break;
           }

       }

       if (provider != null) {
           ServiceProperties sp = new ServiceProperties();
           sp.setService(this.serviceProperties.getService()
                   + &quot;?spring-security-redirect=&quot; + targetUrl);

           provider.setServiceProperties(sp);
       }

       return this.getAuthenticationManager().authenticate(authRequest);
   }

   /**
    * Overridden to provide proxying capabilities.
    */
   protected boolean requiresAuthentication(final HttpServletRequest request, final HttpServletResponse response) {
       final String requestUri = request.getRequestURI();

       if (CommonUtils.isEmpty(this.proxyReceptorUrl) || !requestUri.endsWith(this.proxyReceptorUrl) || this.proxyGrantingTicketStorage == null) {
           return super.requiresAuthentication(request, response);
       }

       try {
           CommonUtils.readAndRespondToProxyReceptorRequest(request, response, this.proxyGrantingTicketStorage);
           return false;
       } catch (final IOException e) {
           return super.requiresAuthentication(request, response);
       }
   }

   public final void setProxyReceptorUrl(final String proxyReceptorUrl) {
       this.proxyReceptorUrl = proxyReceptorUrl;
   }

   public final void setProxyGrantingTicketStorage(
           final ProxyGrantingTicketStorage proxyGrantingTicketStorage) {
       this.proxyGrantingTicketStorage = proxyGrantingTicketStorage;
   }

   public final void setServiceProperties(final ServiceProperties serviceProperties) {
       this.serviceProperties = serviceProperties;
   }
}

</pre></p>
<p>The first modification is on line 71 where we declare a serviceProperties member variable to be injected by Spring.  The Spring security API does not allow access to the ServiceProperties object from with this class, so we must inject a ServiceProperties object in our Spring configuration as shown in the last section of the article.</p>
<p><strong>private SericeProperties serviceProperties;</strong></p>
<p>The next modification  is line 84 which simply reads in our new request parameter described above.</p>
<p><strong>String targetUrl = request.getParameter("spring-security-redirect");</strong></p>
<p>Lines 95 through 111 encompass the bulk of the modifications to this class shown below with comments.</p>
<p><pre class="brush: java;">
CasAuthenticationProvider provider = null;

// Loop through all AuthenticationProviders to find the CAS provider.
for (AuthenticationProvider ap :
        ((ProviderManager) this.getAuthenticationManager()).getProviders())  {

    if (ap instanceof org.springframework.security.cas.authentication.CasAuthenticationProvider) {
        provider = (CasAuthenticationProvider) ap;
        break;
    }
}

if (provider != null) {
    // Create a new service properties object.  This is necessary because the API
    // doesn't allow access to the configured object.
    ServiceProperties sp = new ServiceProperties();

    // Add the targetUrl read in from our new request parameter to the the the service URL.
    sp.setService(this.serviceProperties.getService() + &quot;?spring-security-redirect=&quot; + targetUrl);

    // set the new SeriveProperties on the provider.
    provider.setServiceProperties(sp);
}
</pre></p>
<p><strong>Spring Configuration</strong></p>
<p>Finally we need to add the custom classes to our Spring configuration file.  Note that the custom authentication filter will need the serviceProperties property set on it so that it can be accessed within the class.</p>
<p><pre class="brush: xml;">
&lt;bean id=&quot;casAuthenticationFilter&quot; class=&quot;com.mycompany.spring.security.CustomCasAuthenticationFilter&quot;&gt;
        &lt;property name=&quot;authenticationManager&quot; ref=&quot;authenticationManager&quot;/&gt;
        &lt;!--  Only valid for our custom filter. --&gt;
        &lt;property name=&quot;serviceProperties&quot; ref=&quot;serviceProperties&quot;/&gt;
        &lt;property name=&quot;authenticationFailureHandler&quot;&gt;
            &lt;bean class=&quot;org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler&quot;&gt;
                &lt;property name=&quot;defaultFailureUrl&quot; value=&quot;/casfailed.jsp&quot;/&gt;
            &lt;/bean&gt;
        &lt;/property&gt;
        &lt;property name=&quot;authenticationSuccessHandler&quot;&gt;
            &lt;bean class=&quot;org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler&quot;&gt;
                &lt;property name=&quot;defaultTargetUrl&quot; value=&quot;/&quot;/&gt;
            &lt;/bean&gt;
        &lt;/property&gt;
    &lt;/bean&gt;

    &lt;bean id=&quot;casProcessingFilterEntryPoint&quot; class=&quot;com.mycompany.spring.security.CustomCasAuthenticationEntryPoint&quot;&gt;
        &lt;property name=&quot;loginUrl&quot; value=&quot;https://cas.mydomain.com/cas/login&quot;/&gt;
        &lt;property name=&quot;serviceProperties&quot; ref=&quot;serviceProperties&quot;/&gt;
    &lt;/bean&gt;
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/roguecoder.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/roguecoder.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/roguecoder.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/roguecoder.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/roguecoder.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/roguecoder.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/roguecoder.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/roguecoder.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/roguecoder.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/roguecoder.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/roguecoder.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/roguecoder.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/roguecoder.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/roguecoder.wordpress.com/145/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=145&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://roguecoder.wordpress.com/2010/05/14/jasig-cas-spring-security-and-bookmarking/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/70f14d7cfe282c558d45a6ec0dba9f05?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">roguecoder</media:title>
		</media:content>
	</item>
		<item>
		<title>Ajax File Upload with Struts 2 and Spring</title>
		<link>http://roguecoder.wordpress.com/2009/05/21/ajax-file-upload-with-struts-2-and-spring/</link>
		<comments>http://roguecoder.wordpress.com/2009/05/21/ajax-file-upload-with-struts-2-and-spring/#comments</comments>
		<pubDate>Thu, 21 May 2009 20:28:29 +0000</pubDate>
		<dc:creator>roguecoder</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Struts 2]]></category>
		<category><![CDATA[File Upload]]></category>
		<category><![CDATA[Struts]]></category>
		<category><![CDATA[Struts2]]></category>

		<guid isPermaLink="false">http://roguecoder.wordpress.com/?p=39</guid>
		<description><![CDATA[This article assumes you have Struts 2.1.6 up and running with Spring and  the dojo plugin. To activate the dojo plugin simply drop the struts2-dojo-plugin-2.1.6.jar file from the Struts distro into your application&#8217;s classpath. I&#8217;m going to give a brief overview before getting into the code portion. First of all, Struts 2 will not support [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=39&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This article assumes you have Struts 2.1.6 up and running with Spring and  the dojo plugin. To activate the dojo plugin simply drop the struts2-dojo-plugin-2.1.6.jar file from the Struts distro into your application&#8217;s classpath.</p>
<p>I&#8217;m going to give a brief overview before getting into the code portion.</p>
<p>First of all, Struts 2 will not support Ajax multipart form data via tags, so you will need to write a small javascript function to send the data to the server when the submit button is clicked.</p>
<p>On the server we&#8217;ll set up a directory to store the uploaded files and keep track of the files in a List stored in the Session.</p>
<p>We will have two JSP pages.  One with the main form and another one that displays the list of uploaded files.</p>
<p><strong>The Javascript Function:</strong></p>
<p>Since Struts 2 will not support multipart form data natively we will write a small javascript function that uses dojo to send the data to the server.</p>
<p><pre class="brush: jscript;">
 // make sure you include this
 dojo.require(&quot;dojo.io.IframeIO&quot;);

// formId - Id of form being submitted
// indicatorId - Id of indicator
// viewId - Id of the view to update
function sendToServer(formId, indicatorId, viewId) {
 // show the indicator
 document.getElementById(indicatorId).style.display = '';
 var bindArgs = {
     transport: &quot;IframeTransport&quot;,
     formNode: formId,
     mimetype: &quot;text/html&quot;,
     load: function(type, data, evt) {
         // update the view with data returned from server
         document.getElementById(viewId).innerHTML = data.firstChild.innerHTML;

         // turn off the indicator
         document.getElementById(indicatorId).style.display = 'none';
       }
    };
    var request = dojo.io.bind(bindArgs);
}
</pre></p>
<p>The function takes three string arguments:</p>
<ul>
<li>formId &#8211; This is the id of the form element that contains the multipart form data.</li>
<li>indicatorId &#8211; Id  of the element you are using to indicate that processing is taking place. Usually an animated gif.</li>
<li>viewId &#8211; This is the id of the element that will be updated with data returned from the server.  In this example the server will return another JSP page.</li>
</ul>
<p><strong>The Form:</strong></p>
<p>Here is the JSP page containg the multipart form:</p>
<p><pre class="brush: xml;">&lt;%@ taglib prefix=&quot;s&quot; uri=&quot;/struts-tags&quot; %&gt;
&lt;%@ taglib prefix=&quot;sx&quot; uri=&quot;/struts-dojo-tags&quot; %&gt;
&lt;sx:head debug=&quot;false&quot; cache=&quot;false&quot;/&gt;
&lt;s:head/&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
 // make sure you include this
 dojo.require(&quot;dojo.io.IframeIO&quot;);

// formId - Id of form being submitted
// indicatorId - Id of indicator
// viewId - Id of the view to update
function sendToServer(formId, indicatorId, viewId) {
 // show the indicator
 document.getElementById(indicatorId).style.display = '';
 var bindArgs = {
 transport: &quot;IframeTransport&quot;,
 formNode: formId,
 mimetype: &quot;text/html&quot;,
 load: function(type, data, evt) {
 // update the view with data returned from server
 document.getElementById(viewId).innerHTML = data.firstChild.innerHTML;

 // turn off the indicator
 document.getElementById(indicatorId).style.display = 'none';
 }
 };
 var request = dojo.io.bind(bindArgs);
}
&lt;/script&gt;

&lt;H1&gt;Ajax File Upload Test&lt;/H1&gt;

&lt;s:form name=&quot;form1&quot; id=&quot;mainForm&quot; theme=&quot;simple&quot; method=&quot;POST&quot;&gt;
&lt;table cellspacing=&quot;3&quot; cellpadding=&quot;3&quot; width=&quot;50%&quot;&gt;
&lt;tr&gt;
&lt;td&gt;Some Information:&lt;/td&gt;
&lt;td&gt;&lt;s:textfield name=&quot;someData&quot;/&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Some More Information:&lt;/td&gt;
&lt;td&gt;&lt;s:textfield name=&quot;moreData&quot;/&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/s:form&gt;
&lt;div style=&quot;border: solid #dedede 1px; padding: 3px;&quot;&gt;
 &lt;!--  To keep the form form double submitting,
 I had to set the onsubmit attribute
 of the form to call the dojo function and
 then return false instead of just setting
 onclik on the submit button.
 --&gt;
 &lt;s:form theme=&quot;simple&quot; action=&quot;attachFile&quot;
         id=&quot;attachFileForm&quot; method=&quot;post&quot;
         enctype=&quot;multipart/form-data&quot;
         onsubmit=&quot;sendToServer('attachFileForm', 'uploadingFileInd', 'attachedFilesView'); return false;&quot;&gt;

 &lt;s:file id=&quot;fileSelect&quot; size=&quot;50&quot; name=&quot;fileUpload.file&quot;/&gt;

 &lt;sx:submit transport=&quot;IframeTransport&quot;
            showLoadingText=&quot;false&quot;
            value=&quot;%{'Attach File'}&quot;
            indicator=&quot;uploadingFile&quot;/&gt;

 &lt;img id=&quot;uploadingFileInd&quot; src=&quot;/images/ajax-loader.gif&quot; style=&quot;display:none&quot;/&gt;&lt;/td&gt;
&lt;/s:form&gt;

 Attached Files:
 &lt;!-- The element that contains what will be returned from the server. --&gt;
&lt;div id=&quot;attachedFilesView&quot;&gt;
    &lt;jsp:include page=&quot;uploadlist.jsp&quot;/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;!--  submit button for the other form --&gt;
&lt;input onclick=&quot;document.form1.submit();&quot; value=&quot;Submit&quot; type=&quot;button&quot;&gt;
</pre></p>
<p>When the form is submitted the sendToServer javascript function is called then the boolean value false is returned.  The form would attempt to submit again after the javascript function executes without the return false statement.</p>
<p>Also notice the transport attribute of the submit button is set to IframeTransport.</p>
<p>You will need to add a submit button for the additional form like this since you cannot have more than  one Struts 2 submit button on a page:</p>
<p><pre class="brush: xml;">
&lt;input onclick=&quot;document.form1.submit();&quot; type=&quot;button&quot; /&gt;
</pre></p>
<p><strong>The Uploaded Files View:</strong></p>
<p>This is the JSP page that will show the list of uploaded files along with a delete option for each file.</p>
<p>The Struts 2 action will return this JSP page each time a file is uploaded/deleted and the view will be updated by the javascript function we wrote earlier.</p>
<p><pre class="brush: xml;">

&lt;%@ taglib prefix=&quot;s&quot; uri=&quot;/struts-tags&quot; %&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
function removeFile(form) {
if (!confirm(&quot;Are you sure you want to remove this file?&quot;)) {
return;
}
else {
sendToServer(form, 'uploadingFileInd', 'attachedFilesView');
}
}

&lt;/script&gt;

&lt;s:actionerror cssClass=&quot;errorText&quot;/&gt;
&lt;div id=&quot;uploadList&quot; style=&quot;margin-left: 5px&quot;&gt;
&lt;s:iterator value=&quot;#session.fileUploadList&quot; status=&quot;status&quot;&gt;
&lt;s:form theme=&quot;simple&quot; id=&quot;removeFile%{#status.count}&quot;
onsubmit=&quot;removeFile('removeFile%{#status.count}'); return false;&quot;&gt;
         &lt;s:hidden name=&quot;removeIndex&quot; value=&quot;%{#status.count - 1}&quot;/&gt;
         ${session.fileUploadList[status.count - 1].fileFileName }&amp;nbsp;&amp;nbsp;
         &lt;s:submit value=&quot;%{'delete'}&quot;/&gt;
        &lt;/s:form&gt;
   &lt;/s:iterator&gt;&lt;/div&gt;
</pre></p>
<p>The JSP page uses the Struts 2 iterator tag to iterate over the list of files stored in the session.  For each file in the list a form is created to remove the file and the name of the file is displayed.</p>
<p>The ID of each form is set to the status counter and a hidden field is created with the file&#8217;s index in the list.</p>
<p>A javascript function handles submitting the form and confirming that the user really wants to remove the file from the list.</p>
<p><strong>The Server Side:</strong></p>
<p>Before getting into the code let&#8217;s look at the Spring and Struts 2 configurations.</p>
<p><strong>Application Context File (Spring)</strong></p>
<p><pre class="brush: xml;">

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
xmlns:tx=&quot;http://www.springframework.org/schema/tx&quot;
xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
                              http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd&quot;&gt;

    &lt;bean id=&quot;attachFileAction&quot; scope=&quot;prototype&quot;
             class=&quot;com.cowboycoding.ajaxfileupload.AjaxFileUploadAction&quot;&gt;
&lt;property name=&quot;uploadDir&quot; value=&quot;/content/upload/&quot;/&gt;
&lt;property name=&quot;maxUploads&quot; value=&quot;5&quot;/&gt;
    &lt;/bean&gt;

&lt;/beans&gt;

</pre></p>
<p>The main thing to note here is the injection of two properties into our Struts 2 action: uploadDir and maxUploads.  The uploadDir property defines the directory relative to the web application to save the uploaded files into. The maxUploads property defines the maximum number of files that can be uploaded per request.</p>
<p><strong>Struts Configuration:</strong></p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;!DOCTYPE struts PUBLIC
     &quot;-//Apache Software Foundation//DTD Struts Configuration 2.0//EN&quot;
     &quot;http://struts.apache.org/dtds/struts-2.0.dtd&quot;&gt;

&lt;struts&gt;
&lt;package name=&quot;/fileUpload&quot; namespace=&quot;/fileUpload&quot; extends=&quot;struts-default&quot;&gt;

        &lt;action name=&quot;fileUploadTest&quot;&gt;
            &lt;result&gt;/WEB-INF/jsp/upload_test_form.jsp&lt;/result&gt;
        &lt;/action&gt;

        &lt;action name=&quot;attachFile_*&quot; method=&quot;{1}&quot; class=&quot;attachFileAction&quot;&gt;
            &lt;result&gt;/WEB-INF/jsp/uploadlist.jsp&lt;/result&gt;
        &lt;/action&gt;

    &lt;/package&gt;
&lt;/struts&gt;

</pre></p>
<p>For the purposes of this article the fileUploadTest action simply refers to a JSP page.  In a real world scenario, it would refer to a Strtus action that handled form input.</p>
<p>Here you can see our attachFile action.  There is only one default result for the action which is the JSP page that displays the list of uploaded files we wrote earlier.</p>
<p><strong>The FileUpload Bean</strong>:</p>
<p>I created a simple class called FileUploadBean to hold all of the file information submitted by the Struts 2 file tag.  The action class contains an instance variable of this type named fileUpload.</p>
<p>Note the variable name in the name property of the file tag in the form JSP page:</p>
<p><pre class="brush: xml;">

&lt;s:file id=&quot;fileSelect&quot; size=&quot;50&quot; name=&quot;fileUpload.file&quot;/&gt;

</pre></p>
<p>Here is the code for the FileUploadBean class:</p>
<p><pre class="brush: java;">
package com.cowboycoding.ajaxfileupload;

import java.io.File;

public class FileUploadBean {
    private File file;  // the file
    private String fileContentType; //The content type of the file
    private String fileFileName; //The uploaded file name

    public File getFile() {
        return file;
    }

    public void setFile(File file) {
        this.file = file;
    }

    public String getFileContentType() {
        return fileContentType;
    }

    public void setFileContentType(String fileContentType) {
        this.fileContentType = fileContentType;
    }

    public String getfileFileName() {
        return fileFileName;
    }

    public void setFileFileName(String fileFileName) {
        this.fileFileName = fileFileName;
    }
}

</pre></p>
<p><strong>The Action Class</strong>:</p>
<p>Last but not least we have the Struts 2 action class.  This class performs two main tasks: uploading files and deleting files from the list of uploaded files.</p>
<p>Struts automatically assigns uploaded files a generated name and stores them in the directory defined by the struts.multipart.saveDir property in your struts configuration.  If the struts.multipart.saveDir is not defined, a default is used.</p>
<p>When a file is uploaded the FileUploadBean file property will contain a reference to the file that Struts 2 saved on the server&#8217;s filesystem.  The fileFileName property will be set to the original name of the file on the client&#8217;s filesystem.</p>
<p>Our action will rename the file back to the original name and move the file to the upload directory defined in the Spring configuration.</p>
<p>The action class does make use of the org.apache.commons.io.FileUtils class from the commons io package which can be downloaded here: <a href="http://commons.apache.org/io/">http://commons.apache.org/io/</a></p>
<p>Finally here is the action class:</p>
<p><pre class="brush: java;">package com.cowboycoding.ajaxfileupload;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.SessionAware;
import org.springframework.web.context.ServletContextAware;

import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings(&quot;serial&quot;)
public class AjaxFileUploadAction extends ActionSupport implements SessionAware,
    ServletContextAware, ServletRequestAware {
    private HttpServletRequest request;
    private Map session;
    private ServletContext servletContext;
    private FileUploadBean fileUpload;
    private String uploadDir;  // Injected via Spring
    private int maxUploads = 0;  // Injected via Spring
    private int removeIndex = 0;  // passed in from form
    private List&lt;FileUploadBean&gt; uploads;

    public AjaxFileUploadAction() {
        fileUpload = new FileUploadBean();
    }

    public String execute() {
        uploads = (List&lt;FileUploadBean&gt;) session.get(&quot;fileUploadList&quot;);

        // initialize the session list if it hasn't been already
        if (uploads == null)
            uploads = new ArrayList&lt;FileUploadBean&gt;();

        // check to see if maxUploads has been met
        if (uploads.size() &gt;= maxUploads)  {
            addActionError(&quot;Unable to upload file: Max number of uploads: &quot; +
                 maxUploads + &quot; has already been reached.&quot;);
            return SUCCESS;
        }

        // make sure the user selected a file before clicking submit
        if (fileUpload.getFile() == null) {
            addActionError(&quot;No file selected.&quot;);
            return SUCCESS;
        }

        // handle the file upload
        handleUpload();
        return SUCCESS;
    }

    private void handleUpload()  {
        // Make sure they didn't upload a file with the same name as a
        // file that already exists
        for (FileUploadBean f : uploads) {
            if (f.getfileFileName().equals(fileUpload.getfileFileName())) {
                addActionError(&quot;There is already an attached file with file name: &quot; +
                                     fileUpload.getfileFileName());
                return;
            }
        }

        // get the absolute path to the save direcory
        String savePath = getServletContext().getRealPath(uploadDir);

        // set the path for the new file
        File destFile = new File(savePath + &quot;/&quot; + fileUpload.getfileFileName());
        if (destFile.exists()) {
            addActionError(&quot;A file with name &quot; + fileUpload.getfileFileName() + &quot;already&quot; +
                                 &quot; exists on the server. Rename your file and try again.&quot;);
            return;
        }

        try {
            // Copy the file to the new directory
            FileUtils.copyFile(fileUpload.getFile(), destFile);
       } catch (Exception e) {
            e.printStackTrace();
            addActionError(&quot;Unable to save uploaded file: &quot; + e.getMessage());
             return;
       }

        // set the file to the new file
        fileUpload.setFile(destFile);

        // add file to the list of uploaded files
        uploads.add(fileUpload);

        // put the list in the session
        session.put(&quot;fileUploadList&quot;, uploads);
    }

    @SuppressWarnings(&quot;unchecked&quot;)
    public String removeFile() {
        // get the list of uploaded files from the session
        uploads = (List&lt;FileUploadBean&gt;) session.get(&quot;fileUploadList&quot;);
        try {
            // delete the specified file from the filesystem
            uploads.get(removeIndex).getFile().delete();

            // remove the file from the list
           uploads.remove(removeIndex);

            // update the list in the session
           session.put(&quot;fileUploadList&quot;, uploads);

        } catch (Exception e) {
            addActionError(&quot;Error removing attachment: &quot; + e.getMessage());
            e.printStackTrace();
        }

        return SUCCESS;
    }

    // getter and setter methods
    public FileUploadBean getFileUpload() {
        return fileUpload;
    }

    public void setFileUpload(FileUploadBean fileUpload) {
        this.fileUpload = fileUpload;
    }

    public String getUploadDir() {
        return uploadDir;
   }

    public void setUploadDir(String uploadDir) {
        this.uploadDir = uploadDir;
    }

    public void setSession(Map session) {
        this.session = session;
    }

    public ServletContext getServletContext() {
        return servletContext;
    }

    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    public int getMaxUploads() {
        return maxUploads;
    }

    public void setMaxUploads(int maxUploads) {
        this.maxUploads = maxUploads;
    }

    public int getRemoveIndex() {
        return removeIndex;
    }

    public void setRemoveIndex(int removeIndex) {
        this.removeIndex = removeIndex;
    }

    public void setServletRequest(HttpServletRequest request) {
       this.request = request;
    }
}

</pre></p>
<p>Hopefully this article helped you get up and running with Ajax file upload.  All the code in the article was copied/pasted from a working test application.  If you have your web application environment, Struts 2 , and Spring configured correctly the code should work.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/roguecoder.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/roguecoder.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/roguecoder.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/roguecoder.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/roguecoder.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/roguecoder.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/roguecoder.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/roguecoder.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/roguecoder.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/roguecoder.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/roguecoder.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/roguecoder.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/roguecoder.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/roguecoder.wordpress.com/39/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=39&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://roguecoder.wordpress.com/2009/05/21/ajax-file-upload-with-struts-2-and-spring/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/70f14d7cfe282c558d45a6ec0dba9f05?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">roguecoder</media:title>
		</media:content>
	</item>
		<item>
		<title>2 Tweet or Not 2 Tweet?</title>
		<link>http://roguecoder.wordpress.com/2009/05/16/2-tweet-or-not-2-tweet/</link>
		<comments>http://roguecoder.wordpress.com/2009/05/16/2-tweet-or-not-2-tweet/#comments</comments>
		<pubDate>Sat, 16 May 2009 19:40:14 +0000</pubDate>
		<dc:creator>roguecoder</dc:creator>
				<category><![CDATA[Social Media]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://roguecoder.wordpress.com/?p=63</guid>
		<description><![CDATA[I&#8217;ve been using Twitter on sort of a trial basis for about a week now and decided to share my thoughts.  I&#8217;m by no means an expert, but maybe I can help lift the proverbial veil for some of you wondering what all the hype is about. What is Twitter? Twitter sells itself as a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=63&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using Twitter on sort of a trial basis for about a week now and decided to share my thoughts.  I&#8217;m by no means an expert, but maybe I can help lift the proverbial veil for some of you wondering what all the hype is about.</p>
<p><strong>What is Twitter?</strong></p>
<p>Twitter sells itself as a service for friends, family, and co-workers to keep in touch. However, I think of it more in terms of an information subscription service.  Basically you subscribe to the information stream or &#8220;tweets&#8221; of other Twitter members by &#8220;following&#8221; them.  Likewise, other people subscribe to your information stream, &#8220;tweets&#8221;, if they find you interesting. That might turn out to be friends and family for you, but in my opinion this is where Twitter falls flat in the face of competitors like Facebook.  More on that later.</p>
<p>The ability to selectively follow people or organizations with the same common interests as yourself is the real benefit of Twitter. You will not be tapping into the maximum potential of Twitter by limiting yourself to following friends and family. The idea is to form a large network of social connections with like minded people or organizations. You can use your Twitter network as a resource for getting answers to questions and turning you on to valuable information you may have missed otherwise.  A lot of people will share links to articles and blog posts that you may find useful.  It&#8217;s like having your own little army collectively scouring  the web for information you might find useful. If you&#8217;re following a high profile person in a certain industry, you may get tidbits of inside information and goings on inside that industry. You should likewise be contributing useful information to your stream or tweets. Your target audience will dictate what information you provide; different people will find different types of information useful.</p>
<p><strong>What&#8217;s the difference between Facebook and Twitter?</strong></p>
<p>I&#8217;ve seen a few people on Facebook wondering what they&#8217;re missing out on by not using Twitter or if they should switch from Facebook to Twitter.  There seems to be a lot of  general confusion as to why we need another social networking site.  If had to describe Twitter in terms of Facebook, I would describe it as Facebook if you stripped out everything but the status update and then limited that to 140 characters. So, should you start using Twitter?  Like the answer to every other question like this; it depends.</p>
<p>In my opinion if you are using Facebook to stay in touch with people on a personal  level such as friends and family and you don&#8217;t care about anything else, then you aren&#8217;t missing much by not using Twitter.  It is arguable, but I think Facebook is the superior service for staying in touch with people on a personal level.  You can share media on Twitter through sites like <a href="http://www.twitpic.com">twitpic</a>, but Facebook  has much better integration for sharing media since you can post it directly into your live feed.  Twitter is also devoid of things like wall posts, quizzes, and games that a lot of people like to do on Facebook.  Facebook also lets you stay connected on the go just as easily as Twitter through mobile apps and SMS messaging. I can&#8217;t speak to other devices, but from my experience the Facebook application for BlackBerry is much better than TwitterBerry or Tiny Twitter.</p>
<p>On the other hand, if you&#8217;re interested in connecting with people in your profession or people who share the same hobbies, you might want to check out Twitter.  Also, if you&#8217;re looking to promote yourself or small business, Twitter might be for you.  If you want to get a peek into the lives of high profile people such as celebrities, politicians, or movers and shakers in a specific industry, Twitter is the place.<strong></strong></p>
<p><strong>How do I get started with Twitter?<br />
</strong></p>
<p>Simply go to <a href="http://twitter.com">http://twitter.com</a> and sign up for an account. Figuring out who to follow is one of the hardest parts when you first start.  Use tools like <a href="http://search.twitter.com">Twitter search</a> to find people who are tweeting about the things you&#8217;re interested in.  Don&#8217;t be shy about following somebody; most people are more than happy to get new followers.  Look to see who the people you&#8217;re following are following and follow them.</p>
<p>Here is an excellent blog post that is much more detailed about getting started:</p>
<p><a href="http://www.maine-seo.com/social-media/how-to-become-a-twitter-pro-in-no-time-a-guide-for-twitter-newbies">http://www.maine-seo.com/social-media/how-to-become-a-twitter-pro-in-no-time-a-guide-for-twitter-newbies</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/roguecoder.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/roguecoder.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/roguecoder.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/roguecoder.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/roguecoder.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/roguecoder.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/roguecoder.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/roguecoder.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/roguecoder.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/roguecoder.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/roguecoder.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/roguecoder.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/roguecoder.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/roguecoder.wordpress.com/63/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=63&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://roguecoder.wordpress.com/2009/05/16/2-tweet-or-not-2-tweet/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/70f14d7cfe282c558d45a6ec0dba9f05?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">roguecoder</media:title>
		</media:content>
	</item>
		<item>
		<title>Using Struts 1 and Struts 2 in the Same Web App</title>
		<link>http://roguecoder.wordpress.com/2009/05/15/using-struts-1-and-struts-2-in-the-same-web-app/</link>
		<comments>http://roguecoder.wordpress.com/2009/05/15/using-struts-1-and-struts-2-in-the-same-web-app/#comments</comments>
		<pubDate>Fri, 15 May 2009 14:52:23 +0000</pubDate>
		<dc:creator>roguecoder</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Struts 2]]></category>
		<category><![CDATA[Struts]]></category>
		<category><![CDATA[Struts 1]]></category>
		<category><![CDATA[Struts2]]></category>

		<guid isPermaLink="false">http://roguecoder.wordpress.com/?p=10</guid>
		<description><![CDATA[For those of you migrating from Struts 1 to Struts 2 as your primary web framework, I&#8217;m sure you have lots of old Struts 1 apps you aren&#8217;t quite ready to migrate.  I was in the same boat about a year ago.  I wanted to get up and running with Struts 2 quickly, but I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=10&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>For those of you migrating from Struts 1 to Struts 2 as your primary web framework, I&#8217;m sure you have lots of old Struts 1 apps you aren&#8217;t quite ready to migrate.  I was in the same boat about a year ago.  I wanted to get up and running with Struts 2 quickly, but I didn&#8217;t want to migrate all of my Struts 1 applications at once.</p>
<p>Well the good news is Struts 1 and Struts 2 can both run in the same web app in perfect harmony; however, there are a few pit falls that you should be aware of when making the transition.</p>
<p>The remainder of the post will assume you already have Struts 2.1.6  installed and running on your application server.  For instructions go here: <a href="http://struts.apache.org/2.1.6/docs/simple-setup.html"> http://struts.apache.org/2.1.6/docs/simple-setup.html</a></p>
<p>The first thing you&#8217;ll likely notice about the Struts 2 setup is the use of a Filter instead of a servlet mapping like Struts 1.  Here is an excerpt from a web.xml file showing a simple Struts 2 configuration:</p>
<pre class="code-java" style="text-align:left;margin:5px 5px 5px 15px;padding:0;">&lt;filter&gt;
  &lt;filter-name&gt;struts2&lt;/filter-name&gt;
  &lt;filter-class&gt;org.apache.struts2.dispatcher.FilterDispatcher&lt;/filter-class&gt;
&lt;/filter&gt;

&lt;filter-mapping&gt;
  &lt;filter-name&gt;struts2&lt;/filter-name&gt;
  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</pre>
<p>Note the url-pattern of the filter -mapping tag.  This setup will send every request through the Struts 2 filter.  This approach will cause potential conflicts with your Strtus 1 setup.</p>
<p><strong>The Problem:</strong></p>
<p>After installing Struts 2 with the configuration above I noticed that my Struts 1 forms that handled multipart/form-data, or file uploads, no longer worked.  A little investigating revealed the form data was being intercepted by the Struts 2 file upload interceptor. The reason for the intercept was because the request was hitting the Struts 2 filter before the Struts 1 servlet.  I could have just disabled the Struts 2 file upload interceptor, but I knew I wanted Struts 2 forms that could handle multipart/form-data.</p>
<p><strong>Solution 1:</strong></p>
<p>My first solution was to reconfigure Struts 2 as follows:</p>
<pre class="code-java" style="text-align:left;margin:5px 5px 5px 15px;padding:0;">&lt;filter&gt;
  &lt;filter-name&gt;struts2&lt;/filter-name&gt;
  &lt;filter-class&gt;org.apache.struts2.dispatcher.FilterDispatcher&lt;/filter-class&gt;
&lt;/filter&gt;

&lt;filter-mapping&gt;
  &lt;filter-name&gt;struts2&lt;/filter-name&gt;
  &lt;url-pattern&gt;*.action&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</pre>
<p>Notice the new url-pattern.  The *.action pattern only sends requests ending in .action through the Struts 2 filter.  I thought I was finally good to go&#8230;.until I tried using the Struts 2 &lt;datetimepicker&gt; tag.</p>
<p>The &lt;datetimerpicker&gt; tag causes requests for several different resource types including .js, .css, .gif, .png, and .html.  This fact isn&#8217;t isolated to the datetimepicker; that&#8217;s just how I discovered it.  Anytime a Struts 2 tag that depends on requests for resources other than .action is used, the requested resource types must pass through the Struts 2 filter.  Basically, you need the Struts 2 filter to intercept requests for several different types of resources, not just .action.</p>
<p><strong>Solution 2:</strong></p>
<p>Finally, I modified my Struts 2 configuration to look like this:</p>
<pre class="code-java" style="text-align:left;margin:5px 5px 5px 15px;padding:0;">&lt;filter&gt;
  &lt;filter-name&gt;struts2&lt;/filter-name&gt;
  &lt;filter-class&gt;org.apache.struts2.dispatcher.FilterDispatcher&lt;/filter-class&gt;
&lt;/filter&gt;

&lt;filter-mapping&gt;
  &lt;filter-name&gt;struts2&lt;/filter-name&gt;
  &lt;url-pattern&gt;*.action&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;

&lt;filter-mapping&gt;
  &lt;filter-name&gt;struts2&lt;/filter-name&gt;
  &lt;url-pattern&gt;*.js&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;

&lt;filter-mapping&gt;
  &lt;filter-name&gt;struts2&lt;/filter-name&gt;
  &lt;url-pattern&gt;*.css&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;

&lt;filter-mapping&gt;
  &lt;filter-name&gt;struts2&lt;/filter-name&gt;
  &lt;url-pattern&gt;*.html&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;

&lt;filter-mapping&gt;
  &lt;filter-name&gt;struts2&lt;/filter-name&gt;
  &lt;url-pattern&gt;*.gif&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;

&lt;filter-mapping&gt;
  &lt;filter-name&gt;struts2&lt;/filter-name&gt;
  &lt;url-pattern&gt;*.png&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</pre>
<p>The new configuration ensures requests for various resources used by certain Struts 2 tags will pass through the Struts 2 filter.  I haven&#8217;t had any problems with Struts 2 tags since I started using this configuration; and I use the Ajax tags extensively throughout my applications.</p>
<p>There may be a more elegant way to configure Struts 1 and Struts 2 within the same web app, but so far this has worked for me.</p>
<p>Until next time.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/roguecoder.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/roguecoder.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/roguecoder.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/roguecoder.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/roguecoder.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/roguecoder.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/roguecoder.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/roguecoder.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/roguecoder.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/roguecoder.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/roguecoder.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/roguecoder.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/roguecoder.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/roguecoder.wordpress.com/10/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=roguecoder.wordpress.com&amp;blog=7757739&amp;post=10&amp;subd=roguecoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://roguecoder.wordpress.com/2009/05/15/using-struts-1-and-struts-2-in-the-same-web-app/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/70f14d7cfe282c558d45a6ec0dba9f05?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">roguecoder</media:title>
		</media:content>
	</item>
	</channel>
</rss>
