これは、安静な Web サービスのベース URL が正しくない CXF のバグだと思います。
クラス「org.apache.cxf.transport.servlet.ServletController」は、クラス「org.apache.cxf.transport.servlet.BaseUrlHelper」のメソッド「getBaseURL」を呼び出します。
リクエスト URL からベース URL を取得し、パラメーター部分は無視します。SOAP Web サービスの URL はhttp://host:port/basepath?para=a
. 残念ながら、安静な Web サービスの場合、URL は のようになりますhttp://host:port/basepath/method/parameter
。正しいベース URL は であるはずですがhttp://host:port/basepath
、実際には BaseUrlHelper によって が返されますhttp://host:port/basepath/method/parameter
。「?」の前に URL を指定するだけです。にアクセスしたときの結果が正しいのはそのためです。http://localhost:8080/Rest/rest?_wadl
この場合、正しいベース URL が得られますhttp://localhost:8080/Rest
。
http://localhost:8080/Rest/rest?_wadl
最初にアクセスしてから にアクセスすれhttp://localhost:8080/Rest/rest/retrieve
ば正解です。そのため、CXF は初回のみベース URL を EndpointInfo のアドレスとして設定します。つまり、最初は正しいベース URL にアクセスする必要があります。:(
解決策は次のとおりです。「org.apache.cxf.transport.servlet.ServletController」のメソッド「getBaseURL(HttpServletRequest request)」をオーバーライドし、正しいベース URL を返すようにします。
たとえば、step1: ServletController を拡張します。
public class RestfulServletController extends ServletController {
private final String basePath;
public RestfulServletController(DestinationRegistry destinationRegistry, ServletConfig config,
HttpServlet serviceListGenerator, String basePath) {
super(destinationRegistry, config, serviceListGenerator);
this.basePath = basePath;
}
@Override
protected String getBaseURL(HttpServletRequest request) {
// Fixed the bug of BaseUrlHelper.getBaseURL(request) for restful service.
String reqPrefix = request.getRequestURL().toString();
int idx = reqPrefix.indexOf(basePath);
return reqPrefix.substring(0, idx + basePath.length());
}
}
step2: CXFNonSpringServlet を拡張し、サブクラスで RestfulServletController を使用する
public class RestfulCXFServlet extends CXFNonSpringServlet {
... ...
private ServletController createServletController(ServletConfig servletConfig) {
HttpServlet serviceListGeneratorServlet = new ServiceListGeneratorServlet(destinationRegistry, bus);
ServletController newController = new RestfulServletController(destinationRegistry, servletConfig,
serviceListGeneratorServlet, basePath);
return newController;
}
}
step3: CXFNonSpringServlet の代わりに、派生クラス RestfulServletController を使用します。「basePath」を /Rest/rest として構成する必要があることを忘れないでください。
これがあなたを助けることを願っています。