JAX-WS - сопоставление исключений с неисправностями
Я использую 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 ответа
Вы пытались комментировать свое исключение с @WebFault
? Кроме того, вы реализуете getFaultInfo()
?
РЕДАКТИРОВАТЬ: я понимаю, что мой ответ, возможно, не был достаточно подробным. Как напомнили в этой теме (например):
Спецификация JAX-WS 2.0 требует, чтобы исключение было отмечено
@WebFault
должен иметь два конструктора и один метод [getter для получения информации об ошибке]: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-схему.
Таким образом, решение, предложенное выше (в соответствии с шаблоном, описанным в разделе 2.5), является только обходным путем. Создание бобов-оберток должно работать только для других исключений. И я не знаю, почему это не удается здесь.
Дополнение к ответу выше. Я закончил с этим как моя реализация 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-объект-обертку, который, вероятно, является причиной сбоя.
Это достойный обходной путь, но он не объясняет ошибку в вопросе.