001package org.kohsuke.stapler.json;
002
003import net.sf.json.JSONObject;
004import org.kohsuke.stapler.HttpResponse;
005import org.kohsuke.stapler.StaplerRequest;
006import org.kohsuke.stapler.StaplerResponse;
007import org.kohsuke.stapler.interceptor.Interceptor;
008import org.kohsuke.stapler.interceptor.InterceptorAnnotation;
009
010import javax.servlet.ServletException;
011import java.lang.annotation.Documented;
012import java.lang.annotation.Retention;
013import java.lang.annotation.Target;
014import java.lang.reflect.InvocationTargetException;
015import java.util.logging.Level;
016import java.util.logging.Logger;
017
018import static java.lang.annotation.ElementType.METHOD;
019import static java.lang.annotation.RetentionPolicy.RUNTIME;
020
021/**
022 * Used for web methods that return POJO that should be sent across as JSON.
023 *
024 * <p>
025 * See {@link JsonBody} for more comprehensive documentation.
026 *
027 * @author Kohsuke Kawaguchi
028 * @author Carlos Sanchez
029 * @see JsonBody
030 */
031@Target(METHOD)
032@Retention(RUNTIME)
033@Documented
034@InterceptorAnnotation(JsonResponse.Handler.class)
035public @interface JsonResponse {
036    public static class Handler extends Interceptor {
037        private static final Logger logger = Logger.getLogger(Handler.class.getName());
038
039        @Override
040        public Object invoke(StaplerRequest request, StaplerResponse response, Object instance, Object[] arguments)
041                throws IllegalAccessException, InvocationTargetException, ServletException {
042            try {
043                final Object r = target.invoke(request, response, instance, arguments);
044
045                JSONObject j;
046                if (r==null)
047                    j = null;
048                else
049                if (r instanceof JSONObject)
050                    j = (JSONObject)r;
051                else
052                    // will fail in case of Array/List, please keep this behavior
053                    // to prevent top-level json array that has a vulnerability in certain browser
054                    // http://blog.jeremiahgrossman.com/2006/01/advanced-web-attack-techniques-using.html
055                    j = JSONObject.fromObject(r);
056
057                return new JsonHttpResponse(j);
058            } catch (InvocationTargetException e) {
059                logger.log(Level.SEVERE, "Error processing request", e);
060                Throwable target = e.getTargetException();
061                if (target instanceof HttpResponse)
062                    return target;
063                return new JsonHttpResponse(target, 500);
064            }
065        }
066    }
067
068}