簡體   English   中英

如何使用映射到根上下文的其余 API 提供來自 CXF/JAX-RS 的靜態內容?

[英]How can I serve static content from CXF / JAX-RS with my rest API mapped to root context?

我有一個使用 CXF 的 REST API 來實現 JAX-RS,其中 REST 端點直接位於根上下文中。

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

我的端點是:
本地主機:8080/myservice/resource1
本地主機:8080/myservice/resource2

但我想提供這樣的靜態內容:
本地主機: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.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>

希望這對其他人有幫助。

您可以通過將靜態內容添加到 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 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;
    }
}

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 傳輸,“重定向請求和提供靜態內容”部分

添加我的 2 美分,因為我受到了這個問題和答案的啟發。

我希望在 JAVA 中進行配置,並發現我必須使用不同的正則表達式。

我會把代碼放在這里,但先解釋一下:

我的應用程序使用 spring-boot + cxf。 CXF 映射到根“/”並且 CXF 無法為靜態資源提供服務,因此我添加了重定向 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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM