1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts2.dispatcher;
22
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.Map;
26
27 import javax.servlet.http.HttpServletResponse;
28
29 import org.apache.struts2.ServletActionContext;
30
31 import com.opensymphony.xwork2.ActionContext;
32 import com.opensymphony.xwork2.ActionInvocation;
33 import com.opensymphony.xwork2.Result;
34 import com.opensymphony.xwork2.util.TextParseUtil;
35 import com.opensymphony.xwork2.util.ValueStack;
36
37
38 /***
39 * <!-- START SNIPPET: description -->
40 *
41 * A custom Result type for setting HTTP headers and status by optionally evaluating against the ValueStack.
42 *
43 * <!-- END SNIPPET: description -->
44 * <p/>
45 * <b>This result type takes the following parameters:</b>
46 *
47 * <!-- START SNIPPET: params -->
48 *
49 * <ul>
50 *
51 * <li><b>status</b> - the http servlet response status code that should be set on a response.</li>
52 *
53 * <li><b>parse</b> - true by default. If set to false, the headers param will not be parsed for Ognl expressions.</li>
54 *
55 * <li><b>headers</b> - header values.</li>
56 *
57 * </ul>
58 *
59 * <!-- END SNIPPET: params -->
60 *
61 * <b>Example:</b>
62 *
63 * <pre><!-- START SNIPPET: example -->
64 * <result name="success" type="httpheader">
65 * <param name="status">204</param>
66 * <param name="headers.a">a custom header value</param>
67 * <param name="headers.b">another custom header value</param>
68 * </result>
69 * <!-- END SNIPPET: example --></pre>
70 *
71 */
72 public class HttpHeaderResult implements Result {
73
74 private static final long serialVersionUID = 195648957144219214L;
75
76 /*** The default parameter */
77 public static final String DEFAULT_PARAM = "status";
78
79
80 private boolean parse = true;
81 private Map<String,String> headers;
82 private int status = -1;
83
84 public HttpHeaderResult() {
85 super();
86 headers = new HashMap<String,String>();
87 }
88
89 public HttpHeaderResult(int status) {
90 this();
91 this.status = status;
92 this.parse = false;
93 }
94
95
96 /***
97 * Returns a Map of all HTTP headers.
98 *
99 * @return a Map of all HTTP headers.
100 */
101 public Map getHeaders() {
102 return headers;
103 }
104
105 /***
106 * Sets whether or not the HTTP header values should be evaluated against the ValueStack (by default they are).
107 *
108 * @param parse <tt>true</tt> if HTTP header values should be evaluated agains the ValueStack, <tt>false</tt>
109 * otherwise.
110 */
111 public void setParse(boolean parse) {
112 this.parse = parse;
113 }
114
115 /***
116 * Sets the http servlet response status code that should be set on a response.
117 *
118 * @param status the Http status code
119 * @see javax.servlet.http.HttpServletResponse#setStatus(int)
120 */
121 public void setStatus(int status) {
122 this.status = status;
123 }
124
125 /***
126 * Adds an HTTP header to the response
127 * @param name
128 * @param value
129 */
130 public void addHeader(String name, String value) {
131 headers.put(name, value);
132 }
133
134 /***
135 * Sets the optional HTTP response status code and also re-sets HTTP headers after they've
136 * been optionally evaluated against the ValueStack.
137 *
138 * @param invocation an encapsulation of the action execution state.
139 * @throws Exception if an error occurs when re-setting the headers.
140 */
141 public void execute(ActionInvocation invocation) throws Exception {
142 HttpServletResponse response = ServletActionContext.getResponse();
143
144 if (status != -1) {
145 response.setStatus(status);
146 }
147
148 if (headers != null) {
149 ValueStack stack = ActionContext.getContext().getValueStack();
150
151 for (Iterator iterator = headers.entrySet().iterator();
152 iterator.hasNext();) {
153 Map.Entry entry = (Map.Entry) iterator.next();
154 String value = (String) entry.getValue();
155 String finalValue = parse ? TextParseUtil.translateVariables(value, stack) : value;
156 response.addHeader((String) entry.getKey(), finalValue);
157 }
158 }
159 }
160 }