Статьи

Учебник RESTEasy, часть 3: обработка исключений

Обработка исключений является очевидным требованием при разработке программного приложения. Если во время обработки пользовательского запроса произошла какая-либо ошибка, мы должны показать пользователю страницу ошибки с такими подробностями, как краткое сообщение об исключении, код ошибки (необязательно), подсказки для исправления ввода и повторных попыток (необязательно), а также фактическая причина (необязательно). Это применимо и к веб-сервисам RESTful.

Но размещение блоков try-catch-finally вокруг кода не является хорошей практикой. Мы должны спроектировать / кодировать таким образом, чтобы в случае возникновения неисправимой ошибки код генерировал это исключение, и должен быть обработчик исключений, чтобы перехватить эти исключения и извлечь подробности об ошибках и дать правильный ответ об ошибке клиенту со всеми подробности ошибки.

RESTEasy предоставляет такой механизм ExceptionHandler, который упрощает процесс ExceptionHandling.

В этой части я покажу вам, как мы можем использовать ExceptionHandlers в RESTEasy для обработки исключений.

Шаг № 1: Создайте исключения для приложений.

01
02
03
04
05
06
07
08
09
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
**
 * ResourceNotFoundException.java
 *
package com.sivalabs.resteasydemo;
 
public class ResourceNotFoundException extends RuntimeException
{
 private static final long serialVersionUID = 1L;
 public ResourceNotFoundException(String msg)
 {
  super(msg);
 }
}
 
**
 * ApplicationException.java
 *
package com.sivalabs.resteasydemo;
 
import java.io.PrintWriter;
import java.io.StringWriter;
 
public class ApplicationException extends RuntimeException
{
 private static final long serialVersionUID = 1L;
 
 public ApplicationException()
 {
  super();
 }
 public ApplicationException(String message, Throwable cause)
 {
  super(message, cause);
 }
 public ApplicationException(Throwable cause)
 {
  super(cause);
 }
 public ApplicationException(String msg)
 {
  super(msg);
 }
 public String getInternalErrorMessage()
 {
  Throwable cause = this.getCause();
  if(cause != null)
  {
   StringWriter sw = new StringWriter();
   PrintWriter pw = new PrintWriter(sw);
   cause.printStackTrace(pw);
   return sw.toString();
  }
  return null;
 }
}

Шаг № 2: Создание ExceptionHandlers путем реализации интерфейса ExceptionMapper.

01
02
03
04
05
06
07
08
09
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
**
 * ResourceNotFoundExceptionHandler.java
 *
package com.sivalabs.resteasydemo;
 
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
 
import org.springframework.stereotype.Component;
 
@Provider
@Component
public class ResourceNotFoundExceptionHandler implements ExceptionMapper<ResourceNotFoundException>
{
 
 @Override
 public Response toResponse(ResourceNotFoundException ex)
 
  For simplicity I am preparing error xml by hand.
  Ideally we should create an ErrorResponse class to hold the error info.
  String msg = ex.getMessage();
  StringBuilder response = new StringBuilder('<response>');
  response.append('<status>failed<status>');
  response.append('<message>'+msg+'<message>');
  response.append('<response>');
 
  return Response.serverError().entity(response.toString()).build();
 }
 
}
 
**
 * ApplicationExceptionHandler.java
 *
package com.sivalabs.resteasydemo;
 
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
 
import org.springframework.stereotype.Component;
 
@Provider
@Component
public class ApplicationExceptionHandler implements ExceptionMapper<ApplicationException>
{
 @Override
 public Response toResponse(ApplicationException ex)
 {
  For simplicity I am preparing error xml by hand.
  Ideally we should create an ErrorResponse class to hold the error info.
  String msg = ex.getMessage();
  String internalError = ex.getInternalErrorMessage();
  StringBuilder response = new StringBuilder('<response>');
  response.append('<status>failed<status>');
  response.append('<message>'+msg+'<message>');
  response.append('<internalError>'+internalError+'<internalError>');
  response.append('<response>');
  return Response.serverError().entity(response.toString()).build();
 }
 
}

Шаг № 3: Обновите метод UserResource.getUserXMLById (), чтобы проверить ввод данных пользователем и выдать соответствующие исключения .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
@Path('{id}')
@GET
public Response getUserXMLById(@PathParam('id') Integer id)
{
 if(id==null || id < 1 ){
  throw new ApplicationException('User Id['+id+'] should not be less than 1.');
 }
 User user = userService.getById(id);
 
 if(user==null ){
  throw new ResourceNotFoundException('No User found with Id :['+id+']');
 }
 return Response.ok(user).build();
}

Шаг № 4: Проверьте метод службы UserResource.getUserXMLById (), выполнив следующие запросы.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
case 1 : GET http:localhost:8080resteasy-demorestusers0
 Response :
  <response>
                        <status>failed<status>
   <message>User Id[0] should not be less than 1.<message>
   <internalError>null<internalError>
  <response>
 
case 2: GET http:localhost:8080resteasy-demorestusers100
 Response :
         <response>
          <status>failed<status>
   <message>No User found with Id :[100]<message>
  <response>

Важные вещи, на которые стоит обратить внимание:

Поскольку Spring создает необходимые объекты, мы должны сообщить Spring о классах @Provider, чтобы они были зарегистрированы в RESTEasy. Мы можем сделать это двумя способами.

а) Аннотируйте классы провайдера с помощью @Component

б) Использование include-фильтра для компонентного сканирования.
<context: component-scan base-package = ‘com.sivalabs.springdemo’>
<context: include-filter expression = ‘javax.ws.rs.ext.Provider’ type = ‘annotation’ />
</ Контекст: компонент сканирования>

Серия RESTEasy Tutorial

RESTEasy Tutorial Part-1: Основы

Учебник RESTEasy, часть 2: Spring Integration

RESTEasy Tutorial Part 3 — Обработка исключений

Ссылка: Учебное пособие RESTEasy, часть 3 — Обработка исключений от нашего партнера по JCG Шивы Редди в блоге « Мои эксперименты по технологии» .