2012-08-18 3 views
0

Я разрабатываю службу JAX-RS Rest с использованием Apache CXF. После его развертывания на сервере Tomcat 7, если я наберу URL http://localhost:8080/Rest/rest?_wadl, он покажет мне WADL. но если я ввожу URL-адрес http://localhost:8080/Rest/rest/retrieve, он дает мне ошибку 404.Служба Jax-Rs не вызывается

В указанных URL-адресов: Rest это имя моего проекта /rest является URL-шаблон для моей CXFServlet, который указан в web.xml / это адрес jaxrs:server который указан в beans.xml retrieve это путь сервиса, который указан в моем интерфейсе с аннотацией @Path.

(Мои извинения: я не могу предоставить XML-документы, упомянутые выше.)

+0

Не могли бы вы показать свой Java-класс? Мне кажется, что/retrieve не соответствует. Вы указали тип метода? – Jeroen

ответ

0

Я думаю, что это ошибка 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.

Надеюсь, это может вам помочь.

Смежные вопросы