Java Platform, Enterprise Edition (Java EE) 8
Учебник по Java EE

Назад Вперёд Содержание

Приложение customer

В этом разделе описывается, как создать и запустить пример customer. Это приложение представляет собой RESTful веб-сервис, который использует JAXB для выполнения операций создания, чтения, обновления, удаления (CRUD) для конкретного объекта.

Приложение customer находится в каталоге tut-install/examples/jaxrs/customer/. См. главу 2 «Использование учебных примеров», для получения базовой информации о создании и запуске примеров приложений.

Здесь рассматриваются следующие темы:

Обзор customer

Исходные файлы этого приложения находятся в каталоге tut-install/examples/jaxrs/customer/src/main/java/. Приложение состоит из трёх частей.

  • Классы сущностей Customer и Address. Эти классы моделируют данные приложения и содержат аннотации JAXB.

  • Класс ресурсов CustomerService. Этот класс содержит методы ресурсов JAX-RS, которые выполняют операции над объектами Customer, представленными в виде данных XML или JSON, с использованием JAXB. Смотрите Класс CustomerService для подробностей.

  • Сессионный компонент CustomerBean, который является вспомогательным компонентом для веб-клиента. CustomerBean использует клиентский API JAX-RS для вызова методов CustomerService.

Приложение customer показывает, как моделировать объекты данных как классы Java с аннотациями JAXB.

Классы сущностей Customer и Address

Следующий класс представляет адрес клиента:

@Entity
@Table(name="CUSTOMER_ADDRESS")
@XmlRootElement(name="address")
@XmlAccessorType(XmlAccessType.FIELD)
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @XmlElement(required=true)
    protected int number;

    @XmlElement(required=true)
    protected String street;

    @XmlElement(required=true)
    protected String city;

    @XmlElement(required=true)
    protected String province;

    @XmlElement(required=true)
    protected String zip;

    @XmlElement(required=true)
    protected String country;

    public Address() { }

    // get- и set- методы
    // ...
}

Аннотация @XmlRootElement(name="address") отображает этот класс в XML-элемент address. Аннотация @XmlAccessorType(XmlAccessType.FIELD) указывает, что все поля этого класса по умолчанию связаны с XML. Аннотация @XmlElement(required=true) указывает, что элемент должен присутствовать в представлении XML.

Следующий класс представляет клиента:

@Entity
@Table(name="CUSTOMER_CUSTOMER")
@NamedQuery(
    name="findAllCustomers",
    query="SELECT c FROM Customer c " +
          "ORDER BY c.id"
)
@XmlRootElement(name="customer")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @XmlAttribute(required=true)
    protected int id;

    @XmlElement(required=true)
    protected String firstname;

    @XmlElement(required=true)
    protected String lastname;

    @XmlElement(required=true)
    @OneToOne
    protected Address address;

    @XmlElement(required=true)
    protected String email;

    @XmlElement (required=true)
    protected String phone;

    public Customer() {...}

    // get- и set- методы
    // ...
}

Класс Customer содержит те же аннотации JAXB, что и предыдущий класс, за исключением аннотации @XmlAttribute(required=true), которая отображает свойство в атрибут элемента XML, представляющего класс.

Класс Customer содержит свойство, тип которого является другой сущностью, класс Address. Этот механизм позволяет вам определять в коде Java иерархические отношения между сущностями без необходимости писать файл .xsd самостоятельно.

JAXB генерирует следующее определение схемы XML для двух предыдущих классов:


<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="address" type="address"/>
  <xs:element name="customer" type="customer"/>

  <xs:complexType name="address">
    <xs:sequence>
      <xs:element name="id" type="xs:long" minOccurs="0"/>
      <xs:element name="number" type="xs:int"/>
      <xs:element name="street" type="xs:string"/>
      <xs:element name="city" type="xs:string"/>
      <xs:element name="province" type="xs:string"/>
      <xs:element name="zip" type="xs:string"/>
      <xs:element name="country" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="customer">
    <xs:sequence>
      <xs:element name="firstname" type="xs:string"/>
      <xs:element name="lastname" type="xs:string"/>
      <xs:element ref="address"/>
      <xs:element name="email" type="xs:string"/>
      <xs:element name="phone" type="xs:string"/>
    </xs:sequence>
    <xs:attribute name="id" type="xs:int" use="required"/>
  </xs:complexType>
</xs:schema>

Класс CustomerService

Класс CustomerService имеет метод createCustomer, который создаёт ресурс клиента на основе класса Customer и возвращает URI для нового ресурса.

@Stateless
@Path("/Customer")
public class CustomerService {
    public static final Logger logger =
            Logger.getLogger(CustomerService.class.getCanonicalName());
    @PersistenceContext
    private EntityManager em;
    private CriteriaBuilder cb;

    @PostConstruct
    private void init() {
        cb = em.getCriteriaBuilder();
    }
    ...
    @POST
    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response createCustomer(Customer customer) {

        try {
            long customerId = persist(customer);
            return Response.created(URI.create("/" + customerId)).build();
        } catch (Exception e) {
            logger.log(Level.SEVERE,
                    "Error creating customer for customerId {0}. {1}",
                    new Object[]{customer.getId(), e.getMessage()});
            throw new WebApplicationException(e,
                    Response.Status.INTERNAL_SERVER_ERROR);
        }
    }
    ...
    private long persist(Customer customer) {
        try {
            Address address = customer.getAddress();
            em.persist(address);
            em.persist(customer);
        } catch (Exception ex) {
            logger.warning("Something went wrong when persisting the customer");
        }
        return customer.getId();
    }

Ответ, возвращённый клиенту, имеет URI для вновь созданного ресурса. Тип возвращаемого значения — это тело объекта, отображаемое из свойства ответа с кодом состояния, указанным в свойстве status ответа. WebApplicationException — это RuntimeException, который используется для переноса соответствующего кода состояния ошибки HTTP, такого как 404, 406, 415 или 500.

Аннотации @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) и @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) устанавливают типы MIME для запросов и ответов для использования соответствующего клиента MIME. Эти аннотации могут применяться к методу ресурса, классу ресурса или даже провайдеру сущностей. Если вы не используете эти аннотации, JAX-RS позволяет использовать любой тип MIME ("*/*").

В следующем фрагменте кода показана реализация методов getCustomer и findById. Метод getCustomer использует аннотацию @Produces и возвращает объект Customer, который преобразуется в представление XML или JSON в зависимости от заголовка Accept, указанного клиентом.

    @GET
    @Path("{id}")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Customer getCustomer(@PathParam("id") String customerId) {
        Customer customer = null;

        try {
            customer = findById(customerId);
        } catch (Exception ex) {
            logger.log(Level.SEVERE,
                    "Error calling findCustomer() for customerId {0}. {1}",
                    new Object[]{customerId, ex.getMessage()});
        }
        return customer;
    }
    ...
    private Customer findById(String customerId) {
        Customer customer = null;
        try {
            customer = em.find(Customer.class, customerId);
            return customer;
        } catch (Exception ex) {
            logger.log(Level.WARNING,
                    "Couldn't find customer with ID of {0}", customerId);
        }
        return customer;
    }

Использование клиента JAX-RS в классах CustomerBean

Используйте клиентский API JAX-RS для написания клиента в приложении customer.

Класс Enterprise-бина CustomerBean вызывает клиентский API JAX-RS для тестирования веб-сервиса CustomerService:

@Named
@Stateless
public class CustomerBean {
    protected Client client;
    private static final Logger logger =
            Logger.getLogger(CustomerBean.class.getName());

    @PostConstruct
    private void init() {
        client = ClientBuilder.newClient();
    }

    @PreDestroy
    private void clean() {
        client.close();
    }

    public String createCustomer(Customer customer) {
        if (customer == null) {
            logger.log(Level.WARNING, "customer is null.");
            return "customerError";
        }
        String navigation;
        Response response =
                client.target("http://localhost:8080/customer/webapi/Customer")
                .request(MediaType.APPLICATION_XML)
                .post(Entity.entity(customer, MediaType.APPLICATION_XML),
                        Response.class);
        if (response.getStatus() == Status.CREATED.getStatusCode()) {
            navigation = "customerCreated";
        } else {
            logger.log(Level.WARNING, "couldn''t create customer with " +
                    "id {0}. Status returned was {1}",
                    new Object[]{customer.getId(), response.getStatus()});
            navigation = "customerError";
        }
        return navigation;
    }

    public String retrieveCustomer(String id) {
        String navigation;
        Customer customer =
                client.target("http://localhost:8080/customer/webapi/Customer")
                .path(id)
                .request(MediaType.APPLICATION_XML)
                .get(Customer.class);
        if (customer == null) {
            navigation = "customerError";
        } else {
            navigation = "customerRetrieved";
        }
        return navigation;
    }

    public List<Customer> retrieveAllCustomers() {
        List<Customer> customers =
                client.target("http://localhost:8080/customer/webapi/Customer")
                .path("all")
                .request(MediaType.APPLICATION_XML)
                .get(new GenericType<List<Customer>>() {});
        return customers;
    }
}

Этот клиент использует методы POST и GET.

Все эти коды состояния HTTP указывают на успешное выполнение: 201 для POST, 200 для GET и 204 для DELETE. Подробнее о значениях кодов состояния HTTP см. http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.

Запуск customer

Вы можете использовать IDE NetBeans или Maven для сборки, упаковки, развёртывания и запуска приложения customer.

Здесь рассматриваются следующие темы:

Сборка, упаковка и развёртывание customer с IDE NetBeans

  1. Удостоверьтесь, чтобы GlassFish Server был запущен (см. Запуск и остановка сервера GlassFish).

  2. В меню «Файл» выберите «Открыть проект».

  3. В диалоговом окне «Открыть проект» перейдите к:

    tut-install/examples/jaxrs
  4. Выберите каталог customer.

  5. Нажмите Открыть проект.

  6. На вкладке «Проекты» кликните правой кнопкой мыши проект customer и выберите «Сборка».

    Эта команда собирает и упаковывает приложение в WAR-файл customer.war, расположенный в каталоге target. Затем WAR-файл развёртывается на сервере GlassFish.

  7. Откройте веб-клиент в браузере по следующему URL:

    http://localhost:8080/customer/

    Веб-клиент позволяет создавать и просматривать клиентов.

Сборка, упаковка и развёртывание customer с использованием Maven

  1. Удостоверьтесь, чтобы GlassFish Server был запущен (см. Запуск и остановка сервера GlassFish).

  2. В окне терминала перейдите в:

    tut-install/examples/jaxrs/customer/
  3. Введите следующую команду:

    mvn install

    Эта команда собирает и упаковывает приложение в WAR-файл customer.war, расположенный в каталоге target. Затем WAR-файл развёртывается на сервере GlassFish.

  4. Откройте веб-клиент в браузере по следующему URL:

    http://localhost:8080/customer/

    Веб-клиент позволяет создавать и просматривать клиентов.


Назад Вперёд Содержание
Логотип Oracle  Copyright © 2017, Oracle и/или её дочерних компаний. Все права защищены. Версия перевода 1.0.5 (Java EE Tutorial — русскоязычная версия)