JAX-WS сервер SOAPHandler, который возвращает ошибку, получает "Внутреннюю ошибку" на WebSphere v8
У меня есть сервер JAX-WS SOAPHandler
(на WebSphere v8) на стороне сервера, который в некоторых случаях должен отвечать клиенту с ответом SOAP, который он имеет в переменной String (позвольте ему позвонить responseXml
).
Когда responseXml
содержит успешное (то есть неважное) сообщение SOAP, JAX-WS корректно отправляет ответ клиенту. Однако, когда responseXml
содержит сообщение об ошибке SOAP, появляется "Внутренняя ошибка", и клиент получает другой ответ на ошибку, чем тот, что находится в responseXml
, как показано ниже:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<soapenv:Fault xmlns:axis2ns1="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>axis2ns1:Server</faultcode>
<faultstring>Internal Error</faultstring>
<detail/>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
На консоль записывается следующая ошибка:
[10/9/12 12:21:04:177 EDT] 00000025 AxisEngine E org.apache.axis2.engine.AxisEngine receive An error was detected during JAXWS processing
org.apache.axis2.AxisFault: An error was detected during JAXWS processing
at org.apache.axis2.jaxws.server.JAXWSMessageReceiver.receive(JAXWSMessageReceiver.java:208)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:198)
at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
at com.ibm.ws.websvcs.transport.http.WASAxis2Servlet.doPost(WASAxis2Servlet.java:1466)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)
...
Вот упрощенная SOAPHandler
, которая иллюстрирует эту проблему. (Обратите внимание, что показанное здесь значение responseXml
является просто примером. В моем фактическом SOAPHandler
ответы не жестко закодированы, а считываются из базы данных. Я просто пытаюсь показать простой пример кода. )
package simplified.demo;
import java.io.ByteArrayInputStream;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class FaultyHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public boolean handleMessage(SOAPMessageContext context) {
Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (!outbound) {
String responseXml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Header></soapenv:Header><soapenv:Body><soapenv:Fault><faultcode>soapenv:Server</faultcode><faultstring>ORA-01031: insufficient privileges</faultstring><detail/></soapenv:Fault></soapenv:Body></soapenv:Envelope>";
try {
SOAPMessage newMsg = createSOAPMessage(responseXml);
context.setMessage(newMsg);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return (outbound);
}
private SOAPMessage createSOAPMessage(String responseXml) {
try {
ByteArrayInputStream in = new ByteArrayInputStream(responseXml.getBytes());
MessageFactory messageFactory = MessageFactory.newInstance();
return messageFactory.createMessage(null, in);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public boolean handleFault(SOAPMessageContext context) {
return true;
}
@Override
public Set<QName> getHeaders() {
return null;
}
@Override
public void close(MessageContext context) {
}
}
Я получаю ту же ошибку, когда я код SOAPHandler
создает объект SOAPFault
(используя SOAPFactory
) и бросаю его в SOAPFaultException
.
На основе трассировки стека я посмотрел исходный код JAXWSMessageReceiver
, и, похоже, под обложками Axis2 выглядит для вызванного исключенияByException, но, конечно, в этом случае его нет.
Кто-нибудь знает, почему это происходит или как это можно исправить? Спасибо!
Ответы
Ответ 1
Реальная проблема не в недостатке, вызванном исключением, это скорее унифицированная обработка ошибок в websphere:
http://www-01.ibm.com/support/docview.wss?uid=swg1PM58524
Используйте описанное обходное решение или установите не менее 8.0.0.4
Ответ 2
У меня была такая же проблема, и я смог ее решить, отключив единую обработку ошибок (это не ошибка, это функция!).
В консоли разработчика WAS
https://<yourhost>/<yourport>/ibm/console/login.do
выполните, как описано here (для WAS8):
Выберите "Серверы" > "Типы серверов"., а также серверы приложений WebSphere > имя_сервера или прокси-серверы WebSphere > имя_сервера. Затем в разделе "Инфраструктура сервера" выберите "Управление Java" и "Управление процессами" > "Определение процесса" и выберите "Управление", "Служебный" или "Адъюнкт". Затем щелкните виртуальную машину Java > Пользовательские свойства.
Там добавьте новое свойство webservices.unify.faults
и установите значение false
.
![введите описание изображения здесь]()
Ответ 3
WebSphere, начиная с версии 8, имеет функцию безопасности по умолчанию, просто возвращая сообщение "Внутренняя ошибка". Это делается для " предотвращения подробной информации о том, почему обработка входящих сообщений не удалась с момента отправки отправителям сообщений". Найдите "webservices.unify.faults"
Чтобы отключить эту функцию, добавьте в пользовательские свойства JVM -Dwebservices.unify.faults = false.
Ответ 4
Эта ошибка может быть устранена путем отключения общей функции обработки ошибок на серверах приложений IBM Websphere Application Servers.
Чтобы отключить это свойство, перейдите в Консоль администраторa > Серверы > Серверы приложений → Определение процессa > Виртуальная машина Java > Пользовательские свойства.
Введите ключ как "webservice.unify.faults" и значение "false".
После обновления перезапустите сервер и установите EAR для получения пользовательских ошибок WSDL для транзакций SOAP.
Ответ 5
У меня была такая же проблема после обновления WAS FP 8.5.5.10 до 8.5.5.12. У нас было две службы с точно таким же именем метода, но у другого targetNameSpace, например у DomainService1 есть метод 'get', а DomainService2 также имеет метод 'get', но WAS 8.5. 5.12 выбрасывает это исключение и не дает никакой подсказки, чтобы найти основную причину. По-видимому, WAS более строгий в последней версии с наименованием методов.
Это было исключение:
org.apache.axis2.jaxws.wrapper.impl.JAXBWrapperException: Произошла внутренняя ошибка утверждения. Объект com.xxx.web.myapp.services.jaxws.GetResponse JAXB не имеет xxxxxStatus xml
После изменения имени метода, специфичного для каждой службы "getABC" и "getPQR", это сработало!!!
надеюсь, что это сработает!