You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2020/06/29 06:55:38 UTC

[struts] branch WW-5080-plain-result updated (ac06412 -> f15d85b)

This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a change to branch WW-5080-plain-result
in repository https://gitbox.apache.org/repos/asf/struts.git.


 discard ac06412  WW-5080 Defines a new result type plain to use directly with Java code
     new f15d85b  WW-5080 Defines a new result type plain to use directly with Java code

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (ac06412)
            \
             N -- N -- N   refs/heads/WW-5080-plain-result (f15d85b)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/struts2/result/PlainResultTest.java     | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)


[struts] 01/01: WW-5080 Defines a new result type plain to use directly with Java code

Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch WW-5080-plain-result
in repository https://gitbox.apache.org/repos/asf/struts.git

commit f15d85b496d7723cd8dfbe984ea48ad1363806e9
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Mon Jun 29 08:16:48 2020 +0200

    WW-5080 Defines a new result type plain to use directly with Java code
---
 .../org/apache/struts2/result/PlainResult.java     |  64 +++++++++++
 .../apache/struts2/result/plain/BodyWriter.java    |  41 +++++++
 .../struts2/result/plain/DateHttpHeader.java       |  38 +++++++
 .../apache/struts2/result/plain/HttpCookies.java   |  39 +++++++
 .../apache/struts2/result/plain/HttpHeader.java    |  27 +++++
 .../apache/struts2/result/plain/HttpHeaders.java   |  58 ++++++++++
 .../apache/struts2/result/plain/IntHttpHeader.java |  39 +++++++
 .../struts2/result/plain/ResponseBuilder.java      | 111 +++++++++++++++++++
 .../struts2/result/plain/StringHttpHeader.java     |  39 +++++++
 .../org/apache/struts2/result/PlainResultTest.java | 123 +++++++++++++++++++++
 10 files changed, 579 insertions(+)

diff --git a/core/src/main/java/org/apache/struts2/result/PlainResult.java b/core/src/main/java/org/apache/struts2/result/PlainResult.java
new file mode 100644
index 0000000..99e978a
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/result/PlainResult.java
@@ -0,0 +1,64 @@
+/*
+ * 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.result;
+
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.Result;
+import org.apache.struts2.StrutsException;
+import org.apache.struts2.result.plain.HttpHeader;
+import org.apache.struts2.result.plain.ResponseBuilder;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+public abstract class PlainResult implements Result {
+
+    @Override
+    public void execute(ActionInvocation invocation) throws Exception {
+        ResponseBuilder builder = new ResponseBuilder();
+        write(builder);
+
+        HttpServletResponse response = invocation.getInvocationContext().getServletResponse();
+
+        if (response.isCommitted()) {
+            throw new StrutsException("Http response already committed, cannot modify it!");
+        }
+
+        for (HttpHeader<String> header : builder.getStringHeaders()) {
+            response.addHeader(header.getName(), header.getValue());
+        }
+        for (HttpHeader<Long> header : builder.getDateHeaders()) {
+            response.addDateHeader(header.getName(), header.getValue());
+        }
+        for (HttpHeader<Integer> header : builder.getIntHeaders()) {
+            response.addIntHeader(header.getName(), header.getValue());
+        }
+
+        for (Cookie cookie : builder.getCookies()) {
+            response.addCookie(cookie);
+        }
+
+        response.getWriter().write(builder.getBody());
+        response.flushBuffer();
+    }
+
+    protected abstract void write(ResponseBuilder response);
+
+}
+
diff --git a/core/src/main/java/org/apache/struts2/result/plain/BodyWriter.java b/core/src/main/java/org/apache/struts2/result/plain/BodyWriter.java
new file mode 100644
index 0000000..ff22769
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/result/plain/BodyWriter.java
@@ -0,0 +1,41 @@
+/*
+ * 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.result.plain;
+
+import java.io.StringWriter;
+
+class BodyWriter {
+
+    private final StringWriter body = new StringWriter();
+
+    public BodyWriter write(String out) {
+        body.write(out);
+        return this;
+    }
+
+    public BodyWriter writeLine(String out) {
+        body.write(out);
+        body.write("\n");
+        return this;
+    }
+
+    public String getBody() {
+        return body.toString();
+    }
+}
diff --git a/core/src/main/java/org/apache/struts2/result/plain/DateHttpHeader.java b/core/src/main/java/org/apache/struts2/result/plain/DateHttpHeader.java
new file mode 100644
index 0000000..906860b
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/result/plain/DateHttpHeader.java
@@ -0,0 +1,38 @@
+/*
+ * 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.result.plain;
+
+class DateHttpHeader implements HttpHeader<Long> {
+
+    private final String name;
+    private final Long value;
+
+    public DateHttpHeader(String name, Long value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Long getValue() {
+        return value;
+    }
+}
diff --git a/core/src/main/java/org/apache/struts2/result/plain/HttpCookies.java b/core/src/main/java/org/apache/struts2/result/plain/HttpCookies.java
new file mode 100644
index 0000000..22c105b
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/result/plain/HttpCookies.java
@@ -0,0 +1,39 @@
+/*
+ * 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.result.plain;
+
+import javax.servlet.http.Cookie;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+class HttpCookies {
+
+    private final List<Cookie> cookies = new ArrayList<>();
+
+    public HttpCookies add(String name, String value) {
+        cookies.add(new Cookie(name, value));
+        return this;
+    }
+
+    public List<Cookie> getCookies() {
+        return Collections.unmodifiableList(cookies);
+    }
+
+}
diff --git a/core/src/main/java/org/apache/struts2/result/plain/HttpHeader.java b/core/src/main/java/org/apache/struts2/result/plain/HttpHeader.java
new file mode 100644
index 0000000..90de858
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/result/plain/HttpHeader.java
@@ -0,0 +1,27 @@
+/*
+ * 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.result.plain;
+
+public interface HttpHeader<T> {
+
+    String getName();
+
+    T getValue();
+
+}
diff --git a/core/src/main/java/org/apache/struts2/result/plain/HttpHeaders.java b/core/src/main/java/org/apache/struts2/result/plain/HttpHeaders.java
new file mode 100644
index 0000000..31715c6
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/result/plain/HttpHeaders.java
@@ -0,0 +1,58 @@
+/*
+ * 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.result.plain;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+class HttpHeaders {
+
+    private final List<HttpHeader<String>> stringHeaders = new ArrayList<>();
+    private final List<HttpHeader<Long>> dateHeaders = new ArrayList<>();
+    private final List<HttpHeader<Integer>> intHeaders = new ArrayList<>();
+
+    public HttpHeaders add(String name, String value) {
+        stringHeaders.add(new StringHttpHeader(name, value));
+        return this;
+    }
+
+    public HttpHeaders add(String name, Long value) {
+        dateHeaders.add(new DateHttpHeader(name, value));
+        return this;
+    }
+
+    public HttpHeaders add(String name, Integer value) {
+        intHeaders.add(new IntHttpHeader(name, value));
+        return this;
+    }
+
+    public List<HttpHeader<String>> getStringHeaders() {
+        return Collections.unmodifiableList(stringHeaders);
+    }
+
+    public List<HttpHeader<Long>> getDateHeaders() {
+        return Collections.unmodifiableList(dateHeaders);
+    }
+
+    public List<HttpHeader<Integer>> getIntHeaders() {
+        return Collections.unmodifiableList(intHeaders);
+    }
+
+}
diff --git a/core/src/main/java/org/apache/struts2/result/plain/IntHttpHeader.java b/core/src/main/java/org/apache/struts2/result/plain/IntHttpHeader.java
new file mode 100644
index 0000000..c190617
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/result/plain/IntHttpHeader.java
@@ -0,0 +1,39 @@
+/*
+ * 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.result.plain;
+
+class IntHttpHeader implements HttpHeader<Integer> {
+
+    private final String name;
+    private final Integer value;
+
+    public IntHttpHeader(String name, Integer value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Integer getValue() {
+        return value;
+    }
+
+}
diff --git a/core/src/main/java/org/apache/struts2/result/plain/ResponseBuilder.java b/core/src/main/java/org/apache/struts2/result/plain/ResponseBuilder.java
new file mode 100644
index 0000000..5e1ae20
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/result/plain/ResponseBuilder.java
@@ -0,0 +1,111 @@
+/*
+ * 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.result.plain;
+
+import javax.servlet.http.Cookie;
+
+public class ResponseBuilder {
+
+    public static final String CONTENT_TYPE = "Content-Type";
+
+    public static final String TEXT_PLAIN = "text/plain";
+    public static final String TEXT_HTML = "text/html";
+    public static final String APPLICATION_JSON = "application/json";
+
+    private final BodyWriter body;
+    private final HttpHeaders headers;
+    private final HttpCookies cookies;
+
+    public ResponseBuilder() {
+        this.body = new BodyWriter();
+        this.headers = new HttpHeaders().add(CONTENT_TYPE, TEXT_PLAIN + "; charset=UTF-8");
+        this.cookies = new HttpCookies();
+    }
+
+    public ResponseBuilder write(String out) {
+        body.write(out);
+        return this;
+    }
+
+    public ResponseBuilder writeLine(String out) {
+        body.writeLine(out);
+        return this;
+    }
+
+    public ResponseBuilder withHeader(String name, String value) {
+        headers.add(name, value);
+        return this;
+    }
+
+    public ResponseBuilder withHeader(String name, Long value) {
+        headers.add(name, value);
+        return this;
+    }
+
+    public ResponseBuilder withHeader(String name, Integer value) {
+        headers.add(name, value);
+        return this;
+    }
+
+    public ResponseBuilder withContentTypeTextPlain() {
+        headers.add(CONTENT_TYPE, TEXT_PLAIN + "; charset=UTF-8");
+        return this;
+    }
+
+    public ResponseBuilder withContentTypeTextHtml() {
+        headers.add(CONTENT_TYPE, TEXT_HTML + "; charset=UTF-8");
+        return this;
+    }
+
+    public ResponseBuilder withContentTypeJson() {
+        headers.add(CONTENT_TYPE, APPLICATION_JSON);
+        return this;
+    }
+
+    public ResponseBuilder withContentType(String contentType) {
+        headers.add(CONTENT_TYPE, contentType);
+        return this;
+    }
+
+    public ResponseBuilder withCookie(String name, String value) {
+        cookies.add(name, value);
+        return this;
+    }
+
+    public Iterable<HttpHeader<String>> getStringHeaders() {
+        return headers.getStringHeaders();
+    }
+
+    public Iterable<HttpHeader<Long>> getDateHeaders() {
+        return headers.getDateHeaders();
+    }
+
+    public Iterable<HttpHeader<Integer>> getIntHeaders() {
+        return headers.getIntHeaders();
+    }
+
+    public Iterable<Cookie> getCookies() {
+        return cookies.getCookies();
+    }
+
+    public String getBody() {
+        return body.getBody();
+    }
+
+}
diff --git a/core/src/main/java/org/apache/struts2/result/plain/StringHttpHeader.java b/core/src/main/java/org/apache/struts2/result/plain/StringHttpHeader.java
new file mode 100644
index 0000000..e4e3e03
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/result/plain/StringHttpHeader.java
@@ -0,0 +1,39 @@
+/*
+ * 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.result.plain;
+
+class StringHttpHeader implements HttpHeader<String> {
+
+    private final String name;
+    private final String value;
+
+    public StringHttpHeader(String name, String value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+}
diff --git a/core/src/test/java/org/apache/struts2/result/PlainResultTest.java b/core/src/test/java/org/apache/struts2/result/PlainResultTest.java
new file mode 100644
index 0000000..7e0ff11
--- /dev/null
+++ b/core/src/test/java/org/apache/struts2/result/PlainResultTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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.result;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.mock.MockActionInvocation;
+import org.apache.struts2.StrutsInternalTestCase;
+import org.apache.struts2.result.plain.ResponseBuilder;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+public class PlainResultTest extends StrutsInternalTestCase {
+
+    private MockHttpServletResponse response;
+    private MockActionInvocation invocation;
+
+    public void testWritePlainText() throws Exception {
+        PlainResult result = new PlainResult() {
+            @Override
+            protected void write(ResponseBuilder response) {
+                response.write("test")
+                    .withContentTypeTextPlain();
+            }
+        };
+
+        result.execute(invocation);
+
+        assertEquals("test", response.getContentAsString());
+        assertEquals("text/plain; charset=UTF-8", response.getContentType());
+    }
+
+    public void testWritePlainHtml() throws Exception {
+        PlainResult result = new PlainResult() {
+            @Override
+            protected void write(ResponseBuilder response) {
+                response.write("<b>test</b>")
+                    .withContentTypeTextHtml();
+            }
+        };
+
+        result.execute(invocation);
+
+        assertEquals("<b>test</b>", response.getContentAsString());
+        assertEquals("text/html; charset=UTF-8", response.getContentType());
+    }
+
+    public void testWriteJson() throws Exception {
+        PlainResult result = new PlainResult() {
+            @Override
+            protected void write(ResponseBuilder response) {
+                response.write("{ 'value': 'test' }")
+                    .withContentTypeJson();
+            }
+        };
+
+        result.execute(invocation);
+
+        assertEquals("{ 'value': 'test' }", response.getContentAsString());
+        assertEquals("application/json", response.getContentType());
+    }
+
+    public void testWriteContentTypeCsvWithCookie() throws Exception {
+        PlainResult result = new PlainResult() {
+            @Override
+            protected void write(ResponseBuilder response) {
+                response.writeLine("name;value")
+                    .withContentType("text/csv")
+                    .withCookie("X-Test", "test")
+                    .writeLine("line;1")
+                    .write("line;2");
+            }
+        };
+
+        result.execute(invocation);
+
+        assertEquals("name;value\nline;1\nline;2", response.getContentAsString());
+        assertEquals("text/csv", response.getContentType());
+    }
+
+    public void testHeaders() throws Exception {
+        PlainResult result = new PlainResult() {
+            @Override
+            protected void write(ResponseBuilder response) {
+                response.withHeader("X-String", "test")
+                    .withHeader("X-Date", 0L)
+                    .withHeader("X-Number", 100)
+                    .write("");
+            }
+        };
+
+        result.execute(invocation);
+
+        assertEquals("", response.getContentAsString());
+        assertEquals("text/plain; charset=UTF-8", response.getContentType());
+        assertEquals("test", response.getHeader("X-String"));
+        assertEquals("Thu, 01 Jan 1970 00:00:00 GMT", response.getHeader("X-Date"));
+        assertEquals("100", response.getHeader("X-NUmber"));
+    }
+
+    public void setUp() throws Exception {
+        super.setUp();
+        invocation = new MockActionInvocation();
+        response = new MockHttpServletResponse();
+        invocation.setInvocationContext(ActionContext.getContext());
+
+        ActionContext.getContext().withServletResponse(response).withActionInvocation(invocation);
+    }
+}
\ No newline at end of file