Repository: incubator-juneau Updated Branches: refs/heads/master 50baa1e20 -> 6d63a4183
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/6d63a418/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java index fc9ff2e..0c691d0 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java @@ -48,12 +48,11 @@ public abstract class RestServlet extends HttpServlet { public final synchronized void init(ServletConfig servletConfig) throws ServletException { try { RestConfig rsc = new RestConfig(servletConfig, this.getClass(), null); - init(rsc); - if (! isInitialized) { - // Subclass may not have called super.init(RestServletConfig), so initialize here. - createContext(rsc); - super.init(servletConfig); - } + rsc.init(this); + RestContext context = createContext(rsc); + super.init(servletConfig); + context.postInit(); + context.postInitChildFirst(); } catch (RestException e) { // Thrown RestExceptions are simply caught and re-thrown on subsequent calls to service(). initException = e; @@ -75,33 +74,21 @@ public abstract class RestServlet extends HttpServlet { } } - /** - * Resource initialization method. - * - * <p> - * Identical to {@link Servlet#init(ServletConfig)} except the config object provides access to the external config - * file, configuration properties, and variable resolver defined for this resource. - * - * <p> - * Classes can also use {@link HttpServlet#init()} and {@link RestServlet#getServletConfig()} as well to perform - * initialization. - * - * <p> - * Note that if you override this method, you must first call <code><jk>super</jk>.init(servletConfig)</code>! - * - * <p> - * Resource classes that don't extend from {@link RestServlet} can add this method to their class to get access to - * the config object. - * - * @param config The servlet configuration. - * @throws Exception Any exception can be thrown to signal an initialization failure. + /* + * Bypasses the init(ServletConfig) method and just calls the super.init(ServletConfig) method directly. + * Used when subclasses of RestServlet are attached as child resources. */ - public synchronized void init(RestConfig config) throws Exception { - if (isInitialized) - return; - createContext(config); - super.init(config); - init(context); + void innerInit(ServletConfig servletConfig) throws ServletException { + super.init(servletConfig); + } + + /* + * Sets the context object for this servlet. + * Used when subclasses of RestServlet are attached as child resources. + */ + void setContext(RestContext context) { + this.config = context.config; + this.context = context; } /** @@ -120,12 +107,13 @@ public abstract class RestServlet extends HttpServlet { public synchronized void init(RestContext context) throws Exception {} - private synchronized void createContext(RestConfig config) throws Exception { - if (isInitialized) - return; - this.config = config; - this.context = new RestContext(this, this.getServletContext(), config); - this.isInitialized = true; + private synchronized RestContext createContext(RestConfig config) throws Exception { + if (! isInitialized) { + this.config = config; + this.context = new RestContext(this, this.getServletContext(), config); + this.isInitialized = true; + } + return context; } @@ -142,7 +130,6 @@ public abstract class RestServlet extends HttpServlet { @Override /* Servlet */ public void service(HttpServletRequest r1, HttpServletResponse r2) throws ServletException, IOException { try { - if (initException != null) { if (initException instanceof RestException) throw (RestException)initException; @@ -166,7 +153,7 @@ public abstract class RestServlet extends HttpServlet { * Returns the read-only context object that contains all the configuration information about this resource. * * <p> - * This object is <jk>null</jk> during the call to {@link #init(RestConfig)} but is populated by the time + * This object is <jk>null</jk> during the call to {@link #init(ServletConfig)} but is populated by the time * {@link #init()} is called. * * <p> @@ -183,59 +170,6 @@ public abstract class RestServlet extends HttpServlet { } /** - * Callback method for listening for successful completion of requests. - * - * <p> - * Subclasses can override this method for gathering performance statistics. - * - * <p> - * The default implementation does nothing. - * - * <p> - * Resources that don't extend from {@link RestServlet} can implement an equivalent method by overriding the - * {@link RestCallHandler#onSuccess(RestRequest, RestResponse, long)} method. - * - * @param req The HTTP request. - * @param res The HTTP response. - * @param time The time in milliseconds it took to process the request. - */ - protected void onSuccess(RestRequest req, RestResponse res, long time) {} - - /** - * Callback method that gets invoked right before the REST Java method is invoked. - * - * <p> - * Subclasses can override this method to override request headers or set request-duration properties before the - * Java method is invoked. - * - * <p> - * Resources that don't extend from {@link RestServlet} can implement an equivalent method by overriding the - * {@link RestCallHandler#onPreCall(RestRequest)} method. - * - * @param req The HTTP servlet request object. - * @throws RestException If any error occurs. - */ - protected void onPreCall(RestRequest req) throws RestException {} - - /** - * Callback method that gets invoked right after the REST Java method is invoked, but before the serializer is - * invoked. - * - * <p> - * Subclasses can override this method to override request and response headers, or set/override properties used by - * the serializer. - * - * <p> - * Resources that don't extend from {@link RestServlet} can implement an equivalent method by overriding the - * {@link RestCallHandler#onPostCall(RestRequest,RestResponse)} method. - * - * @param req The HTTP servlet request object. - * @param res The HTTP servlet response object. - * @throws RestException If any error occurs. - */ - protected void onPostCall(RestRequest req, RestResponse res) throws RestException {} - - /** * Convenience method for calling <code>getContext().getLogger().log(level, msg, args);</code> * * @param level The log level. http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/6d63a418/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HookEvent.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HookEvent.java b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HookEvent.java new file mode 100644 index 0000000..74684e8 --- /dev/null +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/HookEvent.java @@ -0,0 +1,419 @@ +// *************************************************************************************************************************** +// * 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.juneau.rest.annotation; + +import java.io.*; +import java.util.*; +import java.util.logging.*; + +import javax.servlet.*; +import javax.servlet.http.*; + +import org.apache.juneau.*; +import org.apache.juneau.dto.swagger.*; +import org.apache.juneau.http.*; +import org.apache.juneau.ini.*; +import org.apache.juneau.internal.*; +import org.apache.juneau.rest.*; +import org.apache.juneau.utils.*; + +/** + * Identifies servlet and REST call lifecycle events which cause {@link RestHook @RestHook}-annotated Java methods + * to be called. + */ +public enum HookEvent { + + /** + * Identifies a method that should be called immediately after the <code>HttpServlet.service(HttpServletRequest, HttpServletResponse)</code> + * method is called. + * + * <p> + * Note that you only have access to the raw request and response objects at this point. + * + * <p> + * The list of valid parameter types are as follows: + * <ul> + * <li>Servlet request/response objects: + * <ul> + * <li>{@link HttpServletRequest} + * <li>{@link HttpServletResponse} + * </ul> + * </ul> + * + * <h6 class='figure'>Example:</h6> + * <p class='bcode'> + * <ja>@RestResource</ja>(...) + * <jk>public class</jk> MyResource <jk>extends</jk> RestServletDefault { + * + * <jc>// Add a request attribute to all incoming requests.</jc> + * <ja>@RestHook</ja>(<jsf>START_CALL</jsf>) + * <jk>public void</jk> onStartCall(HttpServletRequest req) { + * req.setAttribute(<js>"foobar"</js>, <jk>new</jk> FooBar()); + * } + * } + * </p> + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li>If the method returns any value, it is ignored. + * <li>Multiple START_CALL methods can be defined on a class. + * <br>START_CALL methods on parent classes are invoked before START_CALL methods on child classes. + * <br>The order of START_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types. + * <li>The method can throw any exception. + * <br>{@link RestException RestExceptions} can be thrown to cause a particular HTTP error status code. + * <br>All other exceptions cause an HTTP 500 error status code. + * <li>Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>. + * <br>The method is still considered part of the parent class for ordering purposes even though it's + * overridden by the child class. + * </ul> + */ + START_CALL, + + /** + * Identifies a method that gets called immediately before the <ja>@RestMethod</ja> annotated method gets called. + * + * <p> + * At this point, the {@link RestRequest} object has been fully initialized, and all {@link RestGuard} and + * {@link RestMatcher} objects have been called. + * + * <p> + * The list of valid parameter types are as follows: + * <ul> + * <li>Servlet request/response objects: + * <ul> + * <li>{@link HttpServletRequest} + * <li>{@link HttpServletResponse} + * </ul> + * <li>Extended request/response objects: + * <ul> + * <li>{@link RestRequest} + * <li>{@link RestResponse} + * </ul> + * <li>Header objects: + * <ul> + * <li>{@link Accept} + * <li>{@link AcceptCharset} + * <li>{@link AcceptEncoding} + * <li>{@link AcceptLanguage} + * <li>{@link Authorization} + * <li>{@link CacheControl} + * <li>{@link Connection} + * <li>{@link ContentLength} + * <li>{@link ContentType} + * <li>{@link org.apache.juneau.http.Date} + * <li>{@link Expect} + * <li>{@link From} + * <li>{@link Host} + * <li>{@link IfMatch} + * <li>{@link IfModifiedSince} + * <li>{@link IfNoneMatch} + * <li>{@link IfRange} + * <li>{@link IfUnmodifiedSince} + * <li>{@link MaxForwards} + * <li>{@link Pragma} + * <li>{@link ProxyAuthorization} + * <li>{@link Range} + * <li>{@link Referer} + * <li>{@link TE} + * <li>{@link UserAgent} + * <li>{@link Upgrade} + * <li>{@link Via} + * <li>{@link Warning} + * <li>{@link TimeZone} + * </ul> + * <li>Other objects: + * <ul> + * <li>{@link ResourceBundle} + * <li>{@link MessageBundle} + * <li>{@link InputStream} + * <li>{@link ServletInputStream} + * <li>{@link Reader} + * <li>{@link OutputStream} + * <li>{@link ServletOutputStream} + * <li>{@link Writer} + * <li>{@link RequestHeaders} + * <li>{@link RequestQuery} + * <li>{@link RequestFormData} + * <li>{@link HttpMethod} + * <li>{@link Logger} + * <li>{@link JuneauLogger} + * <li>{@link RestContext} + * <li>{@link org.apache.juneau.parser.Parser} + * <li>{@link Locale} + * <li>{@link Swagger} + * <li>{@link RequestPathMatch} + * <li>{@link RequestBody} + * <li>{@link ConfigFile} + * <li>{@link UriContext} + * <li>{@link UriResolver} + * </ul> + * </ul> + * + * <h6 class='figure'>Example:</h6> + * <p class='bcode'> + * <ja>@RestResource</ja>(...) + * <jk>public class</jk> MyResource <jk>extends</jk> RestServletDefault { + * + * <jc>// Log the incoming request.</jc> + * <ja>@RestHook</ja>(<jsf>PRE_CALL</jsf>) + * <jk>public void</jk> onPreCall(Accept accept, Logger logger) { + * logger.fine(<js>"Accept {0} header found."</js>, accept); + * } + * } + * </p> + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li>If the method returns any value, it is ignored. + * <li>Multiple PRE_CALL methods can be defined on a class. + * <br>PRE_CALL methods on parent classes are invoked before PRE_CALL methods on child classes. + * <br>The order of PRE_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types. + * <li>The method can throw any exception. + * <br>{@link RestException RestExceptions} can be thrown to cause a particular HTTP error status code. + * <br>All other exceptions cause an HTTP 500 error status code. + * <li>Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>. + * <br>The method is still considered part of the parent class for ordering purposes even though it's + * overridden by the child class. + * <li>It's advisable not to mess around with the HTTP body itself since you may end up consuming the body + * before the actual REST method has a chance to use it. + * </ul> + */ + PRE_CALL, + + /** + * Identifies a method that gets called immediately after the <ja>@RestMethod</ja> annotated method gets called. + * + * <p> + * At this point, the output object returned by the method call has been set on the response, but + * {@link RestConverter RestConverters} have not yet been executed and the response has not yet been written. + * + * <p> + * The list of valid parameter types are the same as {@link #PRE_CALL}. + * + * <h6 class='figure'>Example:</h6> + * <p class='bcode'> + * <ja>@RestResource</ja>(...) + * <jk>public class</jk> MyResource <jk>extends</jk> RestServletDefault { + * + * <jc>// Log the result of the request.</jc> + * <ja>@RestHook</ja>(<jsf>POST_CALL</jsf>) + * <jk>public void</jk> onPostCall(RestResponse res, Logger logger) { + * logger.fine(<js>Output {0} was set on the response."</js>, res.getOutput()); + * } + * } + * </p> + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li>If the method returns any value, it is ignored. + * <li>Multiple POST_CALL methods can be defined on a class. + * <br>POST_CALL methods on parent classes are invoked before POST_CALL methods on child classes. + * <br>The order of POST_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types. + * <li>The method can throw any exception, although at this point it is too late to set an HTTP error status code. + * <li>Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>. + * <br>The method is still considered part of the parent class for ordering purposes even though it's + * overridden by the child class. + * </ul> + */ + POST_CALL, + + /** + * Identifies a method that gets called right before we exit the servlet service method. + * + * <p> + * At this point, the output has been written and flushed. + * + * <p> + * The list of valid parameter types are as follows: + * <ul> + * <li>Servlet request/response objects: + * <ul> + * <li>{@link HttpServletRequest} + * <li>{@link HttpServletResponse} + * </ul> + * </ul> + * + * <p> + * The following attributes are set on the {@link HttpServletRequest} object that can be useful for logging purposes: + * <ul> + * <li><js>"Exception"</js> - Any exceptions thrown during the request. + * <li><js>"ExecTime"</js> - Execution time of the request. + * </ul> + * + * <h6 class='figure'>Example:</h6> + * <p class='bcode'> + * <ja>@RestResource</ja>(...) + * <jk>public class</jk> MyResource <jk>extends</jk> RestServletDefault { + * + * <jc>// Log the time it took to execute the request.</jc> + * <ja>@RestHook</ja>(<jsf>END_CALL</jsf>) + * <jk>public void</jk> onEndCall(RestRequest req, Logger logger) { + * Exception e = (Exception)req.getAttribute(<js>"Exception"</js>); + * Long execTime = (Long)req.getAttribute(<js>"ExecTime"</js>); + * <jk>if</jk> (e != <jk>null</jk>) + * logger.warn(e, <js>"Request failed in {0}ms."</js>, execTime); + * <jk>else</jk> + * logger.fine(<js>"Request finished in {0}ms."</js>, execTime); + * } + * } + * </p> + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li>If the method returns any value, it is ignored. + * <li>Multiple END_CALL methods can be defined on a class. + * <br>END_CALL methods on parent classes are invoked before END_CALL methods on child classes. + * <br>The order of END_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types. + * <li>The method can throw any exception, although at this point it is too late to set an HTTP error status code. + * <li>Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>. + * <br>The method is still considered part of the parent class for ordering purposes even though it's + * overridden by the child class. + * </ul> + */ + END_CALL, + + /** + * Identifies a method that gets called during servlet initialization. + * + * <p> + * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestConfig} + * object has been created and initialized with the annotations defined on the class, but before the + * {@link RestContext} object has been created. + * + * <p> + * The only valid parameter type for this method is {@link RestConfig} which can be used to configure the servlet. + * + * <p> + * An example of this is the <code>PetStoreResource</code> class that uses an init method to perform initialization + * of an internal data structure. + * + * <h6 class='figure'>Example:</h6> + * <p class='bcode'> + * <ja>@RestResource</ja>(...) + * <jk>public class</jk> PetStoreResource <jk>extends</jk> ResourceJena { + * + * <jc>// Our database.</jc> + * <jk>private</jk> Map<Integer,Pet> <jf>petDB</jf>; + * + * <ja>@RestHook</ja>(<jsf>INIT</jsf>) + * <jk>public void</jk> onInit(RestConfig config) <jk>throws</jk> Exception { + * <jc>// Load our database from a local JSON file.</jc> + * <jf>petDB</jf> = JsonParser.<jsf>DEFAULT</jsf>.parse(getClass().getResourceAsStream(<js>"PetStore.json"</js>), LinkedHashMap.<jk>class</jk>, Integer.<jk>class</jk>, Pet.<jk>class</jk>); + * } + * } + * </p> + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li>If the method returns any value, it is ignored. + * <li>Multiple INIT methods can be defined on a class. + * <br>INIT methods on parent classes are invoked before INIT methods on child classes. + * <br>The order of INIT method invocations within a class is alphabetical, then by parameter count, then by parameter types. + * <li>The method can throw any exception causing initialization of the servlet to fail. + * <li>Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>. + * <br>The method is still considered part of the parent class for ordering purposes even though it's + * overridden by the child class. + * </ul> + */ + INIT, + + /** + * Identifies a method that gets called immediately after servlet initialization. + * + * <p> + * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContext} + * object has been created. + * + * <p> + * The only valid parameter type for this method is {@link RestContext} which can be used to retrieve information + * about the servlet. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li>If the method returns any value, it is ignored. + * <li>Multiple POST_INIT methods can be defined on a class. + * <br>POST_INIT methods on parent classes are invoked before POST_INIT methods on child classes. + * <br>The order of POST_INIT method invocations within a class is alphabetical, then by parameter count, then by parameter types. + * <li>The method can throw any exception causing initialization of the servlet to fail. + * <li>Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>. + * <br>The method is still considered part of the parent class for ordering purposes even though it's + * overridden by the child class. + * </ul> + */ + POST_INIT, + + /** + * Identical to {@link #POST_INIT} except the order of execution is child-resources first. + * + * <p> + * Use this annotation if you need to perform any kind of initialization on child resources before the parent resource. + * + * <p> + * This method is called from within the {@link Servlet#init(ServletConfig)} method after the {@link RestContext} + * object has been created and after the {@link #POST_INIT} methods have been called. + * + * <p> + * The only valid parameter type for this method is {@link RestContext} which can be used to retrieve information + * about the servlet. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li>If the method returns any value, it is ignored. + * <li>Multiple POST_INIT_CHILD_FIRST methods can be defined on a class. + * <br>POST_INIT_CHILD_FIRST methods on parent classes are invoked before POST_INIT_CHILD_FIRST methods on child classes. + * <br>The order of POST_INIT_CHILD_FIRST method invocations within a class is alphabetical, then by parameter count, then by parameter types. + * <li>The method can throw any exception causing initialization of the servlet to fail. + * </ul> + */ + POST_INIT_CHILD_FIRST, + + /** + * Identifies a method that gets called during servlet destroy. + * + * <p> + * This method is called from within the {@link Servlet#destroy()}. + * + * <p> + * The only valid parameter type for this method is {@link RestContext}, although typically no arguments will + * be specified. + * + * <h6 class='figure'>Example:</h6> + * <p class='bcode'> + * <ja>@RestResource</ja>(...) + * <jk>public class</jk> PetStoreResource <jk>extends</jk> ResourceJena { + * + * <jc>// Our database.</jc> + * <jk>private</jk> Map<Integer,Pet> <jf>petDB</jf>; + * + * <ja>@RestHook</ja>(<jsf>DESTROY</jsf>) + * <jk>public void</jk> onDestroy() { + * <jf>petDB</jf> = <jk>null</jk>; + * } + * } + * </p> + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li>If the method returns any value, it is ignored. + * <li>Multiple DESTROY methods can be defined on a class. + * <br>DESTROY methods on child classes are invoked before DESTROY methods on parent classes. + * <br>The order of DESTROY method invocations within a class is alphabetical, then by parameter count, then by parameter types. + * <li>In general, destroy methods should not throw any exceptions, although if any are thrown, the stack trace will be + * printed to <code>System.err</code>. + * <li>Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>. + * <br>The method is still considered part of the parent class for ordering purposes even though it's + * overridden by the child class. + * </ul> + */ + DESTROY +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/6d63a418/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestHook.java ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestHook.java b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestHook.java new file mode 100644 index 0000000..828df43 --- /dev/null +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestHook.java @@ -0,0 +1,86 @@ +// *************************************************************************************************************************** +// * 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.juneau.rest.annotation; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.lang.annotation.*; + +/** + * Identifies Java methods on a resource/servlet class that get invoked during particular lifecycle events of + * the servlet or REST call. + * + * <p> + * For example, if you want to add an initialization method to your resource: + * <p class='bcode'> + * <ja>@RestResource</ja>(...) + * <jk>public class</jk> MyResource { + * + * <jc>// Our database.</jc> + * <jk>private</jk> Map<Integer,Object> <jf>myDatabase</jf>; + * + * <ja>@RestHook</ja>(<jsf>INIT</jsf>) + * <jk>public void</jk> initMyDatabase(RestConfig config) <jk>throws</jk> Exception { + * <jf>myDatabase</jf> = <jk>new</jk> LinkedHashMap<>(); + * } + * } + * </p> + * + * <p> + * Or if you want to intercept REST calls: + * <p class='bcode'> + * <ja>@RestResource</ja>(...) + * <jk>public class</jk> MyResource { + * + * <jc>// Add a request attribute to all incoming requests.</jc> + * <ja>@RestHook</ja>(<jsf>PRE_CALL</jsf>) + * <jk>public void</jk> onPreCall(RestRequest req) { + * req.setAttribute(<js>"foo"</js>, <js>"bar"</js>); + * } + * } + * </p> + * + * <p> + * The hook events can be broken down into two categories: + * <ul class='spaced-list'> + * <li>Resource lifecycle events: + * <ul> + * <li>{@link HookEvent#INIT INIT} - Right before initialization. + * <li>{@link HookEvent#POST_INIT POST_INIT} - Right after initialization. + * <li>{@link HookEvent#POST_INIT_CHILD_FIRST POST_INIT_CHILD_FIRST} - Right after initialization, but run child methods first. + * <li>{@link HookEvent#DESTROY DESTROY} - Right before servlet destroy. + * </ul> + * <li>REST call lifecycle events: + * <ul> + * <li>{@link HookEvent#START_CALL START_CALL} - At the beginning of a REST call. + * <li>{@link HookEvent#PRE_CALL PRE_CALL} - Right before the <ja>@RestMethod</ja> method is invoked. + * <li>{@link HookEvent#POST_CALL POST_CALL} - Right after the <ja>@RestMethod</ja> method is invoked. + * <li>{@link HookEvent#END_CALL END_CALL} - At the end of the REST call after the response has been flushed. + * </ul> + * </ul> + * + * <p> + * See the {@link HookEvent} class for information about individual event types. + */ +@Documented +@Target(METHOD) +@Retention(RUNTIME) +@Inherited +public @interface RestHook { + + /** + * The lifecycle event. + */ + HookEvent value(); +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/6d63a418/juneau-rest/src/main/java/org/apache/juneau/rest/package.html ---------------------------------------------------------------------- diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/package.html b/juneau-rest/src/main/java/org/apache/juneau/rest/package.html index 8097a17..e3f1427 100644 --- a/juneau-rest/src/main/java/org/apache/juneau/rest/package.html +++ b/juneau-rest/src/main/java/org/apache/juneau/rest/package.html @@ -2485,28 +2485,9 @@ <h3 class='topic' onclick='toggle(this)'>4.16 - Listener Methods</h3> <div class='topic'> <p> - Various convenience listener methods are provided on the {@link org.apache.juneau.rest.RestCallHandler} - class that subclasses can use to intercept requests: + Various convenience listener methods can be implemented by using the {@link org.apache.juneau.rest.annotation.RestHook @RestHook} + annotation on methods in your resource class. </p> - <ul class='doctree'> - <li class='jac'> - {@link org.apache.juneau.rest.RestCallHandler} - <ul> - <li class='jm'> - {@link org.apache.juneau.rest.RestCallHandler#onPreCall(RestRequest) onPreCall(RestRequest)} - <br>Callback method that gets invoked right before the REST Java method is invoked. - <li class='jm'> - {@link org.apache.juneau.rest.RestCallHandler#onPostCall(RestRequest,RestResponse) onPostCall(RestRequest,RestResponse)} - <br>Callback method that gets invoked right after the REST Java method is invoked, but before the serializer is invoked. - <li class='jm'> - {@link org.apache.juneau.rest.RestCallHandler#onSuccess(RestRequest,RestResponse,long) onSuccess(RestRequest,RestResponse,long)} - <br>Callback method for listening for successful completion of requests. - <li class='jm'> - {@link org.apache.juneau.rest.RestLogger#onError(HttpServletRequest,HttpServletResponse,RestException) onError(HttpServletRequest,HttpServletResponse,RestException)} - <br>Callback method for logging errors during HTTP requests. - </ul> - </li> - </ul> </div> <!-- ======================================================================================================== -->
