Skip to content

Latest commit

 

History

History
398 lines (329 loc) · 14.9 KB

README.adoc

File metadata and controls

398 lines (329 loc) · 14.9 KB

Возможности

Эта библиотека обеспечивает интеграцию JaxRS провайдера CXF и моделей Spring Data Common через автоконфигурацию Spring Boot.

  • Автоматическое разворачивание REST сервисов (@Path)

  • @deprecated (use feign) Автоматическое подключение REST прокси клиентов

  • Интеграция со Swagger (@Api*)

  • Прозрачная работа с моделями Spring Data: Page, Pageable, Sort

  • Обработка и возврат локализованных сообщений об ошибках клиенту в виде json

  • Логирование всех запросов / ответов (можно отключить через jaxrs.logging-in.enabled=false, jaxrs.logging-out.enabled=false)

  • Включение JSR303 валидаций на REST сервисах (можно отключить через jaxrs.jsr303=false)

Инструкции

Сервер

Подключение

Добавьте зависимость:

<dependency>
  <groupId>net.n2oapp.platform</groupId>
  <artifactId>n2o-platform-starter-jaxrs-server</artifactId>
</dependency>

Инициализация

Задаёте следующие настройки:

cxf.path=/api
cxf.jaxrs.component-scan=true
cxf.servlet.init.service-list-path=/info

Настройки таймаута

Чтобы переопределить значения таймаута, задайте следующие настройки:

#Таймаут (мс) ожидания клиентом соединения с сервером. 0 - бесконечность, по умолчанию 30000мс.
cxf.jaxrs.client.connection.timeout=30000
#Таймаут (мс) ожидания клиентом ответа сервера. 0 - бесконечность, по умолчанию 60000мс.
cxf.jaxrs.client.receive.timeout=60000

Интерфейс и реализация

Чтобы написать REST сервис, создайте интерфейс с аннотациями JaxRs:

@Path("/example")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public interface SomeRest {
    ...
}

Создайте класс реализующий интерфейс и добавьте его в Spring Context как bean, например, аннотацией @Controller:

@Controller
public class SomeRestImpl implements SomeRest {
    ...
}
Note
Разделение на интерфейс и класс требуется для использования прокси клиентов. Более того, желательно чтобы интерфейсы и классы были в разных Maven модулях.

Паджинация, сортировки и фильтры

Чтобы сервисы принимали параметры паджинации и сортировки, а возвращали одну страницу данных и общее количество записей, можно использовать классы Spring Data:

@GET
@Path("/search")
Page<SomeModel> search(@BeanParam SomeCriteria criteria);

Класс Page возвращает список записей одной страницы (getContent), общее количество записей (getTotalElements) и заданные сортировки.

Для задания сортировок и фильтров используйте классы критериев поиска (SomeCriteria), они должны расширять класс RestCriteria, который в свою очередь является реализацией интерфейса Pageable.

public class SomeCriteria extends RestCriteria {
    @QueryParam("name")
    private String likeName;
    @QueryParam("date")
    private Date dateBegin;

    //getters setters
}

Валидации

Чтобы проверить входные данные сервисов на валидность, удобно использовать аннотации JSR303, такие как @NotNull, @Size и др.

@Validated
public class SomeModel {
    private Long id;
    @NotBlank
    private String name;
    @Past
    private Date date;
    //getters setters
}

Для того, чтобы активировать аннотации JSR303, необходимо пометить аргументы REST метода аннотацией @Valid:

@POST
@Path("/")
Long create(@Valid SomeModel model);

Если валидации не используются, обработчика валидаций можно отключить настройкой jaxrs.jsr303=false.

Исключения и локализация

Для возвращения всех исключений клиенту в виде json укажите настройку:

n2o.ui.message.stacktrace=true
{
  "message" : "Some error",
  "stackTrace":[
    "...",
    "\tat ...",
    "\tat ...",
    "\tat ...",
    "\tat ..."
  ]
}

В поле message попадает сообщение исключения, в поле stackTrace весь список строк java стектрейса.

Чтобы локализовать сообщение для клиента, выбрасывайте специальное исключение UserException:

throw new UserException("example.code")
            .set("раз")
            .set("два");

Подробнее о нем написано в модуле n2o-platform-i18n.

Чтобы передать сообщение под каждое поле формы используйте JSR303 валидации. В этом случае в json ответ добавится поле errors:

{
  "errors" : [
    {
      "field" : "create.arg0.name",
      "message" : "не может быть пусто"
    }
  ]
}

А http статус будет 400.

Логирование

Все запросы и ответы, и сервера, и клиента логируются по умолчанию. Для настройки параметров логирования (logging-in - входящие, logging-out - исходящие) используйте следующие настройки:

#Включить/выключить логирование. По-умолчанию true.
jaxrs.logging-in.enabled = true
#Размер в байтах, свыше которого сообщение будет обрезано. По-умолчанию -1, не ограничено.
jaxrs.logging-in.limit = -1
#Размер в байтах, свыше которого сообщение будет записано на диск. По-умолчанию 100кб.
jaxrs.logging-in.in-mem-threshold = 100 * 1024
#Форматирование сообщения
jaxrs.logging-in.pretty-logging
jaxrs.logging-in.log-binary
jaxrs.logging-in.log-multipart

Документирование

Добавьте в модуль с api следующие зависимости:

<dependency>
    <groupId>net.n2oapp.platform</groupId>
    <artifactId>n2o-platform-jaxrs-commons</artifactId>
</dependency>

Для совместимости со старыми версиями платформы api-модуль нужно собирать с указанием:

<properties>
    <java.version>1.8</java.version>
</properties>

Используйте на рест сервисах аннотации @Api* из пакета io.swagger.annotations.

@Path("/example")
@Api("Пример документирования REST сервиса")
public interface SomeRest {
    @GET
    @Path("/search")
    @ApiOperation("Найти что-нибудь")
    @ApiResponse(code = 200, message = "Нашли что-то")
    Page<SomeModel> search(@BeanParam SomeCriteria criteria);
    ...
}

В настройках приложения задайте путь к REST сервисам со openApi аннотациями и другие параметры:

jaxrs.openapi.enabled=true
jaxrs.openapi.title=REST сервисы для примера
jaxrs.openapi.version=1.0
jaxrs.openapi.resource-package=net.n2oapp.microservice.example
#Опционально можно указать какие протоколы (http,https,ws,wss):
jaxrs.openapi.schemes=http,https
jaxrs.openapi.auth.name=oauth2
jaxrs.openapi.auth.token-uri=http://localhost:8080/oauth/token
Note
Для корректной работы авторизации необходимо передать аргумент authorizations = @Authorization(value = "oauth2") в аннотацию @Api(…​) сервисов, требующих авторизации. Аргумент value должен соответствовать настройке jaxrs.swagger.auth.name.

Ссылка на документацию Swagger будет доступна по адресу /api/info (cxf.path + cxf.servlet.init.service-list-path).

images\README f585f

Прокси клиент @deprecated (use feign)

Подключение

Для подключения REST прокси клиентов добавьте зависимость:

<dependency>
  <groupId>net.n2oapp.platform</groupId>
  <artifactId>n2o-platform-starter-jaxrs-client</artifactId>
</dependency>

Также вам понадобится зависимость от api-модуля, где лежат ваши интерфейсы сервисов с аннотациями jaxrs.

Поиск JaxRs интерфейсов

Чтобы подключить REST прокси клиент, как обычный Spring бин, задайте следующие настройки:

#Включение поиска и регистрации прокси клиентов
cxf.jaxrs.client.classes-scan=true
#Пакет, в котором искать JaxRs интерфейсы
cxf.jaxrs.client.classes-scan-packages=net.n2oapp.microservice.example
#Адрес, где развернуты REST сервисы
cxf.jaxrs.client.address=http://localhost:8080/api

Добавьте аннотацию @EnableJaxRsProxyClient в конфигурацию Spring:

import net.n2oapp.platform.jaxrs.autoconfigure.EnableJaxRsProxyClient;
...
@Configuration
@EnableJaxRsProxyClient
public class ExampleConfiguration {
  ...
}

В этом случае сработает автоконфигурация JaxRsClientAutoConfiguration и создадутся прокси клиенты под каждый найденный интерфейс.

Выборочное подключение

Если вам требуются сервисы развернутые на разных адресах, то нужно использовать более тонкий способ настройки с помощью аннотации @EnableJaxRsProxyClient:

import net.n2oapp.platform.jaxrs.autoconfigure.EnableJaxRsProxyClient;
...
@Configuration
@EnableJaxRsProxyClient(
  classes = SomeRest.class,
  address = "${myapp.url}/example/api")
public class ExampleConfiguration {
  ...
}

Использование

Используйте REST прокси клиенты как обычные Spring бины:

@Service
public class ConsumerServiceImpl {
  @Autowired
  private SomeRest client;//REST прокси клиент

  ...
}

Каждый вызов метода прокси клиента будет делать http запрос к сервису.

Обработка исключений

При использовании REST прокси клиентов, исключения возникшие на сервере, автоматически выбрасываются и на клиенте. Класс исключений: RestException:

try {
   client.create(model);
 } catch (RestException e) {
   e.getMessage();//Локализованное сообщение
   e.getErrors();//Ошибки JSR303 валидаций
 }

При этом стектрейс исключения RestException будет содержать в себе стектрейс от сервера.

Веб клиент

Инициализация

Для подключения WEB клиента, необходимо на класс конфигурации Spring повесить аннотацию @EnableJaxRsWebClient:

@Configuration
@EnableJaxRsWebClient
public class ExampleConfiguration {
  ...
}

Адрес REST сервисов задаётся настройкой:

cxf.jaxrs.client.address=http://localhost:8080/api

Использование

Для выполнения запросов к REST сервисам, через аннотацию @Autowired подключаем клиента:

@Service
public class ConsumerServiceImpl {
  @Autowired
  private Client client;

  ...
}

Формат даты и времени

В качестве формата даты и времени в параметрах запроса, в теле запроса и ответа используется формат ISO8601:

YYYY-MM-DDThh:mm:ss[.sss]

Поддержка XML

Поддержка заголовков Accept и Content-Type, указанных как application/xml.

Методы веб-сервиса теперь можно пометить как

@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})

В таком случае, в зависимости от заголовков Accept и Content-Type будут приниматься и возвращаться данные в соответствующем формате.

Однако есть несколько ограничений. Самое значительное это то, что нельзя использовать примитивы в качестве body в своих сервисах (даже обертки типа java.lang.Long). Они обязательно должны быть обернуты в POJO объект.

И вообще желательно всегда оборачивать body запросов и ответов в POJO объекты. Желательно также по - минимуму использовать wildcard-ы (List<?>), вещи наподобие Map<String, Object> и т.д.