如何在将我的rest API映射到根上下文时,从CXF / JAX-RS提供静态内容?

3
我有一个使用CXF实现JAX-RS的REST API,其中REST端点直接在根上下文中。例如,如果我的根上下文是localhost:8080/myservice,而我的端点是: localhost:8080/myservice/resource1 localhost:8080/myservice/resource2
但我想像这样提供静态内容: localhost:8080/myservice/docs/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>

有什么想法吗?

根上下文在Web容器级别进行配置,必须是host:port/myservice,因为同一主机和端口上部署了许多其他服务。 - Nathan Hadzariga
4个回答

5
我通过这个链接找到了解决方案!
以下是我在web.xml中的servlet配置,用于使用映射到根的CXFServlet来提供静态资源。
<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>

希望这对其他人有所帮助。


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代表URL后缀,例如您可以在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;
    }
}

1

由于这个问题和答案的启发,我想加入我的两分钱。

我希望在JAVA中进行配置,并发现我必须使用不同的正则表达式。

我将在此处放置代码,但首先解释一下:

我的应用程序正在使用spring-boot + cxf。 CXF映射到根“/”,但无法提供静态资源,因此我添加了redirect-servlet-name参数,它说:“嘿cxf,如果请求以.css结尾,请将请求分派给dispatcherServlet。”

为什么要使用dispatcher 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;
}

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响应缓存控制头:

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

Apache CXF Servlet Transport,章节“重定向请求和提供静态内容”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接