Статьи

Использование Defne Framework с веб-сервисами RESTful через Apache Wink

Defne — сервис-ориентированная платформа веб-приложений. Основной мотивацией Defne является простота использования. Defne позволяет разработчикам сконцентрироваться на своей бизнес-логике, а также обеспечивает все другие требования приложений, такие как транзакции и безопасность. С Defne вы можете легко реализовать бизнес-логику на основе Java EE.

Apache Wink  — это законченное решение на основе Java для реализации и использования веб-служб на основе REST. Цель платформы Wink — предоставить повторно используемый и расширяемый набор классов и интерфейсов, которые послужат основой, на которой разработчик может эффективно создавать приложения. Apache Wink 1.1 стремится быть полностью совместимой реализацией спецификации JAX-RS v1.1.

 В этой статье мы рассмотрим, как реализовать веб-приложение, используя Wink и Defne вместе. В то время как Wink предоставляет веб-сервисы RESTful, Defne обеспечивает внедрение бизнес-сервисов сервис-ориентированным способом.

Требования

В этой статье мы используем SIwpas, http://code.google.com/p/siwpas , сервер приложений Simple Web Profile, который содержит все необходимые библиотеки. Если вы хотите использовать Tomcat, Jetty или любой другой сервер приложений, вам необходимо объединить необходимые библиотеки с вашим классом пути приложения или сервера.

 Библиотеки Defne можно загрузить с  http://code.google.com/p/defne/ . Библиотеки Apache Wink можно загрузить с http://incubator.apache.org/wink/.

Пример веб-приложения

В этой статье наше приложение представляет собой простое веб-приложение, которое 

  • Создает экземпляр книги с « именем и автором » и возвращает «идентичность» созданной книги: мы создадим параметры формы POST «имя» и «автор» для создания экземпляра книги.
  • Получает информацию о книге по заданному « идентификатору книги »: мы получим информацию о книге, используя запрос GET, например; HTTP: // локальный: 8080 / покоя пример / книги / {book_id}

Веб-сервис RESTful

Сначала мы пишем веб-сервис RESTful.

@Path("/books")
public class BookResource
{
@POST
@Consumes(value=MediaType.APPLICATION_FORM_URLENCODED)
@Produces(value=MediaType.TEXT_PLAIN)
public String createBook(MultivaluedMap<String, String> formParams)
{
Message message = MessageFactory.newMessage(IBookService.SERVICE_NAME, IBookService.ADD_OPERATION.OPERATION_NAME);
message.putMessageParameter(IBookService.ADD_OPERATION.INPUT.NAME, formParams.getFirst(IBookService.ADD_OPERATION.INPUT.NAME));
message.putMessageParameter(IBookService.ADD_OPERATION.INPUT.AUTHOR, formParams.getFirst(IBookService.ADD_OPERATION.INPUT.AUTHOR));

message = PojoServiceExecutor.execute(message);

return message.getMessageParameter(String.class, IBookService.ADD_OPERATION.OUTPUT.ID);
}

@GET
@Path(value="{bookid}")
public String showBookInfo(@PathParam(value="bookid") String id)
{
Message message = MessageFactory.newMessage(IBookService.SERVICE_NAME, IBookService.GET_INFO_OPERATION.OPERATION_NAME);
message.putMessageParameter(IBookService.GET_INFO_OPERATION.INPUT.ID, id);

message = PojoServiceExecutor.execute(message);

return message.getMessageParameter(Book.class, IBookService.GET_INFO_OPERATION.OUTPUT.BOOK).toString();
}
}

Здесь вы видите корневой ресурс RESTful, BookResource, который содержит один подресурс.

From Wink Руководство пользователя

Ресурсы являются одним из фундаментальных понятий в REST. REST подчеркивает манипулирование ресурсами, а не вызовы функций. Ресурсы имеют уникальные идентификаторы. В терминах HTTP это означает, что каждый ресурс должен быть связан хотя бы с одним URL.

Чтобы манипулировать ресурсом, запросы выполняются с помощью специального метода HTTP. Например, чтобы получить представление ресурса, выдается HTTP-запрос GET к URL-адресу ресурса. Для создания нового элемента в коллекции можно использовать HTTP-запрос POST с URL-адресом коллекции. Разработчики приложений определяют ресурсы и методы HTTP, чтобы быстро манипулировать ими, используя обычные простые старые объекты Java и аннотации JAX-RS.

Вернемся наш случай, у нас есть один корневой ресурс , BookResource , для обработки «HTTP: // локальный: 8080 / отдых-выборочные / отдых / книги» URL и один суб-ресурс для обработки «HTTP: // локальный: 8080 / отдых -sample / rest / books / {book_id} « URL .

  • Доступ к одному осуществляется с помощью http: // localhost: 8080 / rest-sample / rest / books. Когда форма заявки отправляется, во время выполнения Apache Wink вызывается метод createBook . Он создает сообщение Defne и вызывает ADD_OPERATION службы Book.
  • Доступ к одному осуществляется с использованием http: // localhost: 8080 / rest-sample / rest / books / {book_id}.  Когда вы нажимаете на URL book_id, Apache Winkruntime вызывает метод showBookInfo. Он создает сообщение Defne и вызывает GET_INFO_OPERATION службы Book.

Defne Book Service

Здесь представлен интерфейс и реализация Defne Book Service.

Сервисный интерфейс,

public interface IBookService
{
String SERVICE_NAME = "BookService";

interface ADD_OPERATION{

String OPERATION_NAME = "createBook";
interface INPUT{
String NAME = "NAME";
String AUTHOR = "AUTHOR";
}

interface OUTPUT{
String ID = "ID";
}

}

interface GET_INFO_OPERATION{
String OPERATION_NAME = "getBookInfo";
interface INPUT{
String ID = "ID";
}

interface OUTPUT{
String BOOK = "BOOK";
}

}
}

 А вот и реализация. Это очень легко написать услуги Defne,

@Service(name="BookService")
public class BookServiceImpl
{

@Operation
@TransactionAttribute(TransactionPolicy.WITH_TRANSACTION)
@EntityManagerAttribute
public static Message createBook(Message message) throws DefneException
{
String name = message.getMessageParameter(String.class, IBookService.ADD_OPERATION.INPUT.NAME);
String author = message.getMessageParameter(String.class, IBookService.ADD_OPERATION.INPUT.AUTHOR);

Book book = new Book();
book.setName(name);
book.setAuthor(author);

EntityManager manager = EntityManagerUtil.getEntityManagerFromBag(message);
manager.persist(book);

Message oMessage = MessageFactory.newMessage();
oMessage.putMessageParameter(IBookService.ADD_OPERATION.OUTPUT.ID,Integer.toString(book.getId()));

return oMessage;
}

@Operation
@TransactionAttribute(TransactionPolicy.NO_TRANSACTION)
@EntityManagerAttribute
public static Message getBookInfo(Message message) throws DefneException
{
EntityManager manager = EntityManagerUtil.getEntityManagerFromBag(message);
Query query = manager.createQuery("select c from Book c where c.id=:id");
query.setParameter("id", Integer.parseInt(message.getMessageParameter(String.class, IBookService.GET_INFO_OPERATION.INPUT.ID)));

Book book = (Book) query.getSingleResult();
Message oMessage = MessageFactory.newMessage();
oMessage.putMessageParameter(IBookService.GET_INFO_OPERATION.OUTPUT.BOOK,book);

return oMessage;
}

}

Аннотации TransactionAttribute и EntityManagerAttribute используются для определения требований Transaction и JPA к операции службы.

 В первой операции мы получаем параметры формы (имя и автор) и создаем экземпляр Book. Во второй операции мы получаем «id» экземпляра книги, который мы запрашиваем для информации о книге.

Wink Application Class 

Чтобы зарегистрировать наш сервис RESTful в Wink, нам нужно написать класс приложения, который расширяет javax.ws.rs.core.Application.

public class WinkBookApplication extends Application
{

@Override
public Set<Class<?>> getClasses()
{
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(BookResource.class);

return classes;
}

}

Наша HTML-страница

Это наша простая HTML-страница для публикации параметров формы, предоставляющих информацию о Книге.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>REST Example</title>
</head>
<body>

<form action="/rest-sample/rest/books/" method="post">
<label>Name : </label>
<input type="text" name="NAME"/>

<br/>
<label>Author : </label>
<input type="text" name="AUTHOR"/>

<br/>

<input type="submit" value="Add Book"/>

</form>
</body>
</html>

Когда форма публикуется, Wink находит связанный сервис RESTful из URL и метода, связанного с вызовом, BookResource # createBook, с экземпляром MultivaluedMap <String, String>, который содержит параметры формы.

Когда вы нажимаете URL-адрес, например, http: // localhost: 8080 / rest-sample / rest / books / 2, Wink находит связанный RESTful-сервис из URL-адреса и метода, связанного с вызовом , BookResource # showBookInfo с @PathParam (value = «bookid») Экземпляр строки , содержащий «2».

Конфигурация Wink

Чтобы использовать Wink, мы должны добавить некоторые настройки в «web.xml». Вот полный файл web.xml.

<web-app id="WebApp_ID" version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<display-name>Rest Example Application</display-name>

<listener>
<listener-class>org.defne.service.scanner.ScannerListener</listener-class>
</listener>

<servlet>
<servlet-name>Books</servlet-name>
<servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.defne.server.rest.WinkBookApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Books</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>

 Здесь мы регистрируем наш экземпляр приложения с помощью init-param. Мы также предоставляем обработку URL сервлета REST, / rest / *. Слушатель используется для сканирования сервисов Defne.

Файлы beans.xml и defne-service.xml

Эти файлы используются Apache OpenWebBeans и Defne соответственно. Файл defne-service.xml представляет собой файл маркера, который помещается в папку META-INF / каталога classpath приложения. Defne Framework ищет этот файл для сканирования развертывания. beans.xml — это файл конфигурации CDI.

JPA файл persistence.xml

Платформа Defne использует Java Persistence API для обработки операций с базой данных. Вот файл persistence.xml, используемый приложением,

 <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">

<persistence-unit name="default" transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>

<class>org.defne.server.rest.Book</class>

<properties>
<property name="openjpa.jdbc.DBDictionary" value="hsql" />
<property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver" />
<property name="openjpa.ConnectionURL" value="jdbc:hsqldb:mem:test" />
<property name="openjpa.ConnectionUserName" value="sa" />
<property name="openjpa.ConnectionPassword" value="" />
<property name="openjpa.Log" value="DefaultLevel=TRACE"/>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
</properties>

</persistence-unit>
</persistence>

 Мы используем Apache OpenJPA, это время выполнения предоставляется с SIwpas. Если вы хотите использовать другого поставщика сохраняемости, вам необходимо связать его библиотеки с вашим приложением и соответствующим образом обновить конфигурацию.

Полная заявка

Вы можете получить полное приложение-пример от Defne SVN, http://tiny.cc/zs9sx

Вывод

Defne предоставляет простой способ написания вашей бизнес-логики с использованием технологий Java EE. Службы Defne могут легко вызываться различными клиентами, такими как, Pure AJAX, Автономная Java, Java-сервлет, JSF, RESTful Services и т. Д. В следующем выпуске мы добавим больше клиентов, таких как JMS, TCP, Web-сервис и т. Д.

Wink облегчает разработку и использование веб-сервисов REST, предоставляя средства для моделирования сервиса в соответствии с архитектурным стилем REST. Wink предоставляет необходимую инфраструктуру для определения и реализации ресурсов, представлений и унифицированных методов, которые составляют
сервис.

Определить URL

Веб-сайт: http://code.google.com/p/defne/

Сайт SVN: http://code.google.com/p/defne/source/browse/

Снимок Maven: https://oss.sonatype.org / содержание / хранилища / снимки / орг / Defne /

Maven: http://repo1.maven.org/maven2/org/defne/

Обсуждение Defne: http://groups.google.com/group/defnedev

Apache Wink URL

Веб-сайт:  http://incubator.apache.org/wink/

Сайт SVN: http://svn.apache.org/repos/asf/incubator/wink/

Наслаждайтесь!

Член АФС, http://apache.org

Председатель PMC, Apache OpenWebBeans

Технический директор, MechSoft Механические и программные решения, http://www.mechsoft.com.tr