View Javadoc

1   /*
2    * $Id: HttpHeaderResult.java 651946 2008-04-27 13:41:38Z apetrelli $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  package org.apache.struts2.dispatcher;
23  
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.Map;
27  
28  import javax.servlet.http.HttpServletResponse;
29  
30  import org.apache.struts2.ServletActionContext;
31  
32  import com.opensymphony.xwork2.ActionContext;
33  import com.opensymphony.xwork2.ActionInvocation;
34  import com.opensymphony.xwork2.Result;
35  import com.opensymphony.xwork2.util.TextParseUtil;
36  import com.opensymphony.xwork2.util.ValueStack;
37  
38  
39  /***
40   * <!-- START SNIPPET: description -->
41   *
42   * A custom Result type for setting HTTP headers and status by optionally evaluating against the ValueStack.
43   * This result can also be used to send and error to the client.
44   *
45   * <!-- END SNIPPET: description -->
46   * <p/>
47   * <b>This result type takes the following parameters:</b>
48   *
49   * <!-- START SNIPPET: params -->
50   *
51   * <ul>
52   *
53   * <li><b>status</b> - the http servlet response status code that should be set on a response.</li>
54   *
55   * <li><b>parse</b> - true by default. If set to false, the headers param will not be parsed for Ognl expressions.</li>
56   *
57   * <li><b>headers</b> - header values.</li>
58   * 
59   * <li><b>error</b> - the http servlet response error code that should be set on a response.</li>
60   *
61   * <li><b>errorMessage</b> - error message to be set on response if 'error' is set.</li>
62   * </ul>
63   *
64   * <!-- END SNIPPET: params -->
65   *
66   * <b>Example:</b>
67   *
68   * <pre><!-- START SNIPPET: example -->
69   * &lt;result name="success" type="httpheader"&gt;
70   *   &lt;param name="status"&gt;204&lt;/param&gt;
71   *   &lt;param name="headers.a"&gt;a custom header value&lt;/param&gt;
72   *   &lt;param name="headers.b"&gt;another custom header value&lt;/param&gt;
73   * &lt;/result&gt;
74   * 
75   * &lt;result name="proxyRequired" type="httpheader"&gt;
76   *   &lt;param name="error"&gt;305&lt;/param&gt;
77   *   &lt;param name="errorMessage"&gt;this action must be accessed through a prozy&lt;/param&gt;
78   * &lt;/result&gt;
79   * <!-- END SNIPPET: example --></pre>
80   *
81   */
82  public class HttpHeaderResult implements Result {
83  
84      private static final long serialVersionUID = 195648957144219214L;
85  
86      /*** The default parameter */
87      public static final String DEFAULT_PARAM = "status";
88  
89  
90      private boolean parse = true;
91      private Map<String,String> headers;
92      private int status = -1;
93      private int error = -1;
94      private String errorMessage;
95      
96      public HttpHeaderResult() {
97          super();
98          headers = new HashMap<String,String>();
99      }
100 
101     public HttpHeaderResult(int status) {
102         this();
103         this.status = status;
104         this.parse = false;
105     }
106 
107 
108     /***
109      * Sets the http servlet error code that should be set on the reponse
110      * 
111      * @param error the Http error code
112      * @see javax.servlet.http.HttpServletResponse#sendError(int)
113      */
114     public void setError(int error) {
115         this.error = error;
116     }
117     
118     /***
119      * Sets the error message that should be set on the reponse
120      * 
121      * @param errorMessage error message send to the client
122      * @see javax.servlet.http.HttpServletResponse#sendError(int, String)
123      */
124     public void setErrorMessage(String errorMessage) {
125         this.errorMessage = errorMessage;
126     }
127 
128     /***
129      * Returns a Map of all HTTP headers.
130      *
131      * @return a Map of all HTTP headers.
132      */
133     public Map getHeaders() {
134         return headers;
135     }
136 
137     /***
138      * Sets whether or not the HTTP header values should be evaluated against the ValueStack (by default they are).
139      *
140      * @param parse <tt>true</tt> if HTTP header values should be evaluated agains the ValueStack, <tt>false</tt>
141      *              otherwise.
142      */
143     public void setParse(boolean parse) {
144         this.parse = parse;
145     }
146 
147     /***
148      * Sets the http servlet response status code that should be set on a response.
149      *
150      * @param status the Http status code
151      * @see javax.servlet.http.HttpServletResponse#setStatus(int)
152      */
153     public void setStatus(int status) {
154         this.status = status;
155     }
156 
157     /***
158      * Adds an HTTP header to the response
159      * @param name
160      * @param value
161      */
162     public void addHeader(String name, String value) {
163         headers.put(name, value);
164     }
165 
166     /***
167      * Sets the optional HTTP response status code and also re-sets HTTP headers after they've
168      * been optionally evaluated against the ValueStack.
169      *
170      * @param invocation an encapsulation of the action execution state.
171      * @throws Exception if an error occurs when re-setting the headers.
172      */
173     public void execute(ActionInvocation invocation) throws Exception {
174         HttpServletResponse response = ServletActionContext.getResponse();
175         ValueStack stack = ActionContext.getContext().getValueStack();
176         
177         if (status != -1) {
178             response.setStatus(status);
179         } else if (error != -1) {
180             if (errorMessage != null) {
181                 String finalMessage = parse ? TextParseUtil.translateVariables(
182                     errorMessage, stack) : errorMessage;
183                 response.sendError(error, finalMessage);
184             } else
185                 response.sendError(error);
186         }
187 
188         if (headers != null) {
189             for (Iterator iterator = headers.entrySet().iterator();
190                  iterator.hasNext();) {
191                 Map.Entry entry = (Map.Entry) iterator.next();
192                 String value = (String) entry.getValue();
193                 String finalValue = parse ? TextParseUtil.translateVariables(value, stack) : value;
194                 response.addHeader((String) entry.getKey(), finalValue);
195             }
196         }
197     }
198 }