001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.rest.annotation; 014 015import static java.lang.annotation.ElementType.*; 016import static java.lang.annotation.RetentionPolicy.*; 017 018import java.lang.annotation.*; 019 020import jakarta.servlet.http.*; 021 022/** 023 * Identifies a method that gets called right before we exit the servlet service method. 024 * 025 * <p> 026 * At this point, the output has been written and flushed. 027 * 028 * <p> 029 * The list of valid parameter types are as follows: 030 * <ul> 031 * <li>Servlet request/response objects: 032 * <ul> 033 * <li>{@link HttpServletRequest} 034 * <li>{@link HttpServletResponse} 035 * </ul> 036 * </ul> 037 * 038 * <p> 039 * The following attributes are set on the {@link HttpServletRequest} object that can be useful for logging purposes: 040 * <ul> 041 * <li><js>"Exception"</js> - Any exceptions thrown during the request. 042 * <li><js>"ExecTime"</js> - Execution time of the request. 043 * </ul> 044 * 045 * <h5 class='figure'>Example:</h5> 046 * <p class='bjava'> 047 * <ja>@Rest</ja>(...) 048 * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet { 049 * 050 * <jc>// Log the time it took to execute the request.</jc> 051 * <ja>@RestEndCall 052 * <jk>public void</jk> onEndCall(HttpServletRequest <jv>req</jv>, Logger <jv>logger</jv>) { 053 * Exception <jv>exception</jv> = (Exception)<jv>req</jv>.getAttribute(<js>"Exception"</js>); 054 * Long <jv>execTime</jv> = (Long)<jv>req</jv>.getAttribute(<js>"ExecTime"</js>); 055 * <jk>if</jk> (<jv>exception</jv> != <jk>null</jk>) 056 * <jv>logger</jv>.warn(<jv>exception</jv>, <js>"Request failed in {0}ms."</js>, <jv>execTime</jv>); 057 * <jk>else</jk> 058 * <jv>logger</jv>.fine(<js>"Request finished in {0}ms."</js>, <jv>execTime</jv>); 059 * } 060 * } 061 * </p> 062 * 063 * <h5 class='section'>Notes:</h5><ul> 064 * <li class='note'> 065 * The method should return <jk>void</jk> although if it does return any value, the value will be ignored. 066 * <li class='note'> 067 * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it. 068 * <li class='note'> 069 * Static methods can be used. 070 * <li class='note'> 071 * Multiple END_CALL methods can be defined on a class. 072 * <br>END_CALL methods on parent classes are invoked before END_CALL methods on child classes. 073 * <br>The order of END_CALL method invocations within a class is alphabetical, then by parameter count, then by parameter types. 074 * <li class='note'> 075 * The method can throw any exception, although at this point it is too late to set an HTTP error status code. 076 * <li class='note'> 077 * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>. 078 * <br>The method is still considered part of the parent class for ordering purposes even though it's 079 * overridden by the child class. 080 * </ul> 081 * 082 * <h5 class='section'>See Also:</h5><ul> 083 * <li class='link'><a class="doclink" href="../../../../../index.html#jrs.LifecycleHooks">Lifecycle Hooks</a> 084 * </ul> 085 */ 086@Target({METHOD,TYPE}) 087@Retention(RUNTIME) 088@Inherited 089@Repeatable(RestEndCallAnnotation.Array.class) 090public @interface RestEndCall { 091 092 /** 093 * Dynamically apply this annotation to the specified methods. 094 * 095 * <h5 class='section'>See Also:</h5><ul> 096 * <li class='link'><a class="doclink" href="../../../../../index.html#jm.DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a> 097 * </ul> 098 * 099 * @return The annotation value. 100 */ 101 String[] on() default {}; 102}