tag:blogger.com,1999:blog-89578161787904351412024-03-13T07:36:55.479+05:300110My (random) thoughts on the wire ...Anonymoushttp://www.blogger.com/profile/00484583641040518813noreply@blogger.comBlogger5125tag:blogger.com,1999:blog-8957816178790435141.post-7377665027323864532012-05-20T13:35:00.001+05:302012-05-20T13:44:35.667+05:30There and back again ...<div dir="ltr" style="text-align: left;" trbidi="on">
I would like to pretend I was not on this planet for last few years, and looking at the frequency of my posts, or rather lack of it, someone might actually believe that. Well, I was right here, doing quite a few things on the technical frontier. However, when it comes to putting it on paper, you know the story.<br />
<br />
Anyway, past is past and everyday is a new beginning. Hence, I'm back with grand aim of making my two (or probably three, I guess I'm flattering myself) readers happy, I have decided that I would be or will try to be fairly regular with my posts now on. Wish me luck and stay tuned ...</div>Anonymoushttp://www.blogger.com/profile/00484583641040518813noreply@blogger.com1Pune, Maharashtra, India18.5204303 73.856743718.3999798 73.6988152 18.6408808 74.014672199999993tag:blogger.com,1999:blog-8957816178790435141.post-54132624167994509632010-02-25T08:06:00.006+05:302010-02-25T08:47:34.663+05:30Learning the hard way - no two laptop keyboards are alikeI learnt a (apparently very obvious) thing yesterday in a hard way. The fact is, just like humans, no two laptop keyboard layouts are alike. My wife created a beautiful PowerPoint presentation on her laptop with quite some effort in the evening. She asked me to just browse through it so that it goes through a second set of eyes. As helpful as ever (at least in my humble opinion, my wife may differ there), I happily went through it, admiring her work, using right-hand topmost key on her laptop keyboard, assuming it to be the "Page Up" key like it was on my laptop. Then I started wondering why the number of slides is going down as I page up, only to realize to my horror, I had been pounding away on "Delete" key. But by then, 7 to 8 slides had been erased.<br /><br />Consequences - My wife putting another hour or so in the night to get her presentation to its prior glory. For me, if I tell you I was tweeting at 1 o'clock in night, you get the picture.<br /><br />Moral of the story - Never ever start pounding away on a laptop that is not yours without paying close attention to the keyboard layout. No two laptop keyboards are alike.<br /><br />Here is how my laptop keyboard looks like-<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuazlzQK0I3ti9qRlAp0WhDv43BGDVD95w_7JBdb0LufWcfvjBjESs3dNglQAVA2ll09gbB9zT1z6-koow9UQWmA7Zqh62OIJD__KkeIs-6DfinGqyv4NIzgtXBmdtZdEMblESGwufqGLf/s1600-h/Photo0016.jpg"><img style="cursor: pointer; width: 320px; height: 240px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuazlzQK0I3ti9qRlAp0WhDv43BGDVD95w_7JBdb0LufWcfvjBjESs3dNglQAVA2ll09gbB9zT1z6-koow9UQWmA7Zqh62OIJD__KkeIs-6DfinGqyv4NIzgtXBmdtZdEMblESGwufqGLf/s320/Photo0016.jpg" alt="" id="BLOGGER_PHOTO_ID_5442013047069724930" border="0" /></a><br /><br />And here is hers-<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZnED9okmugT4d40vq0RH5c_vu-FTA-g_y0Ly0wM_YTQ9F3zs3CzGE9Bd7Oi0M7lqcS8rt70AUna1LvEMFfJ9P6TKEJMg3NgFsCZpVKrOutbG83cBdPmYb5wH31Gof-5udShYGoj7oPwe-/s1600-h/Photo0013.jpg"><img style="cursor: pointer; width: 320px; height: 240px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZnED9okmugT4d40vq0RH5c_vu-FTA-g_y0Ly0wM_YTQ9F3zs3CzGE9Bd7Oi0M7lqcS8rt70AUna1LvEMFfJ9P6TKEJMg3NgFsCZpVKrOutbG83cBdPmYb5wH31Gof-5udShYGoj7oPwe-/s320/Photo0013.jpg" alt="" id="BLOGGER_PHOTO_ID_5442013466403106290" border="0" /></a>Anonymoushttp://www.blogger.com/profile/00484583641040518813noreply@blogger.com1tag:blogger.com,1999:blog-8957816178790435141.post-75601410455490425982007-11-09T22:31:00.006+05:302008-09-13T14:44:04.445+05:30Working with cookies in Struts 2 - Part 3<p>Picking up the hanging thread from my <a href="http://omkarp.blogspot.com/2007/08/working-with-cookies-in-struts-2-part-2.html">previous post</a>, a thread that was left hanging for a little too longer as other concerns, a job switch being the principal one, kept me busy. Now things smoothly falling into place once again, let's conclude this series by taking a look at how Struts2 Interceptors can be utilized for adding Cookies to HTTP Response.</p><br /><p>To begin with, let's remind ourselves how the Struts2 uses Interface Injection. To put it in one line, an interface is defined, an Action implements the interface and interceptors intercept the calls to the action at runtime to call the interface methods on it. Just to give one example, the built in ServletConfigInterceptor works with many "aware" interfaces such as SessionAware, ServletRequestAware etc. to provide access to Servlet-based objects.</p><br /><p>Let's start by defining an interface named CookieProvider. It provides one method named getCookies() which returns a list of Cookies to be added to the HTTP Response. Any action that needs to add cookies to HTTP Response needs to implement it.<br />Here is the code for it - </p><pre><br />package com.omkarpatil.interceptor;<br /><br />import java.util.List;<br />import com.omkarpatil.util.CookieBean;<br /><br />public interface CookieProvider {<br />List<CookieBean> getCookies();<br />}</pre><br /><p>Now let's define an action, HelloWorld, which implements this interface. Here is how it looks like - </p><pre><br />public class HelloWorld extends ActionSupport implements CookieProvider {<br />private String username;<br /><br />public String getUsername() {<br /> return username;<br />}<br /><br />public void setUsername(String username) {<br /> this.username = username;<br />}<br /><br />public String execute() throws Exception {<br /> // Carry out the processing<br /> return SUCCESS;<br />}<br /><br />public List<CookieBean> getCookies() {<br /> List<CookieBean> cookies = new ArrayList<CookieBean>();<br /><br /> CookieBean cookie = new CookieBean();<br /> cookie.setCookieName("flash");<br /> cookie.setCookieValue(getUsername());<br /> //cookie.setPath("/firstapp");<br /><br /> cookies.add(cookie);<br /><br /> return cookies;<br />}<br />}</pre><br /><p>Let's take a look at implementation of getCookies() method. The CookieBean used here is a simple JavaBean that has same attributes as a HTTP cookie. What's the purpose of defining it when we could very well have used the HTTP Cookie? Well, it's a simple JavaBean independent of Servlet environment and that's the purpose of this post, to show how to make an Action independent of Servlet environment while adding a Cookie to a HTTP Response :^)<br />Here is the CookieBean code snippet - </p><pre><br />package com.omkarpatil.util;<br /><br />public class CookieBean {<br />private String cookieName; // Name of cookie<br />private String cookieValue; // value of cookie<br /><br />private String comment; // describes cookie's use<br />private String domain; // domain that sees cookie<br />private int maxAge = -1; // cookies auto-expire<br />private String path; // URLs that see the cookie<br />private boolean secure; // use SSL<br />private int version = 0;<br />.<br />.<br />.<br />//and all the getters and setters for these attributes<br />}<br /></pre><br /><p>Now that we have our Action ready, let's create an Interceptor, CookieProviderInterceptor, that uses the CookieProvider interface. Here is the code for it -</p><pre><br />public class CookieProviderInterceptor extends AbstractInterceptor implements PreResultListener {<br /><br />@Override<br />public String intercept(ActionInvocation invocation) throws Exception {<br /> before(invocation);<br /> return invocation.invoke();<br />}<br /><br />private void before(ActionInvocation invocation) {<br /> invocation.addPreResultListener(this);<br />}<br /><br />private void addCookiesToResponse(Object action, HttpServletResponse response) {<br /> if (action instanceof CookieProvider) {<br /><br /> List<CookieBean> cookies = ((CookieProvider) action).getCookies();<br /><br /> if (cookies != null) {<br /> for (CookieBean cookiebean : cookies) {<br /> Cookie cookie = new Cookie(cookiebean.getCookieName(), cookiebean.getCookieValue());<br /> <br /> //Set any other attributes you would like to add<br /> //A utility such as Commons BeanUtils can be used to copy between to objects<br /> //cookie.setMaxAge(cookiebean.getMaxAge());<br /> //cookie.setPath(cookiebean.getPath());<br /> <br /> response.addCookie(cookie);<br /> }<br /> }<br /> }<br />}<br /><br />public void beforeResult(ActionInvocation invocation, String resultCode) {<br /> ActionContext ac = invocation.getInvocationContext();<br /> HttpServletResponse response = (HttpServletResponse) ac.get(StrutsStatics.HTTP_RESPONSE);<br /> addCookiesToResponse(invocation.getAction(), response); <br />}<br />}</pre><br /><p>Before diving into the code of the interceptor, let's summarize the request lifecycle in Struts2.</p><ol><br /><li><b>Accept Request</b> - The web browser requests a resource</li><br /><li><b>Select Action</b> - The Filter Dispatcher looks at the request and determines the appropriate Action</li><br /><li><b>Push Interceptors</b> - The Interceptors apply common functionality to the request</li><br /><li><b>Invoke Action</b> - The Action method executes</li><br /><li><b>Execute Result</b> - Result is executed</li><br /><li><b>Pop Interceptors</b> - The request passes back through the set of Interceptors after Result is executed</li><br /><li><b>Return Response</b> - The response is returned to the web browser</li></ol><br /><p>Coming back to the Interceptor code, we need to fit our cookie into the Response after the Action has executed and before the Result is executed. PreResultListener allows us to do just that. CookieProviderInterceptor implements PreResultListener and provides implementation of the beforeResult method. In this method, we get the HttpServletResponse object from the ActionContext and add cookies to it. The CookieProviderInterceptor registers itself with the ActionInvocation in the before method, which gets a callback before the result is executed.</p><br /><p>The last piece of this jigsaw puzzle is the configuration of the Interceptor.<br />Here is the struts config file -</p><pre><br /><?xml version="1.0" encoding="UTF-8" ?><br /><!DOCTYPE struts PUBLIC<br /> "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"<br /> "http://struts.apache.org/dtds/struts-2.0.dtd"><br /><struts><br /><package name="default" extends="struts-default"><br /> <interceptors><br /> <interceptor name="cookieprovider"<br /> class="com.omkarpatil.interceptor.CookieProviderInterceptor"><br /> </interceptor><br /> <interceptor-stack name="defaultAndCookiesProvider"><br /> <interceptor-ref name="defaultStack" /><br /> <interceptor-ref name="cookieprovider" /><br /> </interceptor-stack><br /> </interceptors><br /><br /> <action name="HelloWorld_*" method="{1}" class="com.omkarpatil.HelloWorld"><br /> <result name="input">/Welcome.jsp</result><br /> <result type="redirect-action"><br /> <param name="actionName">Greet</param><br /> </result><br /> <interceptor-ref name="defaultAndCookiesProvider" /><br /> </action><br /><br /> <action name="Greet" class="com.omkarpatil.Greeter"><br /> <result>/greet.jsp</result><br /> <interceptor-ref name="cookie"><br /> <param name="cookiesName">flash</param><br /> </interceptor-ref><br /> </action> <br /></package><br /></struts></pre><br /><p>That completes our mini-series about cookie handling in Struts2. Hope this is useful. Good luck and happy Strutting.<br /></p><p><span style="font-weight: bold; color: rgb(153, 102, 51);"><br /></span></p><p><span style="font-weight: bold; color: rgb(0, 0, 153);">Note - Difference between packaged CookieInterceptor and CookieProviderInterceptor</span><br /><br /><span style="color: rgb(0, 0, 153);">The CookieInterceptor that comes packaged only works on the cookies for the inbound requests. It picks up cookies that are present in the incoming http request and then based on S2 configuration, injects them into S2 actions. It doesn't give you any facility to add cookies into an outgoing http response. The CookieProviderInterceptor, fills this gap and provides the facility to add cookies to an outgoing http response.</span><br /><br /></p><p></p><p></p>Anonymoushttp://www.blogger.com/profile/00484583641040518813noreply@blogger.com3tag:blogger.com,1999:blog-8957816178790435141.post-29637834243650370112007-08-01T22:34:00.000+05:302007-08-02T00:13:05.280+05:30Working with cookies in Struts 2 - Part 2Continuing from my <a href="http://omkarp.blogspot.com/2007/07/working-with-cookies-in-struts2.html">earlier post</a>, let's see how to add cookies to a HTTP response in an action class. Here also, I could figure out two ways by which it can be achieved -<br /><ol><li>Use <span style="font-style: italic;">ServletActionContext</span> to get HTTP response and set a cookie on it in the action</li><br /><li>Make the action implement <span style="font-style: italic;">ServletResponseAware</span> interface and use the HTTP response object made available by the framework</li></ol><br /><p>Let's say we have an action class <span style="font-style: italic;">HelloWorld</span> that needs to add a cookie named <span style="font-style: italic;">flash </span>in the response.<br />Using the first option is pretty straightforward, here is how the code looks like - </p><br /><div><pre><br />public class HelloWorld extends ActionSupport {<br /> <br /> private String username;<br /> <br /> public String getUsername() {<br /> return username;<br /> }<br /> public void setUsername(String username) {<br /> this.username = username;<br /> }<br /> <br /> public String execute() throws Exception {<br /> ServletActionContext.getResponse().addCookie(new Cookie("flash", getUsername()));<br /> return SUCCESS;<br /> }<br />}<br /></pre></div><br /><p>To use the second option, the <span style="font-style: italic;">HelloWorld</span> action needs to implement <span style="font-style: italic;">ServletResponseAware</span> interface. This interface defines a single method,<br /><span style="font-style: italic;">void setServletResponse(HttpServletResponse response)</span>, which the framework, <span style="font-style: italic;">ServletConfigInterceptor</span> to be precise, uses to carry out interface injection into the action at runtime. Here is how the code looks like -</p><br /><div><pre><br />public class HelloWorld extends ActionSupport implements ServletResponseAware {<br /> <br /> private String username;<br /> private HttpServletResponse response;<br /> <br /> public String getUsername() {<br /> return username;<br /> }<br /> <br /> public void setUsername(String username) {<br /> this.username = username;<br /> }<br /> <br /> public void setServletResponse(HttpServletResponse response) {<br /> this.response = response;<br /> }<br /> <br /> public String execute() throws Exception {<br /> response.addCookie(new Cookie("flash", getUsername()));<br /> return SUCCESS;<br /> }<br />}<br /></pre></div><br /><p>So far, so good. These options will allow us to do the needful. Still, I'm a little uncomfortable using any of these. Reason? Well, both options will tie up the actions to servlet environment, which , amongst others, will make unit testing difficult. Do we have a better option? Yes, in my opinion, we can use the interceptors feature of the Struts 2 framework to our advantage, to abstract this functionality into a separate interceptor and decouple the actions from Servlet API. More on it in the next post. Thanks for reading and stay tuned.</p><br /><br />Anonymoushttp://www.blogger.com/profile/00484583641040518813noreply@blogger.com4tag:blogger.com,1999:blog-8957816178790435141.post-80233106963097642422007-07-28T09:47:00.000+05:302007-09-27T20:27:24.505+05:30Working with cookies in Struts 2I have been working with Struts for a very long time now, in fact, I still clearly remember using <span style="font-style: italic;">perform</span> method in the action classes :^) . And then, a few days ago, I got an opportunity to try my hand at Struts 2, the reincarnation of Struts, and at a first glance, it looks impressive, to say the least.<br /><br />Coming to the subject, when I googled for how to work with cookies in struts 2, I could only find a couple of references, viz. <a href="http://mail-archives.apache.org/mod_mbox/struts-user/200701.mbox/%3CAC0E0610-6454-4473-8170-278748CD7DC2@lo-fi.net%3E">struts-users mail archive link</a> and <a href="http://struts.apache.org/2.x/struts2-core/apidocs/index.html">CookieInterceptor</a> javadoc . So, I'll take this opportunity to share whatever little I have picked up.<br /><br />Let's divide this into two parts -<br /> - Receiving cookies in an action<br /> - Adding cookies to a response in an action<br /><br />First, let's see how to receive cookies in an action. I could figure out two options by which it can be achieved. Well, there could possibly be other options available as well, but I'm sure you'll excuse me, as this post is based on my extremely limited knowledge of struts 2 that I could manage to gather in past couple of days. Please feel free to enlighten me if you know more about it. Both options need the <span style="font-style: italic;">CookieInterceptor</span> to be configured for the action that needs to receive cookies. Here are the two options -<br /><br />Option 1 - Filter cookies in the <span style="font-style: italic;">CookieInterceptor</span> configuration and add properties with the cookie names to the action class<br />Option 2 - Make the action implement <span style="font-style: italic;">CookiesAware</span> interface and receive a map that contains cookies received<br /><br />Let's say we have an action class <span style="font-style: italic;">Greeter</span> that expects a cookie named <span style="font-style: italic;">flash</span> in the incoming request. Here is the action configuration for the <span style="font-style: italic;">CookieInterceptor</span>. The <span style="font-style: italic;">param</span> tag under <span style="font-style: italic;">interceptor-ref</span> tag indicates the cookie name that is expected by the action.<br /><div><pre style="height: 150px;"><br /><action name="Greet" class="com.omkarpatil.Greeter"><br /> <result>/greet.jsp</result><br /> <interceptor-ref name="cookie"><br /> <param name="cookiesName">flash</param><br /> </interceptor-ref><br /></action></pre></div><br /><p>To Use the first option, a field named <span style="font-style: italic;">flash</span> with getters/setters needs to be added to <span style="font-style: italic;">Greeter </span>action. The <span style="font-style: italic;">CookieInterceptor</span> does it's magic at runtime to make the cookie available into the action. Here is the code snippet for <span style="font-style: italic;">Greeter</span> action -</p><br /><div><pre>public class Greeter extends ActionSupport {<br /> private String message;<br /> private String flash;<br /><br /> public String getFlash() {<br /> return flash;<br /> }<br /><br /> public void setFlash(String flash) {<br /> this.flash = flash;<br /> }<br /><br /> public String getMessage() {<br /> return message;<br /> }<br /><br /> public void setMessage(String message) {<br /> this.message = message;<br /> }<br /><br /> public String execute() throws Exception {<br /> setMessage("Hello " + getFlash());<br /> return SUCCESS;<br /> }<br />}</pre></div><br /><p>To use the second option, the <span style="font-style: italic;">Greeter</span> action needs to implement <span style="font-style: italic;">CookiesAware</span> interface. <span style="font-style: italic;">CookiesAware</span> interface defines one method <span style="font-style: italic;">void setCookiesMap(Map cookies)</span>, which the <span style="font-style: italic;">CookiesInterceptor</span> uses to carry out interface injection into the action at runtime.</p><br /><div><pre>public class Greeter extends ActionSupport implements CookiesAware {<br /> private Map cookiesMap;<br /><br /> public Map getCookiesMap() {<br /> return cookiesMap;<br /> }<br /><br /> public void setCookiesMap(Map cookiesMap) {<br /> this.cookiesMap = cookiesMap;<br /> }<br /><br /> public String execute() throws Exception {<br /> // Do whatever you want to with the cookies map<br /> return SUCCESS;<br /> }<br />}</pre></div><br /><p>Well, that covers the "Receiving cookies into action" part. Onto the "Adding cookies to a response" in the next post. Stay tuned. </p><br /><br />Anonymoushttp://www.blogger.com/profile/00484583641040518813noreply@blogger.com15