Author: jleroux
Date: Sun Jan 13 08:46:35 2013
New Revision: 1432567

URL: http://svn.apache.org/viewvc?rev=1432567&view=rev
Log:
https://issues.apache.org/jira/browse/OFBIZ-5109
"Allow a whole controller or/and request/s to override a default 302 in case of 
redirect"

Since I did not get any feedbacks but Paul's, I decided to use 302 as default 
instead of 303.
The reason is like that nobody will be surprised. The same (bad for SEO) 
default than Java will be used.

Please test and review, and let's discuss it more if wanted...

Modified:
    ofbiz/trunk/framework/webapp/config/requestHandler.properties
    ofbiz/trunk/framework/webapp/dtd/site-conf.xsd
    
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ConfigXMLReader.java
    
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java

Modified: ofbiz/trunk/framework/webapp/config/requestHandler.properties
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/config/requestHandler.properties?rev=1432567&r1=1432566&r2=1432567&view=diff
==============================================================================
--- ofbiz/trunk/framework/webapp/config/requestHandler.properties (original)
+++ ofbiz/trunk/framework/webapp/config/requestHandler.properties Sun Jan 13 
08:46:35 2013
@@ -1,2 +1,5 @@
 # -- N if you want to use external requests (not in available in current 
controller), see OFBIZ-5037
 throwRequestHandlerExceptionOnMissingLocalRequest=Y
+
+# -- Default HTTP status-code, see OFBIZ-5109
+status-code=302

Modified: ofbiz/trunk/framework/webapp/dtd/site-conf.xsd
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/dtd/site-conf.xsd?rev=1432567&r1=1432566&r2=1432567&view=diff
==============================================================================
--- ofbiz/trunk/framework/webapp/dtd/site-conf.xsd (original)
+++ ofbiz/trunk/framework/webapp/dtd/site-conf.xsd Sun Jan 13 08:46:35 2013
@@ -25,6 +25,7 @@ under the License.
                 <xs:element minOccurs="0" ref="description"/>
                 <xs:element minOccurs="0" ref="owner"/>
                 <xs:element minOccurs="0" ref="errorpage"/>
+                <xs:element minOccurs="0" ref="status-code"/>
                 <xs:element minOccurs="0" maxOccurs="unbounded" ref="handler"/>
                 <xs:element minOccurs="0" ref="protect"/>
                 <xs:element minOccurs="0" ref="firstvisit"/>
@@ -58,6 +59,7 @@ under the License.
     <xs:element name="description" type="xs:string"/>
     <xs:element name="owner" type="xs:string"/>
     <xs:element name="errorpage" type="xs:string"/>
+    <xs:element name="status-code" type="xs:string"/>
     <xs:element name="handler">
         <xs:annotation>
             <xs:documentation>
@@ -639,6 +641,18 @@ under the License.
                 </xs:restriction>
             </xs:simpleType>
         </xs:attribute>
+        <xs:attribute name="status-code" type="xs:string">
+            <xs:annotation>
+                <xs:documentation>
+                    A redirection HTTP status-code
+                    If set it will override (cascading) the default 
status-code sets in requestHandler.properties
+                    and the possible status-code sets at the controller level 
(inclusive included controllers)
+                    
+                    Most possible redirection status-codes are 301, 303 and 
307. 
+                    302 (the Java default) is not recommended for SEO reasons. 
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>        
     </xs:attributeGroup>
     <xs:element name="redirect-parameter">
         <xs:annotation>

Modified: 
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ConfigXMLReader.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ConfigXMLReader.java?rev=1432567&r1=1432566&r2=1432567&view=diff
==============================================================================
--- 
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ConfigXMLReader.java 
(original)
+++ 
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ConfigXMLReader.java 
Sun Jan 13 08:46:35 2013
@@ -82,6 +82,7 @@ public class ConfigXMLReader {
         private String owner;
         private String securityClass;
         private String defaultRequest;
+        private String statusCode;
 
         private List<URL> includes = FastList.newInstance();
         private Map<String, Event> firstVisitEventList = FastMap.newInstance();
@@ -145,6 +146,20 @@ public class ConfigXMLReader {
             return null;
         }
 
+        public String getStatusCode() {
+            if (statusCode != null) {
+                return statusCode;
+            }
+            for (URL includeLocation: includes) {
+                ControllerConfig controllerConfig = 
getControllerConfig(includeLocation);
+                String statusCode = controllerConfig.getStatusCode();
+                if (statusCode != null) {
+                    return statusCode;
+                }
+            }
+            return null;
+        }
+
         public String getOwner() {
             if (owner != null) {
                 return owner;
@@ -297,6 +312,7 @@ public class ConfigXMLReader {
             }
 
             this.errorpage = UtilXml.childElementValue(rootElement, 
"errorpage");
+            this.statusCode = UtilXml.childElementValue(rootElement, 
"status-code");
             Element protectElement = UtilXml.firstChildElement(rootElement, 
"protect");
             if (protectElement != null) {
                 this.protectView = protectElement.getAttribute("view");
@@ -593,6 +609,7 @@ public class ConfigXMLReader {
         public String name;
         public String type;
         public String value;
+        public String statusCode;
         public boolean saveLastView = false;
         public boolean saveCurrentView = false;
         public boolean saveHomeView = false;
@@ -603,6 +620,7 @@ public class ConfigXMLReader {
             this.name = responseElement.getAttribute("name");
             this.type = responseElement.getAttribute("type");
             this.value = responseElement.getAttribute("value");
+            this.statusCode = responseElement.getAttribute("status-code");
             this.saveLastView = 
"true".equals(responseElement.getAttribute("save-last-view"));
             this.saveCurrentView = 
"true".equals(responseElement.getAttribute("save-current-view"));
             this.saveHomeView = 
"true".equals(responseElement.getAttribute("save-home-view"));

Modified: 
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java?rev=1432567&r1=1432566&r2=1432567&view=diff
==============================================================================
--- 
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java 
(original)
+++ 
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java 
Sun Jan 13 08:46:35 2013
@@ -20,7 +20,6 @@ package org.ofbiz.webapp.control;
 
 import static org.ofbiz.base.util.UtilGenerics.checkMap;
 
-import java.io.IOException;
 import java.io.Serializable;
 import java.io.UnsupportedEncodingException;
 import java.net.URL;
@@ -66,9 +65,9 @@ import org.owasp.esapi.errors.EncodingEx
 public class RequestHandler {
 
     public static final String module = RequestHandler.class.getName();
-    private static final Boolean 
THROW_REQUEST_HANDLER_EXCEPTION_ON_MISSING_LOCAL_REQUEST =  
-        
UtilProperties.propertyValueEqualsIgnoreCase("requestHandler.properties", 
"throwRequestHandlerExceptionOnMissingLocalRequest", "Y");  
-
+    private boolean throwRequestHandlerExceptionOnMissingLocalRequest = 
UtilProperties.propertyValueEqualsIgnoreCase(
+            "requestHandler.properties", 
"throwRequestHandlerExceptionOnMissingLocalRequest", "Y");
+    private String statusCodeString = 
UtilProperties.getPropertyValue("requestHandler.properties", "status-code", 
"303");
     public static RequestHandler getRequestHandler(ServletContext 
servletContext) {
         RequestHandler rh = (RequestHandler) 
servletContext.getAttribute("_REQUEST_HANDLER_");
         if (rh == null) {
@@ -115,6 +114,9 @@ public class RequestHandler {
         // get the controllerConfig once for this method so we don't have to 
get it over and over inside the method
         ConfigXMLReader.ControllerConfig controllerConfig = 
this.getControllerConfig();
         Map<String, ConfigXMLReader.RequestMap> requestMapMap = 
controllerConfig.getRequestMapMap();
+        String controllerStatusCodeString = controllerConfig.getStatusCode();
+        if(UtilValidate.isNotEmpty(controllerStatusCodeString != null)) 
+            statusCodeString = controllerStatusCodeString;
 
         // workaround if we are in the root webapp
         String cname = UtilHttp.getApplicationName(request);
@@ -155,10 +157,10 @@ public class RequestHandler {
             }
         }
 
-        // if no matching request is found in the controller, depending on 
THROW_REQUEST_HANDLER_EXCEPTION_ON_MISSING_LOCAL_REQUEST
+        // if no matching request is found in the controller, depending on 
throwRequestHandlerExceptionOnMissingLocalRequest
         //  we throw a RequestHandlerException or 
RequestHandlerExceptionAllowExternalRequests
         if (requestMap == null) {
-            if (THROW_REQUEST_HANDLER_EXCEPTION_ON_MISSING_LOCAL_REQUEST) 
throw new RequestHandlerException(requestMissingErrorMessage);
+            if (throwRequestHandlerExceptionOnMissingLocalRequest) throw new 
RequestHandlerException(requestMissingErrorMessage);
             else throw new RequestHandlerExceptionAllowExternalRequests();
          }
 
@@ -245,7 +247,7 @@ public class RequestHandler {
                     String newUrl = RequestHandler.makeUrl(request, response, 
urlBuf.toString());
                     if (newUrl.toUpperCase().startsWith("HTTPS")) {
                         // if we are supposed to be secure, redirect secure.
-                        callRedirect(newUrl, response, request);
+                        callRedirect(newUrl, response, request, 
statusCodeString);
                         return;
                     }
                 }
@@ -260,7 +262,7 @@ public class RequestHandler {
                 }
                 String newUrl = RequestHandler.makeUrl(request, response, 
urlBuf.toString(), true, false, false);
                 if (newUrl.toUpperCase().startsWith("HTTP")) {
-                    callRedirect(newUrl, response, request);
+                    callRedirect(newUrl, response, request, statusCodeString);
                     return;
                 }
             }
@@ -507,7 +509,8 @@ public class RequestHandler {
                 if (UtilValidate.isNotEmpty(queryString)) {
                     redirectTarget += "?" + queryString;
                 }
-                callRedirect(makeLink(request, response, redirectTarget), 
response, request);
+                
+                callRedirect(makeLink(request, response, redirectTarget), 
response, request, statusCodeString);
 
                 // the old/uglier way: doRequest(request, response, 
previousRequest, userLogin, delegator);
 
@@ -569,20 +572,25 @@ public class RequestHandler {
                 }
             }
 
+            String responseStatusCode  = nextRequestResponse.statusCode;
+            if(UtilValidate.isNotEmpty(responseStatusCode))
+                statusCodeString = responseStatusCode;            
+            
+            
             if ("url".equals(nextRequestResponse.type)) {
                 if (Debug.verboseOn()) 
Debug.logVerbose("[RequestHandler.doRequest]: Response is a URL redirect." + " 
sessionId=" + UtilHttp.getSessionId(request), module);
-                callRedirect(nextRequestResponse.value, response, request);
+                callRedirect(nextRequestResponse.value, response, request, 
statusCodeString);
             } else if ("cross-redirect".equals(nextRequestResponse.type)) {
                 // check for a cross-application redirect
                 if (Debug.verboseOn()) 
Debug.logVerbose("[RequestHandler.doRequest]: Response is a Cross-Application 
redirect." + " sessionId=" + UtilHttp.getSessionId(request), module);
                 String url = nextRequestResponse.value.startsWith("/") ? 
nextRequestResponse.value : "/" + nextRequestResponse.value;
-                callRedirect(url + this.makeQueryString(request, 
nextRequestResponse), response, request);
+                callRedirect(url + this.makeQueryString(request, 
nextRequestResponse), response, request, statusCodeString);
             } else if ("request-redirect".equals(nextRequestResponse.type)) {
                 if (Debug.verboseOn()) 
Debug.logVerbose("[RequestHandler.doRequest]: Response is a Request redirect." 
+ " sessionId=" + UtilHttp.getSessionId(request), module);
-                callRedirect(makeLinkWithQueryString(request, response, "/" + 
nextRequestResponse.value, nextRequestResponse), response, request);
+                callRedirect(makeLinkWithQueryString(request, response, "/" + 
nextRequestResponse.value, nextRequestResponse), response, request, 
statusCodeString);
             } else if 
("request-redirect-noparam".equals(nextRequestResponse.type)) {
                 if (Debug.verboseOn()) 
Debug.logVerbose("[RequestHandler.doRequest]: Response is a Request redirect 
with no parameters." + " sessionId=" + UtilHttp.getSessionId(request), module);
-                callRedirect(makeLink(request, response, 
nextRequestResponse.value), response, request);
+                callRedirect(makeLink(request, response, 
nextRequestResponse.value), response, request, statusCodeString);
             } else if ("view".equals(nextRequestResponse.type)) {
                 if (Debug.verboseOn()) 
Debug.logVerbose("[RequestHandler.doRequest]: Response is a view." + " 
sessionId=" + UtilHttp.getSessionId(request), module);
 
@@ -681,6 +689,13 @@ public class RequestHandler {
         return "/error/error.jsp";
     }
 
+    /** Returns the default status-code for this request. */
+    public String getStatusCode(HttpServletRequest request) {
+        String statusCode = getControllerConfig().getStatusCode();
+        if (UtilValidate.isNotEmpty(statusCode)) return statusCode;
+        return null;
+    }
+
     /** Returns the ServletContext Object. */
     public ServletContext getServletContext() {
         return context;
@@ -728,11 +743,17 @@ public class RequestHandler {
         return nextPage;
     }
 
-    private void callRedirect(String url, HttpServletResponse resp, 
HttpServletRequest req) throws RequestHandlerException {
+    private void callRedirect(String url, HttpServletResponse resp, 
HttpServletRequest req, String statusCodeString) throws RequestHandlerException 
{
         if (Debug.infoOn()) Debug.logInfo("Sending redirect to: [" + url + "], 
sessionId=" + UtilHttp.getSessionId(req), module);
         // set the attributes in the session so we can access it.
         Enumeration<String> attributeNameEnum = 
UtilGenerics.cast(req.getAttributeNames());
         Map<String, Object> reqAttrMap = FastMap.newInstance();
+        Integer statusCode;
+        try {
+            statusCode = Integer.valueOf(statusCodeString);
+        } catch (NumberFormatException e) {
+            statusCode = 303;
+        } 
         while (attributeNameEnum.hasMoreElements()) {
             String name = attributeNameEnum.nextElement();
             Object obj = req.getAttribute(name);
@@ -749,10 +770,10 @@ public class RequestHandler {
         }
 
         // send the redirect
-        try {
-            resp.sendRedirect(url);
-        } catch (IOException ioe) {
-            throw new RequestHandlerException(ioe.getMessage(), ioe);
+        try {            
+            resp.setStatus(statusCode);
+            resp.setHeader("Location", url);
+            resp.setHeader("Connection", "close");
         } catch (IllegalStateException ise) {
             throw new RequestHandlerException(ise.getMessage(), ise);
         }


Reply via email to