在root中映射servlet

时间:2013-04-07 09:49:33

标签: java gwt servlets guice resteasy

这两个“共存”的正确配置是什么:

http://localhost:8888/index.html

http://localhost:8888/{some_path_value}

第一项将返回一个html页面,并且还将包含将访问/public/images/bg.png等资源的href。

现在第二个项目是一个Restful api,它映射在相同的根上下文和提供页面的那个(index.html,png,jpg,css,js等)

所以我现在面临的问题是,当我像这样配置Rest API servlet映射时:

<servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>
        org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
    </servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

Rest API可以工作,但它有效地删除了对index.html,css,js等静态资源的访问,以呈现“主页”。

但是,如果我将映射更改为类似/api/*的内容,则现在可以访问GWT应用程序,但Rest API的PATH不再是根目录。

那么我的应用程序可能出现什么问题?我真的需要让两者共存在同一条道路上。我最初的想法是做一些过滤器,但可能有更容易和更合适的解决方案。

更新

我的应用程序模块

public class MyModule implements Module
{
   public void configure(final Binder binder)
   {
      binder.bind(MyResource.class);
   }
}

的web.xml

<context-param>
    <param-name>resteasy.guice.modules</param-name>
    <param-value>org.jboss.errai.ui.demo.server.MyModule</param-value>
</context-param>

<listener>
    <listener-class>
        org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener
    </listener-class>
</listener>

<context-param>  
    <param-name>resteasy.servlet.mapping.prefix</param-name>  
    <param-value>/api</param-value>  
</context-param>

<servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>
        org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
    </servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

1 个答案:

答案 0 :(得分:6)

所以你的问题是你将所有的根请求映射到其余的servlet,因为它不起作用。

  1. 如果有方法可以了解其余servlet的某些模式,则可以在web.xml中配置所有这些特定模式。但是url-pattern只使用了一种非常简单的语法,whatever/**.extension是允许的,而且你的rest-servlet似乎与此要求不匹配。

  2. 另一种选择可能是使用像GuiceServletContextListener这样的高级servlet调度程序(由guice提供)并配置WebModule富有的正则表达式。修改您的web.xml以添加WebModule并配置该模块以处理URL并使用适当的servlet进行调度(从web.xml中删除这些servlet)

  3.   <context-param>
        <param-name>resteasy.guice.modules&lt;/param-name>
        <param-value>org.jboss.errai.ui.demo.server.MyModule</param-value>
        <param-value>org.jboss.errai.ui.demo.server.MyWebModule</param-value>
      </context-param>
    
      public class MyWebModule extends ServletModule {
        @Override
        protected void configureServlets() {
          // Note: all servlets and filters must be singletons
          bind(FactoryServlet.class).in(Singleton.class);
          // Pass to the HttpServletDispatcher everything but urls ending with static extensions
          serveRegex(".+(?<!\\.(html|css|png|jpg))")
               .with(HttpServletDispatcher.class);
        }
      }    
    
    1. 最后一个选项是编写自己的过滤器,检测路径是否与静态文件匹配并发送。
    2.   private FilterConfig config;
        public void init(FilterConfig filterConfig) throws ServletException {
          config = filterConfig;
        }
      
        public void doFilter(ServletRequest servletRequest,
            ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
      
          HttpServletRequest req = (HttpServletRequest) servletRequest;
          HttpServletResponse resp = (HttpServletResponse) servletResponse;
      
          File file = new File(config.getServletContext().getRealPath(req.getServletPath()));
          if (file.canRead()) {
            // NOTE: you have to set the most appropriate type per file
            resp.setContentType("text/html");
      
            // This depends on apache commons-io
            IOUtils.copy(new FileInputStream(file), resp.getOutputStream());
          } else {
            filterChain.doFilter(req, resp);
          }
        }