В JAX-WS в весенний стороне сервера установить пользовательские сообщение об ошибке для RuntimeExceptions



Задача



По умолчанию JAX-WS создает следующее сообщение об ошибке SOAP, когда на моем сервере возникает необработанное исключение, которое расширяет RuntimeException:



<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns3="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>[runtime exception message here]</faultstring>
<detail>
<ns2:exception class="java.lang.RuntimeException" note="To disable this feature, set com.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTrace system property to false" xmlns:ns2="http://jax-ws.dev.java.net/">
<message>[runtime exception message here too]</message>
<ns2:stackTrace>
[stack trace details]
</ns2:stackTrace>
</ns2:exception>
</detail>
</S:Fault>
</S:Body>
</S:Envelope>


Какой вид имеет смысл, за исключением того, что я хотел бы изменить это поведение, чтобы отправить его вместо этого:



<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns3="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>Something wrong happened and it's totally our fault</faultstring>
</S:Fault>
</S:Body>
</S:Envelope>


Обратите внимание, что сообщение должно не быть содержимым сообщения RuntimeException, а пользовательским статическим сообщением для любого исключения, которое расширяет RuntimeException, которое может возникнуть серверный.

Я не могу изменить WSDL и не хочу устанавливать пользовательское исключение.



Я использую плагин spring: com.sun.xml.ws.transport.http.servlet.WSSpringServlet



Как я могу это сделать?

561   2  

2 ответов:

Я думаю, что вы можете подойти к проблеме с помощью SoapFaultMappingExceptionResolver http://docs.spring.io/spring-ws/site/reference/html/server.html

SoapFaultMappingExceptionResolver является более сложным реализация. Этот распознаватель позволяет вам взять имя класса любое исключение, которое может быть вызвано и сопоставить его с ошибкой SOAP, например Итак:

<beans>
    <bean id="exceptionResolver"
        class="org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver">
        <property name="defaultFault" value="SERVER"/>
        <property name="exceptionMappings">
            <value>
                org.springframework.oxm.ValidationFailureException=CLIENT,Invalid request
            </value>
        </property>
    </bean> </beans>

Значения ключа и конечная точка по умолчанию используют формат faultCode, faultString, locale, где требуется только код ошибки. Если строка неисправности не задана, то по умолчанию будет установлено исключение сообщение. Если язык не задан, по умолчанию используется английский. То выше конфигурация будет отображать исключения типа ValidationFailureException к ошибке SOAP на стороне клиента с ошибкой строка "недопустимый запрос", Как видно из следующего ответа:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Body>
       <SOAP-ENV:Fault>
           <faultcode>SOAP-ENV:Client</faultcode>
           <faultstring>Invalid request</faultstring>
       </SOAP-ENV:Fault>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Если возникнет какое-либо другое исключение, оно вернет ошибку по умолчанию: a ошибка на стороне сервера с сообщением об исключении в виде строки ошибки.

Вам следует изменить организацию.весенняя рамка.ОКСМ.Исключение ValidationFailureException исключений, что вас интересует, т. е. на Java.яз..Исключение или java.яз..RuntimeException

Можно также создать пользовательский класс исключений

public class CustomGenericAllException extends RuntimeException {


    private String errorCode;
    private String errorMsg;

   //getter and setter for errorCode and errorMsg       

    public CustomGenericAllException(String errorCode, String errorMsg) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

}

В каждом методе вы можете бросить это исключение

 throw new CustomGenericAllException("S:Server", "Something wrong happened and it's totally our fault");

И в конфигурации xml вы можете сопоставить это универсальное исключение <value>com.testpackage.CustomGenericAllException ....

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

Я предполагаю, что у вас есть конечная точка, подобная приведенной ниже:

import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.soap.SoapFaultException;
import org.w3c.dom.Element;

@Endpoint
public class HolidayEndpoint {

    private static final String NAMESPACE_URI = "http://mycompany.com/hr/schemas";

    public HolidayEndpoint() {
    }

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "HolidayRequest")                  
    public void handleHolidayRequest(@RequestPayload Element holidayRequest)               
        throws Exception {
      //your code to handle the request on the server
    }
}

Теперь предположим, что handleHolidayRequest () - это то место, где вы ожидаете появления исключения RuntimeException, которое должно изменить код следующим образом:

import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.soap.SoapFaultException;
import org.w3c.dom.Element;

@Endpoint
public class HolidayEndpoint {

    private static final String NAMESPACE_URI = "http://mycompany.com/hr/schemas";

    public HolidayEndpoint() {
    }

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "HolidayRequest")                  
    public void handleHolidayRequest(@RequestPayload Element holidayRequest)               
        throws Exception {
        try
        {
            //your code to handle the request on the server
        }
        catch(RuntimeException e)
        {
            String faultMessage = "Something's wrong on our end. Try again later.";
            throw new SoapFaultException(faultMessage);
        }
    }
}

Обратите внимание, как я перехватываю исключение среды выполнения и создаю новое SoapFaultException? Это делает трюк, и ответ таков:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>SOAP-ENV:Server</faultcode>
         <faultstring xml:lang="en">Something's wrong on our end. Try again later.</faultstring>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Теперь, если вы используете что-то вроде spring-интеграции с активатором службы, это точно такая же концепция за исключением того, что вместо того, чтобы бросить SoapFaultException, вы просто собираетесь построить сообщение с SoapFaultException в качестве полезной нагрузки:

@ServiceActivator(inputChannel = "input", outputChannel = "output")
public Message<?> handleHolidayRequest(HolidayRequest holidayRequest) {
   try {
      // your code to handle the request on the server
   } catch (RuntimeException e) {
      String faultMessage = "Something's wrong on our end. Try again later.";
      SoapFaultException soapFaultException = new SoapFaultException(faultMessage);
      return MessageBuilder.withPayload(soapFaultException).build();
   }
}

PS: для вашего понимания я использовал пример учебника по веб-сервисам здесь для иллюстрации (и у меня есть рабочий пример, если вы все еще боретесь): http://docs.spring.io/spring-ws/site/reference/html/tutorial.html

Удачи!

Comments

    Ничего не найдено.