All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.juneau.rest.RestServlet Maven / Gradle / Ivy

There is a newer version: 9.0.1
Show newest version
// ***************************************************************************************************************************
// * 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;

import static java.util.logging.Level.*;
import static javax.servlet.http.HttpServletResponse.*;
import static org.apache.juneau.internal.StringUtils.*;

import java.io.*;
import java.text.*;
import java.util.logging.*;

import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.juneau.*;
import org.apache.juneau.utils.*;

/**
 * Servlet implementation of a REST resource.
 *
 * 

* Refer to REST Servlet API for information about using this * class. */ public abstract class RestServlet extends HttpServlet { private static final long serialVersionUID = 1L; private RestConfig config; private RestContext context; private volatile boolean isInitialized = false; private Exception initException; @Override /* Servlet */ public final synchronized void init(ServletConfig servletConfig) throws ServletException { try { RestConfig rsc = new RestConfig(servletConfig, this.getClass(), null); 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; log(SEVERE, e, "Servlet init error on class ''{0}''", getClass().getName()); } catch (ServletException e) { initException = e; log(SEVERE, e, "Servlet init error on class ''{0}''", getClass().getName()); throw e; } catch (Exception e) { initException = e; log(SEVERE, e, "Servlet init error on class ''{0}''", getClass().getName()); throw new ServletException(e); } catch (Throwable e) { initException = new Exception(e); log(SEVERE, e, "Servlet init error on class ''{0}''", getClass().getName()); throw new ServletException(e); } finally { isInitialized = true; } } /* * Bypasses the init(ServletConfig) method and just calls the super.init(ServletConfig) method directly. * Used when subclasses of RestServlet are attached as child resources. */ 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; } /** * Convenience method if you want to perform initialization on your resource after all configuration settings * have been made. * *

* This allows you to get access to the {@link RestContext} object during initialization. * *

* The default implementation does nothing. * * @param context The servlet context containing all the set-in-stone configurations for this resource. * @throws Exception Any exception can be thrown to signal an initialization failure. */ public synchronized void init(RestContext context) throws Exception {} 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; } //-------------------------------------------------------------------------------- // Other methods //-------------------------------------------------------------------------------- /** * The main service method. * *

* Subclasses can optionally override this method if they want to tailor the behavior of requests. */ @Override /* Servlet */ public void service(HttpServletRequest r1, HttpServletResponse r2) throws ServletException, IOException { try { if (initException != null) { if (initException instanceof RestException) throw (RestException)initException; throw new RestException(SC_INTERNAL_SERVER_ERROR, initException); } if (context == null) throw new RestException(SC_INTERNAL_SERVER_ERROR, "Servlet {0} not initialized. init(RestConfig) was not called. This can occur if you've overridden this method but didn't call super.init(RestConfig).", getClass().getName()); if (! isInitialized) throw new RestException(SC_INTERNAL_SERVER_ERROR, "Servlet {0} has not been initialized", getClass().getName()); context.getCallHandler().service(r1, r2); } catch (RestException e) { r2.sendError(SC_INTERNAL_SERVER_ERROR, e.getLocalizedMessage()); } catch (Throwable e) { r2.sendError(SC_INTERNAL_SERVER_ERROR, e.getLocalizedMessage()); } } /** * Returns the read-only context object that contains all the configuration information about this resource. * *

* This object is null during the call to {@link #init(ServletConfig)} but is populated by the time * {@link #init()} is called. * *

* Resource classes that don't extend from {@link RestServlet} can add the following method to their class to get * access to this context object: *

* public void init(RestServletContext context) throws Exception; *

* * @return The context information on this servlet. */ protected RestContext getContext() { return context; } /** * Convenience method for calling getContext().getLogger().log(level, msg, args); * * @param level The log level. * @param msg The message to log. * @param args Optional {@link MessageFormat}-style arguments. */ protected void log(Level level, String msg, Object...args) { if (context != null) context.getLogger().log(level, msg, args); } /** * Convenience method for calling getContext().getLogger().log(level, cause, msg, args); * * @param level The log level. * @param cause The cause. * @param msg The message to log. * @param args Optional {@link MessageFormat}-style arguments. */ protected void log(Level level, Throwable cause, String msg, Object...args) { if (context != null) context.getLogger().log(level, cause, msg, args); else { // If context failed to initialize, log to the console. System.err.println(format(msg, args)); if (cause != null) cause.printStackTrace(); } } @Override /* GenericServlet */ public RestConfig getServletConfig() { return config; } @Override /* GenericServlet */ public void destroy() { if (context != null) context.destroy(); super.destroy(); } /** * Convenience method for calling getContext().getMessages(); * * @return The resource bundle for this resource. Never null. * @see RestContext#getProperties() */ public MessageBundle getMessages() { return context.getMessages(); } /** * Convenience method for calling getContext().getProperties(); * * @return The resource properties as an {@link ObjectMap}. * @see RestContext#getProperties() */ public ObjectMap getProperties() { return getContext().getProperties(); } /** * Convenience method for calling getContext().getBeanContext(); * * @return The bean context used for parsing path variables and header values. * @see RestContext#getBeanContext() */ public BeanContext getBeanContext() { return getContext().getBeanContext(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy