JAX-WS - сопоставление исключений с неисправностями - PullRequest
27 голосов
/ 14 января 2010

Я использую JAX WS для предоставления WebService. Некоторые операции этого сервиса могут генерировать исключения. Не внутренние исключения сервера, а исключения, которые зависят от входных аргументов вызова операции.

Если я укажу, что моя операция выдает специальное исключение, например:

@WebService
@SOAPBinding(style = Style.RPC, use = Use.LITERAL)
public class MyServiceEndpointImpl implements MyServiceEndpoint {

    @WebMethod
    public void throwsException throws InvalidInputException;
}

Я получаю следующую трассировку стека при запуске приложения:

 com.sun.xml.ws.model.RuntimeModelerException: runtime modeler error: Wrapper class com.mypackage.ws.services.jaxws.InvalidInputExceptionBean is not found. Have you run APT to generate them?
    at com.sun.xml.ws.model.RuntimeModeler.getClass(RuntimeModeler.java:285)
    at com.sun.xml.ws.model.RuntimeModeler.processExceptions(RuntimeModeler.java:1006)
    at com.sun.xml.ws.model.RuntimeModeler.processRpcMethod(RuntimeModeler.java:969)
    at com.sun.xml.ws.model.RuntimeModeler.processMethod(RuntimeModeler.java:546)
    at com.sun.xml.ws.model.RuntimeModeler.processClass(RuntimeModeler.java:370)
    at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:256)
    at com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:322)
    at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:188)
    at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:467)
    at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.java:333)
    at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.java:45)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport$1.run(FactoryBeanRegistrySupport.java:121)

Добавление @XmlRootEntity к InvalidInputException не решает проблему.

Если это не рекомендуемый способ сообщать об ошибках через веб-сервисы, то есть ли лучший способ? Должны ли мои исключения наследоваться от RuntimeException и полагаться на транспорт для обработки ошибок (т. Е. Все будет заключено в SOAPException)? Я надеялся на что-то вроде Spring-WS 'SoapFaultAnnotationExceptionResolver. Есть ли что-нибудь подобное для JAX-WS?

Ответы [ 2 ]

27 голосов
/ 14 января 2010

Вы пытались аннотировать свое исключение с помощью @WebFault? Кроме того, вы реализуете getFaultInfo()?

РЕДАКТИРОВАТЬ: Я понимаю, что мой ответ, возможно, был недостаточно подробным. Как указано в этой теме (например):

Требования спецификации JAX-WS 2.0 что исключение аннотировано @WebFault должно иметь два конструктора и один метод [получатель для получения информации о неисправности]:

WrapperException(String message, FaultBean faultInfo)
WrapperException(String message, FaultBean faultInfo, Throwable cause)
FaultBean getFaultInfo()

WrapperException заменяется на название исключения и FaultBean заменяется на класс имя, которое реализует компонент ошибки. Бин ошибки - это бин Java, который содержит информацию о вине и используется клиентом веб-службы узнать причину ошибки.

Это подробно описано в разделе 2.5 Ошибка спецификации JAX-WS. Ваше исключение соответствует этому? Вы можете разместить код?


ОП прав. В соответствии со спецификацией 2.1, раздел 3.7 Исключение, специфичное для службы, не требуется использовать аннотацию @WebFault, JAX-WS может генерировать bean-объекты-оболочки динамически для исключений, которые не соответствуют шаблону, описанному в разделе 2.5 (просто предоставьте метод получения для информация, которую вы хотите, чтобы присутствовать в вине). Для исключений, которые соответствуют шаблону, описанному в разделе 2.5 (т.е. исключениям, которые имеют метод getFaultInfo и аннотацию @WebFault), FaultBean используется в качестве входных данных для JAXB при отображении исключения в XML-схему. 1031 *

Таким образом, решение, предложенное выше (в соответствии с шаблоном, описанным в разделе 2.5), является только обходным путем. Создание бобов-оберток должно работать только для других исключений. И я не знаю, почему это терпит неудачу здесь.

17 голосов
/ 14 января 2010

дополнение к ответу выше. Я закончил с этим как моя реализация InvalidInputException:

@WebFault(faultBean = "com.mypackage.ws.exception.FaultBean")
public class InvalidInputException extends Exception {

    private static final long serialVersionUID = 1L;

    private FaultBean faultBean;

    public InvalidInputException() {
        super();
    }

    public InvalidInputException(String message, FaultBean faultBean, Throwable cause) {
        super(message, cause);
        this.faultBean = faultBean;
    }

    public InvalidInputException(String message, FaultBean faultBean) {
        super(message);
        this.faultBean = faultBean;
    }

    public FaultBean getFaultInfo() {
        return faultBean;
    }
}

И FaultBean - это просто POJO без данных на данный момент. Теперь, в соответствии со спецификацией JAX-WS (см. 3.7 Исключение, специфичное для службы), оно соответствует тому, что требуется для исключения, аннотируемого @WebFault, поэтому оно не будет создавать для него bean-объект-обертку, который, вероятно, является причиной сбоя. 1005 *

Это достойный обходной путь, но он не объясняет ошибку в вопросе.

...