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