Обработка ошибок в SOAP веб-сервисе на стороне сервера
Обработка ошибок (exception) soap веб-сервиса на стороне сервера.
Используемые технологии и библиотеки
- Apache CXF 3.1.6
- Spring MVC 4.3.0.Release
1. Описание задачи
Создать и обработать исключение на стороне сервера при использовании SOAP веб-сервиса. Для этой статьи есть описание клиентской стороны, тестирующий данный код.
2. Структура проекта
Проект основан на начальной статье — SOAP java веб сервис. Пример Hello World example. Здесь добавлен пакет exceptions и три класса в нем (ExceptionTrace, MyWebserviceException, WSException). Так же добавлен новый метод в soap веб-сервисе класса HelloSoap, способный выбрасывать исключение.
3. Собественный Exception
Для обработки исключений, которые могут возникать при работе с нашим soap веб-сервисом были написаны три класса. Разумеется можно обрабатывать стандартные Java исключения, но часто они бывают не информативны или вообще не понятны человеку, далекому от Java разработки и тем более вашего сервиса. Поэтому частой практикой является создание собственных исключений, которые будут выдавать какое-либо осмысленное сообщение о возникшей ошибке при работе с вашим сервисом.
Первый класс ExceptionTrace содержит в себе одно поля, которое будет содержать трейс ошибки.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | package ru.javastudy.ws.exceptions; /**  * Created for JavaStudy.ru on 18.06.2016.  */ public class ExceptionTrace {     private String trace;     public String getTrace() {         return trace;     }     public void setTrace(String trace) {         this.trace = trace;     } } | 
Второй класс WSException будет основным родителем для других ошибок нашего сервиса. Он наследует класс Exception.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package ru.javastudy.ws.exceptions; /**  * Created for JavaStudy.ru on 18.06.2016.  */ public class WSException extends Exception {     private ExceptionTrace exceptionTrace = new ExceptionTrace();     public WSException(String message) {         super(message);     }     public WSException(String message, Throwable cause) {         super(message, cause);     }     public WSException(Throwable cause) {         super(cause);     }     public ExceptionTrace getExceptionTrace() {         exceptionTrace.setTrace(getStringFromTrace(getStackTrace()));         return exceptionTrace;     }     private String getStringFromTrace(StackTraceElement[] stackTrace) {         StringBuilder builder = new StringBuilder();         builder.append("\n");         for (StackTraceElement element : stackTrace) {             builder.append(String.valueOf(element)).append("\n");         }         return builder.toString();     } } | 
Как видите он имеет несколько стандартных конструкторов и два самописных метода, которые будут выдавать трейс возникшей ошибки в читаемом виде.
Третий класс MyWebserviceException является тем самым исключением, которое будет выбрасываться одним из методов нашего веб-сервиса.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package ru.javastudy.ws.exceptions; import javax.xml.ws.WebFault; /**  * Created for JavaStudy.ru on 18.06.2016.  */ @WebFault public class MyWebserviceException extends WSException {     public MyWebserviceException(String message) {         super(message);     } } | 
Здесь класс просто наследует вышеописанный класс-исключение. В реальных проектах на месте класса MyWebserviceException обычно находится класс, описывающий конкретное исключение. Например, это может быть класс DocumentNotFoundException, который будет содержать текст сообщения «Документы по вашему запросу не найдены» и возникать, например, при запросе документов из вашей базы данных через API.
4. SOAP Сервис и Exception
В наш soap веб-сервис был добавлен метод, который всегда генерирует исключение.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | package ru.javastudy.ws.soap; import ru.javastudy.ws.exceptions.MyWebserviceException; import ru.javastudy.ws.exceptions.WSException; import ru.javastudy.ws.model.Goods; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; /**  * Created for JavaStudy.ru on 11.06.2016.  */ /**  * The @WebService annotation on the implementation class lets CXF know which  * interface to use when creating WSDL. In this case its simply our HelloWorld interface.  */ @WebService public interface WebserviceSEI {     @WebMethod//annotation optional and is mainly used to provide a name attribute to the public method in wsdl     String testService();     @WebMethod     String sayHelloTo(@WebParam(name = "text") String text);     @WebMethod     Goods getGoods();     @WebMethod     void exceptionTest(@WebParam(name = "text") String text) throws MyWebserviceException; } | 
Реализация этого интерфейса выглядит следующим образом:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | package ru.javastudy.ws.soap; import ru.javastudy.ws.exceptions.MyWebserviceException; import ru.javastudy.ws.model.Goods; import javax.jws.WebService; /**  * Created for JavaStudy.ru on 10.06.2016.  */ @WebService(endpointInterface = "ru.javastudy.ws.soap.WebserviceSEI",         serviceName = "HelloSoap") public class HelloSoap implements WebserviceSEI {     @Override     public String testService() {         return "Hello from SOAP Webservice!";     }     @Override     public String sayHelloTo(String text) {         return "Hello to " + text;     }     @Override     public Goods getGoods() {         Goods goods = new Goods();         goods.setId(1);         goods.setName("Some goods test name");         return goods;     }     @Override     public void exceptionTest(String text) throws MyWebserviceException {         System.out.println("HelloSoap exceptionTest..");             throw new MyWebserviceException(text);     } } | 
Таким образом при вызове этого метода мы увидим текст в консоли о запуске метода и далее будет выброшено исключение, которое мы и должны будем обработать на клиенте. Об этом в следующей статье.



