ResteasyServletInitializer.java 代码

package org.jboss.resteasy.plugins.servlet;

import org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher;
import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;
import org.jboss.resteasy.spi.NotImplementedYetException;

import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.HandlesTypes;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
import javax.ws.rs.ext.Provider;
import java.util.HashSet;
import java.util.Set;

/**
 * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
 * @version $Revision: 1 $
 */
@HandlesTypes({Application.class, Path.class, Provider.class})
public class ResteasyServletInitializer implements ServletContainerInitializer
{
   @Override
   public void onStartup(Set<Class<?>> classes, ServletContext servletContext) throws ServletException
   {
      if (classes == null || classes.size() == 0) return;
      for (ServletRegistration reg : servletContext.getServletRegistrations().values())
      {
         if (reg.getInitParameter("javax.ws.rs.Application") != null)
         {
            return; // there's already a servlet mapping, do nothing
         }
      }

      Set<Class<?>> appClasses = new HashSet<Class<?>>();
      Set<Class<?>> providers = new HashSet<Class<?>>();
      Set<Class<?>> resources = new HashSet<Class<?>>();

      for (Class<?> clazz : classes)
      {
         if (clazz.isAnnotationPresent(Path.class))
         {
            resources.add(clazz);
         }
         else if (clazz.isAnnotationPresent(Provider.class))
         {
            providers.add(clazz);
         }
         else
         {
            appClasses.add(clazz);
         }
      }
      if (appClasses.size() == 0 && resources.size() == 0) return;

      if (appClasses.size() == 0)
      {
         // todo make sure we can do this on all servlet containers
         //handleNoApplicationClass(providers, resources, servletContext);
         return;
      }

      for (Class<?> app : appClasses)
      {
         register(app, providers, resources, servletContext);
      }
   }

   protected void handleNoApplicationClass(Set<Class<?>> providers, Set<Class<?>> resources, ServletContext servletContext)
   {
      ServletRegistration defaultApp = null;
      for (ServletRegistration reg : servletContext.getServletRegistrations().values())
      {
         if (reg.getName().equals(Application.class.getName()))
         {
            defaultApp = reg;
         }
      }
      if (defaultApp == null) return;
      throw new NotImplementedYetException("Default Application class not implemented yet");

   }


   protected void register(Class<?> applicationClass, Set<Class<?>> providers, Set<Class<?>> resources, ServletContext servletContext)
   {
      ApplicationPath path = applicationClass.getAnnotation(ApplicationPath.class);
      if (path == null)
      {
         // todo we don't support this yet, i'm not sure if partial deployments are supported in all servlet containers
         return;
      }
      ServletRegistration.Dynamic reg = servletContext.addServlet(applicationClass.getName(), HttpServlet30Dispatcher.class);
      reg.setLoadOnStartup(1);
      reg.setAsyncSupported(true);
      reg.setInitParameter("javax.ws.rs.Application", applicationClass.getName());

      if (path != null)
      {
         String mapping = path.value();
         if (!mapping.startsWith("/")) mapping = "/" + mapping;
         String prefix = mapping;
         if (!prefix.equals("/") && prefix.endsWith("/")) prefix = prefix.substring(0, prefix.length() - 1);
         if (mapping.endsWith("/")) mapping += "*";
         else mapping += "/*";
         // resteasy.servlet.mapping.prefix
         reg.setInitParameter("resteasy.servlet.mapping.prefix", prefix);
         reg.addMapping(mapping);
      }

      if (resources.size() > 0)
      {
         StringBuilder builder = new StringBuilder();
         boolean first = true;
         for (Class resource : resources)
         {
            if (first)
            {
               first = false;
            }
            else
            {
               builder.append(",");
            }
            builder.append(resource.getName());
         }
         reg.setInitParameter(ResteasyContextParameters.RESTEASY_SCANNED_RESOURCES, builder.toString());
      }
      if (providers.size() > 0)
      {
         StringBuilder builder = new StringBuilder();
         boolean first = true;
         for (Class provider : providers)
         {
            if (first)
            {
               first = false;
            }
            else
            {
               builder.append(",");
            }
            builder.append(provider.getName());
         }
         reg.setInitParameter(ResteasyContextParameters.RESTEASY_SCANNED_PROVIDERS, builder.toString());
      }

   }
}

 
ServletContainerInitializer 也是 Servlet 3.0 新增的一个接口,容器在启动时使用 JAR 服务 API(JAR Service API) 来发现 ServletContainerInitializer 的实现类,并且容器将 WEB-INF/lib 目录下 JAR 包中的类都交给该类的 onStartup() 方法处理,我们通常需要在该实现类上使用 @HandlesTypes 注解来指定希望被处理的类,过滤掉不希望给 onStartup() 处理的类。
目前 tomcat7 支持 servlet 3.0, tomcat6 不支持。这一点需要注意。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值