From 9d6e6a6b0fcfb900daf951fa34750427f5b772ed Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Thu, 23 May 2013 14:12:24 +0000 Subject: [PATCH] WW-4037 Adds functionality to create Cookies in action and apply them to response git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@1485719 13f79535-47bb-0310-9956-ffa450edef68 --- .../struts2/interceptor/CookieProvider.java | 41 +++++++ .../CookieProviderInterceptor.java | 115 ++++++++++++++++++ core/src/main/resources/struts-default.xml | 1 + .../CookieProviderInterceptorTest.java | 55 +++++++++ 4 files changed, 212 insertions(+) create mode 100644 core/src/main/java/org/apache/struts2/interceptor/CookieProvider.java create mode 100644 core/src/main/java/org/apache/struts2/interceptor/CookieProviderInterceptor.java create mode 100644 core/src/test/java/org/apache/struts2/interceptor/CookieProviderInterceptorTest.java diff --git a/core/src/main/java/org/apache/struts2/interceptor/CookieProvider.java b/core/src/main/java/org/apache/struts2/interceptor/CookieProvider.java new file mode 100644 index 000000000..d7aeed525 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/interceptor/CookieProvider.java @@ -0,0 +1,41 @@ +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.struts2.interceptor; + +import javax.servlet.http.Cookie; +import java.util.Set; + +/** + * Action can create cookies which will be stored in response + * + * @see CookieProviderInterceptor + */ +public interface CookieProvider { + + /** + * Return cookies which should be send to client + * + * @return set of cookies or null + */ + Set getCookies(); + +} \ No newline at end of file diff --git a/core/src/main/java/org/apache/struts2/interceptor/CookieProviderInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/CookieProviderInterceptor.java new file mode 100644 index 000000000..88d829cb2 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/interceptor/CookieProviderInterceptor.java @@ -0,0 +1,115 @@ +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.struts2.interceptor; + +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.interceptor.AbstractInterceptor; +import com.opensymphony.xwork2.interceptor.PreResultListener; +import com.opensymphony.xwork2.util.logging.Logger; +import com.opensymphony.xwork2.util.logging.LoggerFactory; +import org.apache.struts2.StrutsStatics; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; +import java.util.Set; + +/** + * + * Allows actions to send cookies to client, action must implement {@link CookieProvider} + * You must reference this interceptor in your default stack or in action's stack, see example below. + * + * + * + * + * + * none + * + * + * + * + * + * + * + * + * + *
+ * 
+ *
+ * <action ... >
+ *   <interceptor-ref name="defaultStack"/>
+ *   <interceptor-ref name="cookieProvider"/>
+ *   ...
+ * </action>
+ *
+ * 
+ * 
+ */ +public class CookieProviderInterceptor extends AbstractInterceptor implements PreResultListener { + + private static final Logger LOG = LoggerFactory.getLogger(CookieProviderInterceptor.class); + + public String intercept(ActionInvocation invocation) throws Exception { + invocation.addPreResultListener(this); + return invocation.invoke(); + } + + /** + * Do what name suggests + * + * @param action {@link CookieProvider} action + * @param response current {@link HttpServletResponse} + */ + protected void addCookiesToResponse(CookieProvider action, HttpServletResponse response) { + Set cookies = action.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if (LOG.isDebugEnabled()) { + LOG.debug("Sending cookie [#0] with value [#1] for domain [#2]", + cookie.getName(), cookie.getValue(), (cookie.getDomain() != null ? cookie.getDomain() : "no domain")); + } + response.addCookie(cookie); + } + } + } + + public void beforeResult(ActionInvocation invocation, String resultCode) { + try { + if (LOG.isTraceEnabled()) { + LOG.trace("beforeResult start"); + } + ActionContext ac = invocation.getInvocationContext(); + if (invocation.getAction() instanceof CookieProvider) { + HttpServletResponse response = (HttpServletResponse) ac.get(StrutsStatics.HTTP_RESPONSE); + addCookiesToResponse((CookieProvider) invocation.getAction(), response); + } + if (LOG.isTraceEnabled()) { + LOG.trace("beforeResult end"); + } + } catch (Exception ex) { + LOG.error("Unable to setup cookies", ex); + } + } + +} diff --git a/core/src/main/resources/struts-default.xml b/core/src/main/resources/struts-default.xml index 4f2d69aae..5eac45019 100644 --- a/core/src/main/resources/struts-default.xml +++ b/core/src/main/resources/struts-default.xml @@ -145,6 +145,7 @@ + diff --git a/core/src/test/java/org/apache/struts2/interceptor/CookieProviderInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/CookieProviderInterceptorTest.java new file mode 100644 index 000000000..5870633b1 --- /dev/null +++ b/core/src/test/java/org/apache/struts2/interceptor/CookieProviderInterceptorTest.java @@ -0,0 +1,55 @@ +package org.apache.struts2.interceptor; + +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.XWorkTestCase; +import org.easymock.EasyMock; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; +import java.util.HashSet; +import java.util.Set; + +public class CookieProviderInterceptorTest extends XWorkTestCase { + + public void testPreResultListenerAddition() throws Exception { + // given + ActionInvocation invocation = EasyMock.createNiceMock(ActionInvocation.class); + CookieProviderInterceptor interceptor = new CookieProviderInterceptor(); + + invocation.addPreResultListener(interceptor); + + EasyMock.replay(invocation); + + // when + interceptor.intercept(invocation); + + // then + EasyMock.verify(invocation); + } + + public void testCookieCreation() throws Exception { + // given + CookieProviderInterceptor interceptor = new CookieProviderInterceptor(); + + final Cookie cookie = new Cookie("foo", "bar"); + + CookieProvider action = new CookieProvider() { + public Set getCookies() { + Set cookies = new HashSet(); + cookies.add(cookie); + return cookies; + } + }; + + HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class); + response.addCookie(cookie); + EasyMock.replay(response); + + // when + interceptor.addCookiesToResponse(action, response); + + // then + EasyMock.verify(response); + } + +}