Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * $Id: JSONInterceptor.java 1129873 2011-05-31 19:36:53Z jafl $
   *
   * 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.json;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 
 
Populates an action from a JSON string
 
 public class JSONInterceptor extends AbstractInterceptor {
     private static final long serialVersionUID = 4950170304212158803L;
     private static final Logger LOG = LoggerFactory.getLogger(JSONInterceptor.class);
     private boolean enableSMD = false;
     private boolean enableGZIP = false;
     private boolean wrapWithComments;
     private boolean prefix;
     private String defaultEncoding = "ISO-8859-1";
     private boolean ignoreHierarchy = true;
     private String root;
     private List<PatternexcludeProperties;
     private List<PatternincludeProperties;
     private boolean ignoreSMDMethodInterfaces = true;
     private JSONPopulator populator = new JSONPopulator();
     private JSONCleaner dataCleaner = null;
     private boolean debug = false;
     private boolean noCache = false;
     private boolean excludeNullProperties;
     private String callbackParameter;
     private String contentType;
 
     @SuppressWarnings("unchecked")
     public String intercept(ActionInvocation invocationthrows Exception {
         HttpServletRequest request = ServletActionContext.getRequest();
         HttpServletResponse response = ServletActionContext.getResponse();
         String contentType = request.getHeader("content-type");
         if (contentType != null) {
             int iSemicolonIdx;
             if ((iSemicolonIdx = contentType.indexOf(";")) != -1)
                 contentType = contentType.substring(0, iSemicolonIdx);
         }
 
         Object rootObject = null;
         if (this. != null) {
             ValueStack stack = invocation.getStack();
             rootObject = stack.findValue(this.);
 
             if (rootObject == null) {
                 throw new RuntimeException("Invalid root expression: '" + this. + "'.");
             }
         }
 
         if ((contentType != null) && contentType.equalsIgnoreCase("application/json")) {
            // load JSON object
            Object obj = JSONUtil.deserialize(request.getReader());
            if (obj instanceof Map) {
                Map json = (Mapobj;
                // clean up the values
                if ( != null)
                    .clean(""json);
                if (rootObject == null// model overrides action
                    rootObject = invocation.getStack().peek();
                // populate fields
                .populateObject(rootObjectjson);
            } else {
                .error("Unable to deserialize JSON object from request");
                throw new JSONException("Unable to deserialize JSON object from request");
            }
        } else if ((contentType != null) && contentType.equalsIgnoreCase("application/json-rpc")) {
            Object result;
            if (this.) {
                // load JSON object
                Object obj = JSONUtil.deserialize(request.getReader());
                if (obj instanceof Map) {
                    Map smd = (Mapobj;
                    if (rootObject == null// model makes no sense when using RPC
                        rootObject = invocation.getAction();
                    // invoke method
                    try {
                        result = this.invoke(rootObjectsmd);
                    } catch (Exception e) {
                        RPCResponse rpcResponse = new RPCResponse();
                        rpcResponse.setId(smd.get("id").toString());
                        rpcResponse.setError(new RPCError(e.getDebug()));
                        result = rpcResponse;
                    }
                } else {
                    String message = "SMD request was not in the right format. See http://json-rpc.org";
                    RPCResponse rpcResponse = new RPCResponse();
                    rpcResponse.setError(new RPCError(message.));
                    result = rpcResponse;
                }
            } else {
                String message = "Request with content type of 'application/json-rpc' was received but SMD is "
                        + "not enabled for this interceptor. Set 'enableSMD' to true to enable it";
                RPCResponse rpcResponse = new RPCResponse();
                rpcResponse.setError(new RPCError(message.));
                result = rpcResponse;
            }
            String json = JSONUtil.serialize(resultgetIncludeProperties(),
                    );
            json = addCallbackIfApplicable(requestjson);
            boolean writeGzip =  && JSONUtil.isGzipInRequest(request);
            JSONUtil.writeJSONToResponse(new SerializationParams(responsethis.,
                    this.jsontruewriteGzip, -1, -1, "application/json"));
            return .;
        } else {
            if (.isDebugEnabled()) {
                .debug("Content type must be 'application/json' or 'application/json-rpc'. " +
                          "Ignoring request with content type " + contentType);
            }
        }
        return invocation.invoke();
    }
    @SuppressWarnings("unchecked")
    public RPCResponse invoke(Object objectMap datathrows IllegalArgumentException,
        RPCResponse response = new RPCResponse();
        // validate id
        Object id = data.get("id");
        if (id == null) {
            String message = "'id' is required for JSON RPC";
            response.setError(new RPCError(message.));
            return response;
        }
        // could be a numeric value
        response.setId(id.toString());
        // the map is going to have: 'params', 'method' and 'id' (for the
        // client to identify the response)
        Class clazz = object.getClass();
        // parameters
        List parameters = (Listdata.get("params");
        int parameterCount = parameters != null ? parameters.size() : 0;
        // method
        String methodName = (Stringdata.get("method");
        if (methodName == null) {
            String message = "'method' is required for JSON RPC";
            response.setError(new RPCError(message.));
            return response;
        }
        Method method = this.getMethod(clazzmethodNameparameterCount);
        if (method == null) {
            String message = "Method " + methodName + " could not be found in action class.";
            response.setError(new RPCError(message.));
            return response;
        }
        // parameters
        if (parameterCount > 0) {
            Class[] parameterTypes = method.getParameterTypes();
            Type[] genericTypes = method.getGenericParameterTypes();
            List invocationParameters = new ArrayList();
            // validate size
            if (parameterTypes.length != parameterCount) {
                // size mismatch
                String message = "Parameter count in request, " + parameterCount
                        + " do not match expected parameter count for " + methodName + ", "
                        + parameterTypes.length;
                response.setError(new RPCError(message.));
                return response;
            }
            // convert parameters
            for (int i = 0; i < parameters.size(); i++) {
                Object parameter = parameters.get(i);
                Class paramType = parameterTypes[i];
                Type genericType = genericTypes[i];
                // clean up the values
                if ( != null)
                    parameter = .clean("[" + i + "]"parameter);
                Object converted = .convert(paramTypegenericTypeparametermethod);
                invocationParameters.add(converted);
            }
            response.setResult(method.invoke(objectinvocationParameters.toArray()));
        } else {
            response.setResult(method.invoke(objectnew Object[0]));
        }
        return response;
    }
    @SuppressWarnings("unchecked")
    private Method getMethod(Class clazzString nameint parameterCount) {
        Method[] smdMethods = JSONUtil.listSMDMethods(clazz);
        for (Method method : smdMethods) {
            if (checkSMDMethodSignature(methodnameparameterCount)) {
                return method;
            }
        }
        return null;
    }

    
Look for a method in clazz carrying the SMDMethod annotation with matching name and parametersCount

Returns:
true if matches name and parameterCount
    private boolean checkSMDMethodSignature(Method methodString nameint parameterCount) {
        SMDMethod smdMethodAnntotation = method.getAnnotation(SMDMethod.class);
        if (smdMethodAnntotation != null) {
            String alias = smdMethodAnntotation.name();
            boolean paramsMatch = method.getParameterTypes().length == parameterCount;
            if (((alias.length() == 0) && method.getName().equals(name) && paramsMatch)
                    || (alias.equals(name) && paramsMatch)) {
                return true;
            }
        }
        return false;
    }
    protected String addCallbackIfApplicable(HttpServletRequest requestString json) {
        if (( != null) && (.length() > 0)) {
            String callbackName = request.getParameter();
            if ((callbackName != null) && (callbackName.length() > 0))
                json = callbackName + "(" + json + ")";
        }
        return json;
    }
    public boolean isEnableSMD() {
        return this.;
    }
    public void setEnableSMD(boolean enableSMD) {
        this. = enableSMD;
    }

    
Ignore annotations on methods in interfaces You may need to set to this true if your action is a proxy/enhanced as annotations are not inherited
    public void setIgnoreSMDMethodInterfaces(boolean ignoreSMDMethodInterfaces) {
        this. = ignoreSMDMethodInterfaces;
    }

    
Wrap generated JSON with comments. Only used if SMD is enabled.

Parameters:
wrapWithComments
    public void setWrapWithComments(boolean wrapWithComments) {
        this. = wrapWithComments;
    }
    public void setDefaultEncoding(String val) {
        this. = val;
    }

    
Ignore properties defined on base classes of the root object.

Parameters:
ignoreHierarchy
    public void setIgnoreHierarchy(boolean ignoreHierarchy) {
        this. = ignoreHierarchy;
    }

    
Sets the root object to be deserialized, defaults to the Action

Parameters:
root OGNL expression of root object to be serialized
    public void setRoot(String root) {
        this. = root;
    }

    
Sets the JSONPopulator to be used

Parameters:
populator JSONPopulator
    public void setJSONPopulator(JSONPopulator populator) {
        this. = populator;
    }

    
Sets the JSONCleaner to be used

Parameters:
dataCleaner JSONCleaner
    public void setJSONCleaner(JSONCleaner dataCleaner) {
        this. = dataCleaner;
    }

    

Returns:
true if debugging is turned on
    public boolean getDebug() {
        Boolean devModeOverride = FilterDispatcher.getDevModeOverride();
        return devModeOverride != null ? devModeOverride.booleanValue() : this.;
    }

    
Turns debugging on or off

Parameters:
debug true or false
    public void setDebug(boolean debug) {
        this. = debug;
    }
    public void setDevMode(
        String mode)
    {
        setDebug("true".equalsIgnoreCase(mode));
    }

    
Sets a comma-delimited list of regular expressions to match properties that should be excluded from the JSON output.

Parameters:
commaDelim A comma-delimited list of regular expressions
    public void setExcludeProperties(String commaDelim) {
        Set<StringexcludePatterns = JSONUtil.asSet(commaDelim);
        if (excludePatterns != null) {
            this. = new ArrayList<Pattern>(excludePatterns.size());
            for (String pattern : excludePatterns) {
                this..add(Pattern.compile(pattern));
            }
        }
    }

    
Sets a comma-delimited list of wildcard expressions to match properties that should be excluded from the JSON output.

Parameters:
commaDelim A comma-delimited list of wildcard expressions
    public void setExcludeWildcards(String commaDelim) {
        Set<StringexcludePatterns = JSONUtil.asSet(commaDelim);
        if (excludePatterns != null) {
            this. = new ArrayList<Pattern>(excludePatterns.size());
            for (String pattern : excludePatterns) {
                this..add(WildcardUtil.compileWildcardPattern(pattern));
            }
        }
    }

    
Sets a comma-delimited list of regular expressions to match properties that should be included from the JSON output.

Parameters:
commaDelim A comma-delimited list of regular expressions
    public void setIncludeProperties(String commaDelim) {
         = JSONUtil.processIncludePatterns(JSONUtil.asSet(commaDelim), .);
    }

    
Sets a comma-delimited list of wildcard expressions to match properties that should be included from the JSON output. The standard boilerplate (id, error, debug) are automatically included, as appropriate, so you only need to provide patterns for the contents of "result".

Parameters:
commaDelim A comma-delimited list of wildcard expressions
    public void setIncludeWildcards(String commaDelim) {
         = JSONUtil.processIncludePatterns(JSONUtil.asSet(commaDelim), .);
        if ( != null) {
            .add(Pattern.compile("id"));
            .add(Pattern.compile("result"));
            .add(Pattern.compile("error"));
            .add(WildcardUtil.compileWildcardPattern("error.code"));
        }
    }

    
Returns the appropriate set of includes, based on debug setting. Derived classes can override if there are additional, custom debug-only parameters.
    protected List getIncludeProperties() {
        if ( != null && getDebug()) {
            List<Patternlist = new ArrayList<Pattern>();
            list.add(Pattern.compile("debug"));
            list.add(WildcardUtil.compileWildcardPattern("error.*"));
            return list;
        } else {
            return ;
        }
    }
    public boolean isEnableGZIP() {
        return ;
    }

    
Setting this property to "true" will compress the output.

Parameters:
enableGZIP Enable compressed output
    public void setEnableGZIP(boolean enableGZIP) {
        this. = enableGZIP;
    }
    public boolean isNoCache() {
        return ;
    }

    
Add headers to response to prevent the browser from caching the response

Parameters:
noCache
    public void setNoCache(boolean noCache) {
        this. = noCache;
    }
    public boolean isExcludeNullProperties() {
        return ;
    }

    
Do not serialize properties with a null value

Parameters:
excludeNullProperties
    public void setExcludeNullProperties(boolean excludeNullProperties) {
        this. = excludeNullProperties;
    }
    public void setCallbackParameter(String callbackParameter) {
        this. = callbackParameter;
    }
    public String getCallbackParameter() {
        return ;
    }

    
Add "{} && " to generated JSON

Parameters:
prefix
    public void setPrefix(boolean prefix) {
        this. = prefix;
    }
    public void setContentType(String contentType) {
        this. = contentType;
    }
New to GrepCode? Check out our FAQ X