在相同的根上下文中托管静态内容和JAX-RS服务 [英] Hosting Static Content and JAX-RS Services Under the Same Root Context

查看:90
本文介绍了在相同的根上下文中托管静态内容和JAX-RS服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们将多个打包为WAR的Java Web应用程序打包在EAR中。我们的RESTful服务是使用JAX-RS和特定于版本的WAR构建的。

We have multiple Java web apps packaged as WARs all packaged in an EAR. Our RESTful services are built using JAX-RS and in version specific WARs.

我们希望为每个特定于版本的WAR添加静态内容,但是对于静态内容和RESTful服务使用(根据WAR)的根上下文API调用,以便所有以下网址都可以使用:

We'd like to add static content for each of these version specific WARs, but use the root context (of the WAR) for both the static content and the RESTful service API calls, such that all of the following URLs will work:

{hostname}/v1/swagger.yaml  <-- Static Content describing the v1 API
{hostname}/v1/orders/{uid}  <-- JAX-RS RESTful API (v1)

{hostname}/v2/swagger.yaml  <-- Static Content describing the v2 API
{hostname}/v2/orders/{uid}  <-- JAX-RS RESTful API (v2)

以下部署结构是我们目前拥有的,适用于JAX-RS服务,但不适用于静态内容。换句话说,这些URL有效:

The following deployment structure is what we currently have, which works for the JAX-RS services, but not the static content. In other words these URLs work:

{hostname}/v1/orders/{uid}  <-- JAX-RS RESTful API (v1)
{hostname}/v2/orders/{uid}  <-- JAX-RS RESTful API (v2)

但问题是这些URL无法访问:

But the problem is that these URLS are inaccessible:

{hostname}/v1/swagger.yaml  <-- Static Content describing the v1 API
{hostname}/v2/swagger.yaml  <-- Static Content describing the v2 API

问题:我们如何让这些静态URL生效?

Question: How do we get these static URLs to work?

这是爆炸的EAR:

example.ear

    META-INF
        application.xml

    v1.war
        swagger.yaml
        WEB-INF
            web.xml
            classes
                ApplicationV1.class
                OrdersResourceV1.class

    v2.war
        swagger.yaml
        WEB-INF
            web.xml
            classes
                ApplicationV2.class
                OrdersResourceV2.class

这是EARs 应用程序。 xml

<?xml version="1.0"?>
<application xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="6">
  <application-name>...</application-name>
  <module>
    <web>
      <web-uri>v1.war</web-uri>
      <context-root>/v1</context-root>
    </web>
  </module>
  <module>
    <web>
      <web-uri>v2.war</web-uri>
      <context-root>/v2</context-root>
    </web>
  </module>
  <module>
    <web>
      <web-uri>another.war</web-uri>
      <context-root>/</context-root>
    </web>
  </module>
</application>

这是v1& v2 web.xml

Here's the v1 & v2 web.xml:

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
</web-app>

这是 ApplicationV1.java (JAX- RS)实现,注意URL映射:

Here's the ApplicationV1.java (JAX-RS) implementation, notice the URL mapping:

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;


@ApplicationPath("/")
public class ApplicationV1 extends Application {

  private Set<Object> singletons = new HashSet<Object>();

  public ApplicationV1() {
    singletons.add(new OrdersResourceV1());
  }

  @Override
  public Set<Object> getSingletons() {
    return singletons;
  }

}

这是 OrdersResourceV1.java (JAX-RS)实现,请注意URL映射:

Here's the OrdersResourceV1.java (JAX-RS) implementation, notice the URL mapping:

import javax.enterprise.context.RequestScoped;
import javax.ws.rs.*;

@RequestScoped
@Path("/orders")
public class OrdersResourceV1 {

  @GET
  @Path("/{uid}")
  @Produces("application/json;charset=UTF-8")
  public Response getOrder(@PathParam("uid") String orderUid) {
    <ommited for brevity>
  }

}

我知道如果我们改变了 ApplicationV * .java 映射到 @ApplicationPath(/ services),静态内容将是可评估的,但URL将如下,但我们的目标是不包括任何无关的路径元素。

I do know that if we changed ApplicationV*.java's mapping to @ApplicationPath("/services"), that the static content will be assessable, but the URLs will then be as follows, but it's our goal to not include any extraneous path elements like this.

{hostname}/v1/swagger.yaml  <-- Static Content describing the v1 API
{hostname}/v1/services/orders/{uid} <-- JAX-RS RESTful API (v1)

{hostname}/v2/swagger.yaml  <-- Static Content describing the v2 API
{hostname}/v2/services/orders/{uid} <-- JAX-RS RESTful API (v2)

所以我的问题是,我们如何在根目录下获取JAX-RS和静态内容WAR的上下文( / v1 / v2 )?是否有不同的方式来映射URL?或者,如果JAX-RS没有URL的处理程序,是否有允许静态回退的配置选项?

So my question is, how do we get the JAX-RS and static content under the root context for the WAR (/v1 and /v2)? Is there a different way to map the URLs? Or is there a configuration option that allows for a static fallback if JAX-RS doesn't have a handler for the URL?

我希望这可以解决JavaEE泛型时尚,但如果没有,我们在Java8上使用Wildfly 8.1。

I'm hoping that this can be solved a JavaEE generic fashion, but if not, we're using Wildfly 8.1 on Java8.

推荐答案

所以我找到了一个解决方案(测试过的) ) 这样可行。如 Resteasy文档中所述 - RESTEasy as servlet过滤器

So I found a solution (tested) that works. As stated in the Resteasy Documentation - RESTEasy as a servlet Filter:


将Resteasy作为Servlet运行的缺点是你不能拥有像.html和.html这样的静态资源。 jpeg文件与JAX-RS服务在同一路径中。 Resteasy允许您作为过滤器运行。如果在请求的URL下找不到JAX-RS资源,Resteasy将委托回基本servlet容器来解析URL。

The downside of running Resteasy as a Servlet is that you cannot have static resources like .html and .jpeg files in the same path as your JAX-RS services. Resteasy allows you to run as a Filter instead. If a JAX-RS resource is not found under the URL requested, Resteasy will delegate back to the base servlet container to resolve URLs.

web.xml示例

<web-app>
    <filter>
        <filter-name>Resteasy</filter-name>
        <filter-class>
            org.jboss.resteasy.plugins.server.servlet.FilterDispatcher
        </filter-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.restfully.shop.services.ShoppingApplication</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>Resteasy</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

这篇关于在相同的根上下文中托管静态内容和JAX-RS服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆