Wednesday 1 August 2007

Working with cookies in Struts 2 - Part 2

Continuing from my earlier post, 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 -
  1. Use ServletActionContext to get HTTP response and set a cookie on it in the action

  2. Make the action implement ServletResponseAware interface and use the HTTP response object made available by the framework

Let's say we have an action class HelloWorld that needs to add a cookie named flash in the response.
Using the first option is pretty straightforward, here is how the code looks like -



public class HelloWorld extends ActionSupport {

private String username;

public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}

public String execute() throws Exception {
ServletActionContext.getResponse().addCookie(new Cookie("flash", getUsername()));
return SUCCESS;
}
}

To use the second option, the HelloWorld action needs to implement ServletResponseAware interface. This interface defines a single method,
void setServletResponse(HttpServletResponse response), which the framework, ServletConfigInterceptor to be precise, uses to carry out interface injection into the action at runtime. Here is how the code looks like -



public class HelloWorld extends ActionSupport implements ServletResponseAware {

private String username;
private HttpServletResponse response;

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public void setServletResponse(HttpServletResponse response) {
this.response = response;
}

public String execute() throws Exception {
response.addCookie(new Cookie("flash", getUsername()));
return SUCCESS;
}
}

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.