如何在我的其余API映射到根上下文的情况下从CXF / JAX-RS提供静态内容?

时间:2015-11-04 23:14:59

标签: java rest jax-rs cxf web.xml

我有一个使用CXF的rest API来实现JAX-RS,其中REST端点直接位于根上下文中。

例如,如果我的根上下文是localhost:8080 / myservice

我的终点是:
本地主机:8080 /为MyService /资源1
本地主机:8080 /为MyService /资源2

但我想提供这样的静态内容:
本地主机:8080 /为MyService /文档/ swagger.json

在我的web.xml中,我想做这样的事情:

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

<servlet-mapping>
  <servlet-name>default</servlet-name>
  <url-pattern>/docs/*</url-pattern>
</servlet-mapping>

但这不起作用,CXFServlet接收所有请求,我找不到配置CXF / JAX-RS来提供静态内容的方法,而不包括新库和创建字节流等等。不想做。我想只映射到默认的servlet。

CXF文档并不容易理解,我尝试执行以下操作失败:

<servlet>
  <servlet-name>CXFServlet</servlet-name>
  <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  <init-param>
    <param-name>static-resources-list</param-name>
    <param-value>
      /docs/(\S)+\.html
      /docs/(\S)+\.json
    </param-value>
  </init-param>
</servlet>

有什么想法吗?

4 个答案:

答案 0 :(得分:4)

我找到了解决方案,感谢this link

下面是我的web.xml中的servlet配置,用于提供静态资源,其中CXFServlet映射到root。

<servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <init-param>
        <param-name>redirects-list</param-name>
        <param-value>
          /docs/(\S)+\.html
          /docs/(\S)+\.json
    </param-value>
    </init-param>
    <init-param>
        <param-name>redirect-attributes</param-name>
        <param-value>
          javax.servlet.include.request_uri
    </param-value>
    </init-param>
    <init-param>
        <param-name>redirect-servlet-name</param-name>
        <param-value>default</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

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

希望这有助于其他人。

答案 1 :(得分:2)

您可以通过将静态内容添加到CXF Jetty资源处理程序来提供静态内容:

<bean id="jettyHTTPServerEngine" class="org.apache.cxf.transport.http_jetty.JettyHTTPServerEngine">
    <property name="threadingParameters" ref="threadingParameters" />
    <property name="port" value="8080" />
      <property name="handlers">
          <list>
              <ref bean="contextHandler" />
          </list>
      </property>
  </bean>

    <bean name="contextHandler" class="org.eclipse.jetty.server.handler.ContextHandler">
        <property name="contextPath" value="/content"/>
        <property name="handler" ref="resourceHandler"/>
    </bean>    

    <bean id="resourceHandler" class="org.eclipse.jetty.server.handler.ResourceHandler">
        <property name="resourceBase" value="#{classpathResourceResolver.path}"/>
        <property name="directoriesListed" value="true"/>
    </bean>

<bean id="classpathResourceResolver" class="com.myapp.ClasspathResourceResolver">
    <property name="resourceLocation" value="myresources/files"/>
  </bean>

其中属性 contextPath 是网址后缀,例如您将获得localhost:8080/content的内容 请注意,Jetty ResourceHandler只接受Java路径(普通),而不接受Spring类路径。 因此,您需要从Spring到Java规范路径的自定义转换器,请参阅:

public class ClasspathResourceResolver
{
    private String resourceLocation;

    public String getPath()
    {
        if (StringUtils.isNotEmpty(resourceLocation))
        {
            try
            {
                return new ClassPathResource(resourceLocation).getFile().getCanonicalPath();
            }
            catch (Exception e)
            {
                log.warn("Unable to resolve classpath as canonical path", e);
            }
        }
        return null;
    }

    public void setResourceLocation(String resourceLocation)
    {
        this.resourceLocation = resourceLocation;
    }
}

答案 2 :(得分:0)

CXFServlet能够直接提供静态内容;将'static-resources-list'init-param与类路径中的静态资源列表用空格分隔:

        <init-param>
            <param-name>static-resources-list</param-name>
            <param-value>/static/(\w)+.css</param-value>
        </init-param>

还可以通过“ static-cache-control”设置HTTP响应Cache-Control标头:

        <init-param>
            <param-name>static-cache-control</param-name>
            <param-value>public, max-age=31536000</param-value>
        </init-param>

Apache CXF Servlet Transport,“重定向请求并提供静态内容”部分

答案 3 :(得分:0)

自从我受到这个问题和答案的启发以来,我增加了2美分。

我希望在JAVA中进行配置,并且还发现我必须使用其他正则表达式。

我将代码放在这里,但先说明:

我的应用程序正在使用spring-boot + cxf。 CXF映射到根目录“ /”,并且CXF无法服务器静态资源,因此我添加了redirect-servlet-name参数,该参数表示“嘿cxf,如果请求以.css结尾,则将记录发送到dispatcherServlet”。

为什么调度程序servlet?这是spring-boot的默认servlet,例如,它可以从特定文件夹中存储静态内容。

@Bean
public ServletRegistrationBean<CXFServlet> servletRegistrationBean() {
    ServletRegistrationBean<CXFServlet> x = new ServletRegistrationBean<>(new CXFServlet(), "/*");

    Map<String, String> params = new HashMap<>();
    params.put("redirects-list", ".*\\.css$"); // space separated list if multiple values are required
    params.put("redirect-servlet-name", "dispatcherServlet");
    x.setInitParameters(params);
    return x;
}