1. Обзор
Jersey – это фреймворк с открытым исходным кодом для разработки веб-сервисов RESTful. Он служит эталонной реализацией JAX-RS.
В этой статье мы рассмотрим создание веб-службы RESTful с использованием Jersey 2 . Кроме того, мы будем использовать инъекцию зависимостей Spring (DI) с конфигурацией Java.
2. Зависимости Maven
Давайте начнем с добавления зависимостей в pom.xml :
org.glassfish.jersey.containers jersey-container-servlet 2.26 org.glassfish.jersey.media jersey-media-json-jackson 2.26
Кроме того, для интеграции с Spring мы должны добавить jersey-spring 4 зависимость:
org.glassfish.jersey.ext jersey-spring4 2.26
Последняя версия этих зависимостей доступна по адресу jersey-container-servlet , jersey-media-json-jackson и jersey-spring4 .
3. Веб-конфигурация
Затем нам нужно настроить веб-проект для настройки сервлета. Для этого мы будем использовать Spring WebApplicationInitializer :
@Order(Ordered.HIGHEST_PRECEDENCE) public class ApplicationInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); servletContext.addListener(new ContextLoaderListener(context)); servletContext.setInitParameter( "contextConfigLocation", "com.baeldung.server"); } }
Здесь мы добавляем @Order(Ordered.HIGHEST_PRECEDENCE) аннотация, чтобы убедиться, что наш инициализатор выполняется до инициализатора по умолчанию Jersey-Spring.
4. Сервис С Использованием Jersey JAX-RS
4.1. Класс представления ресурсов
Давайте воспользуемся примером класса представления ресурсов:
@XmlRootElement public class Employee { private int id; private String firstName; // standard getters and setters }
Обратите внимание, что аннотации JAXB, такие как @XmlRootElement , требуются только в том случае, если требуется поддержка XML (в дополнение к JSON).
4.2. Реализация Услуг
Давайте теперь посмотрим, как мы можем использовать аннотации JAX-RS для создания веб-сервисов RESTful:
@Path("/employees") public class EmployeeResource { @Autowired private EmployeeRepository employeeRepository; @GET @Path("/{id}") @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Employee getEmployee(@PathParam("id") int id) { return employeeRepository.getEmployee(id); } @POST @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response addEmployee( Employee employee, @Context UriInfo uriInfo) { employeeRepository.addEmployee(new Employee(employee.getId(), employee.getFirstName(), employee.getLastName(), employee.getAge())); return Response.status(Response.Status.CREATED.getStatusCode()) .header( "Location", String.format("%s/%s",uriInfo.getAbsolutePath().toString(), employee.getId())).build(); } }
Аннотация @Path предоставляет относительный путь URI к службе. Мы также можем встроить переменные в синтаксис URI, как показано в переменной {id} . Затем переменные будут заменены во время выполнения. Для получения значения переменной мы можем использовать аннотацию @PathParam .
@GET , @PUT , @POST, @УДАЛИТЬ и @ГОЛОВА определите метод HTTP запроса , которые будут обработаны аннотированными методами.
Аннотация @Производит определяет тип ответа конечных точек (тип носителя MIME). В нашем примере мы настроили его для возврата либо JSON, либо XML в зависимости от значения заголовка HTTP Accept ( application/json или application/xml ).
С другой стороны, аннотация @Consumes определяет типы носителей MIME, которые может использовать служба. В нашем примере служба может использовать либо JSON, либо XML в зависимости от заголовка HTTP Content-Type ( application/json или application/xml ).
Аннотация @Context используется для ввода информации в поле класса, свойство компонента или параметр метода. В нашем примере мы используем его для ввода UriInfo . Мы также можем использовать его для ввода ServletConfig , ServletContext , HttpServletRequest и HttpServletResponse.
5. Использование ExceptionMapper
ExceptionMapper позволяет нам перехватывать исключения и возвращать клиенту соответствующий код ответа HTTP. В следующем примере код ответа HTTP 404 возвращается, если Сотрудник не найден возникает исключение:
@Provider public class NotFoundExceptionHandler implements ExceptionMapper{ public Response toResponse(EmployeeNotFound ex) { return Response.status(Response.Status.NOT_FOUND).build(); } }
6. Управление Классами Ресурсов
Наконец, давайте подключим все классы реализации служб и сопоставители исключений к пути приложения:
@ApplicationPath("/resources") public class RestConfig extends Application { public Set> getClasses() { return new HashSet >( Arrays.asList( EmployeeResource.class, NotFoundExceptionHandler.class, AlreadyExistsExceptionHandler.class)); } }
7. Тестирование API
Теперь давайте протестируем API с помощью некоторых живых тестов:
public class JerseyApiLiveTest { private static final String SERVICE_URL = "http://localhost:8082/spring-jersey/resources/employees"; @Test public void givenGetAllEmployees_whenCorrectRequest_thenResponseCodeSuccess() throws ClientProtocolException, IOException { HttpUriRequest request = new HttpGet(SERVICE_URL); HttpResponse httpResponse = HttpClientBuilder .create() .build() .execute(request); assertEquals(httpResponse .getStatusLine() .getStatusCode(), HttpStatus.SC_OK); } }
8. Заключение
В этой статье мы представили фреймворк Jersey и разработали простой API. Мы использовали Spring для функций внедрения зависимостей. Мы также видели использование ExceptionMapper .
Как всегда, полный исходный код доступен в этом проекте Github .