ルートコンテキストでJAX-RXアプリケーションを開始したいので、URLは
http://example.com/restfullPath
ではなく
http://example.com/rest/restfullPath
アプリケーションの注釈をこれから切り替えました
@ApplicationPath("/rest/*")
これに
@ApplicationPath("/*")
しかし、それは/index.htmlなどのファイルの提供を引き継ぐようです
ルートアプリケーションコンテキストでJAX-RSを実行する方法はありますか?
これはJBOSSフォーラムの 前に尋ねた だったようですが、解決策は実際的ではありません
それはおそらくサーブレット仕様の制限としてのバグではありません。 JAX-RS _@ApplicationPath
_の処理方法の詳細は実装固有であり、すべての実装について話すことはできませんが、サーブレットのURLパターンとして単純に使用するのが一般的なアプローチだと思います。 JerseyのServletContainerInitializer実装を一例として見ると、 addServletWithApplication()
method がサーブレットの作成とリクエストを処理するためのマッピングを担当していることがわかります。実際、_@ApplicationPath
_からのパスをJersey ServletContainerのマップされたパスとして使用します。
残念ながら、太古の昔から、サーブレット仕様では、サーブレットをURLパスにマッピングする方法はごく一部しか許可されていません。 仕様のセクション12.2 で提供されるサーブレット3.0の現在のオプションは、残念ながらPDFとしてのみ使用できるため、セクションでリンクできません-
/.../*
_ここで、最初の_/...
_は0個以上のパス要素です*.<ext>
_ここで_<ext>
_は、一致する拡張機能です/
_、単一のスラッシュ。コンテキスト内の「デフォルト」サーブレットを示し、他とは一致しないものを処理します。仕様の同じセクションには、マッチングルールを適用する順序に関する特定のルールもありますが、短いバージョンはこれです。リソースクラスをコンテキストルートでリクエストに応答させるには、_/
_のいずれかを使用する必要がありますまたは_/*
_をパスとして使用します。 _/
_を使用する場合、コンテナーのデフォルトサーブレットを置き換えます。これは通常、静的リソースの処理を担当します。 _/*
_を使用すると、貪欲になりすぎて、常にすべてに一致するはずであり、デフォルトのサーブレットが呼び出されることはありません。
したがって、サーブレットURLパターンの制限によって決定されるボックス内にいることを受け入れると、オプションはかなり制限されます。ここに私が考えることができるものがあります:
1)@ApplicationPath("/")
を使用し、静的リソースを名前または拡張子でコンテナのデフォルトサーブレットに明示的にマッピングします(TomcatおよびJettyでは「default」という名前ですが、他のものについては不明です)。 web.xmlでは、次のようになります。
_<!-- All html files at any path -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<!-- Specifically index.html at the root -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/index.html</url-pattern>
</servlet-mapping>
_
または ServletContextInitializer のように、
_public class MyInitializer implements ServletContainerInitializer {
public void onStartup(Set<Class<?>> c, ServletContext ctx) {
ctx.getServletRegistration("default").addMapping("*.html");
ctx.getServletRegistration("default").addMapping("/index.html");
}
}
_
マッチングルールの記述方法により、拡張パターンはデフォルトのサーブレットよりも優先されます。静的なファイル拡張子ごとにマッピングを追加する必要があるのは、それらと「拡張」で発生する可能性のある重複がない限りです。あなたのAPI。これは、リンクしたフォーラムの投稿で言及されている望ましくないオプションにかなり近いものです。完全を期すため、およびServletContextInitializerの部分を追加するために、このオプションについて言及しました。
2)APIを_/rest/*
_にマップしたままにし、フィルターを使用してAPIのリクエストを識別し、それらをそのパスに転送します。このようにして、サーブレットのURLパターンボックスから抜け出し、URLを任意の方法で照合できます。たとえば、すべてのREST呼び出しが「/ foo」で始まるパスまたは「/ bar」であるパスへの呼び出しであり、他のすべてのリクエストが静的リソースに送られるべきであるとすると、次のようになります。
_import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import Java.io.IOException;
import Java.util.regex.Pattern;
@WebFilter(urlPatterns = "/*")
public class PathingFilter implements Filter {
Pattern[] restPatterns = new Pattern[] {
Pattern.compile("/foo.*"),
Pattern.compile("/bar"),
};
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
String path = ((HttpServletRequest) request).getServletPath();
for (Pattern pattern : restPatterns) {
if (pattern.matcher(path).matches()) {
String newPath = "/rest/" + path;
request.getRequestDispatcher(newPath)
.forward(request, response);
return;
}
}
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void destroy() {}
}
_
上記では、基本的にリクエストを次のように変換します。
_http://example.org/foo -> http://example.org/rest/foo
http://example.org/foox -> http://example.org/rest/foox
http://example.org/foo/anything -> http://example.org/rest/foo/anything
http://example.org/bar -> http://example.org/rest/bar
http://example.org/bart -> http://example.org/bart
http://example.org/index.html -> http://example.org/index.html
_
3)前のオプションは基本的にURLの書き換えであり、既存の実装を使用していることを認識してください Apacheのmod_rewrite 、 Tuckey書き換えフィルター 、または ocpsoft Rewrite =。
内部のJerseyクラスを含む別のソリューションを見つけました。おそらく、それはまだJAX-RS仕様の一部ではないと思います。 (に基づいて: http://www.lucubratory.eu/simple-jerseyrest-and-jsp-based-web-application/ )
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">
<display-name>jersey-rest-jsp-frame-1</display-name>
<filter>
<filter-name>jersey</filter-name>
<filter-class>
com.Sun.jersey.spi.container.servlet.ServletContainer
</filter-class>
<init-param>
<param-name>
com.Sun.jersey.config.property.JSPTemplatesBasePath
</param-name>
<param-value>/WEB-INF/jsp</param-value>
</init-param>
<init-param>
<param-name>
com.Sun.jersey.config.property.WebPageContentRegex
</param-name>
<param-value>
(/(image|js|css)/?.*)|(/.*\.jsp)|(/WEB-INF/.*\.jsp)|
(/WEB-INF/.*\.jspf)|(/.*\.html)|(/favicon\.ico)|
(/robots\.txt)
</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jersey</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
WEB-INF/jsp/index.jsp
<%@ page contentType="text/html; charset=UTF-8" language="Java" %>
<html>
<body>
<h2>Hello ${it.foo}!</h2>
</body>
</html>
IndexModel.Java
package example;
import com.Sun.jersey.api.view.Viewable;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import Java.net.URI;
import Java.util.HashMap;
@Path("/")
@Produces(MediaType.TEXT_HTML)
public class IndexModel {
@GET
public Response root() {
return Response.seeOther(URI.create("/index")).build();
}
@GET
@Path("index")
public Viewable index(@Context HttpServletRequest request) {
HashMap<String, String> model = new HashMap<String, String>();
model.put("foo","World");
return new Viewable("/index.jsp", model);
}
}
これは機能しているようですが、それがJAX-RS仕様の一部であるか、実装の一部になるかどうかです。
サーブレットコンテナのDefaultServlet
を探し、web.xml
に手動でサーブレットマッピングを追加して、*。html、*。jspなどのページファイルを処理できます。
例えば。 Tomcat 5.5の場合、ここで説明します: http://Tomcat.Apache.org/Tomcat-5.5-doc/default-servlet.html 。
別の投稿から@damo for Jersey 2.0を引用
「あるいは、何らかのリダイレクトで何かを引き出すことができるかもしれません。たとえば Pre-matching Filter を使用すると、このようなことをしたことはありませんが、ドキュメントでは「リクエストURIも変更できます。」
代わりに@ApplicationPath("/")
を使用してください(アスタリスクなし)。それはあなたの場合に役立ちます。
サンプルREST Webサービス:
1. JaxRsActivator.Java
package com.stackoverflow;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/")
public class JaxRsActivator extends Application {
}
2. HelloService.Java
package com.stackoverflow;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/hello")
public class HelloService {
@GET
@Produces(MediaType.TEXT_HTML)
public String hello() {
return "hello";
}
}
私はEclipseを使用してこの動的Webプロジェクトをhelloservice.war
という名前のWARファイルにエクスポートし、ローカルマシンで実行されているWildFlyにデプロイしました。そのURL:http://localhost:8080/helloservice/hello
。
このリンクにアクセスすると、次のように返されました。
hello