Я думаю, что это ошибка CXF которые получают неверную базовый URL для веб-служб RESTful.
Класс "org.apache.cxf.transport.servlet.ServletController" вызывает метод "getBaseURL" класса "org.apache.cxf.transport.servlet.BaseUrlHelper".
Он получает базовый URL-адрес с URL-адреса запроса и игнорирует часть параметров. Это правильно для веб-сервисов SOAP, поскольку URL-адрес веб-служб SOAP такой же: http://host:port/basepath?para=a
. К сожалению, для спокойных веб-сервисов 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-адрес в первый раз! :(
Решение: переопределить метод "getBaseURL(HttpServletRequest request)" из "org.apache.cxf.transport.servlet.ServletController", пусть это вернуть правильный базовый URL
Например, шаг1:. Расширяет 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: вместо CXFNonSpr ingServlet, вы используете производный класс RestfulServletController. Не забывайте, что вы должны настроить «basePath» как/Rest/rest.
Надеюсь, это может вам помочь.
Не могли бы вы показать свой Java-класс? Мне кажется, что/retrieve не соответствует. Вы указали тип метода? – Jeroen