Se você tiver aplicativos Enterprise JavaBeans (EJB) que são expostos usando uma visualização de ionterface local, é possível expor uma interface RESTful ao enterprise bean usando Java™ API for RESTful
Web Services (JAX-RS).
Ao implementar enterprise beans anotados do JAX-RS, você mantém a funcionalidade do EJB incluindo suporte a transações, injeção de componentes e recursos Java EE, e outros recursos de bean de sessão do EJB.
Antes de Iniciar
Antes do EJB 3.1, os enterprise beans que necessitavam de uma visualização de cliente local do EJB também precisavam de uma interface Java separada, geralmente localizada em um arquivo separado, que declarava os métodos de visualização locais.
O enterprise bean especificava que implementou a interface de visualização local do EJB usando descritores de implementação ou anotações EJB.
Usando a especificação EJB 3.1, você tem a opção de expor uma visualização local de um enterprise bean sem uma interface local do EJB explícita.
Em vez disso, o enterprise bean tem uma visualização de cliente sem interface que se baseia nos métodos públicos da sua classe de bean. Enterprise beans de visualização sem interface podem ser mais simples de desenvolver do que um enterprise
bean de visualização local pelas seguintes razões:
- Enterprise beans de visualização sem interface não necessitam de uma declaração de interface Java separada.
- Enterprise beans de visualização sem interface não precisam especificar metadados adicionais no descritor de implementação ou ao usar anotações.
Consulte a especificação EJB 3.1 para obter detalhes adicionais sobre as visualizações sem interface de um enterprise bean.
O JAX-RS suporta o uso de enterprise beans que declaram uma interface de negócios local e enterprise beans com visualização sem interface.
Essa tarefa descreve a implementação de visualizações RESTful de um enterprise bean com uma interface local para ativar o enterprise bean para expor recursos JAX-RS.
Sobre Esta Tarefa
É possível criar um enterprise bean simples com anotações JAX-RS.
Apesar de essa tarefa descrever especificamente como implementar visualizações RESTful de um enterprise bean com visualização de interface local, é importante que você considere o escopo completo da arquitetura do seu aplicativo e como deseja expor recursos ao decidir o seu modelo de recurso e determinar quais visualizações RESTful são apropriadas para o seu aplicativo enterprise beans. Essas considerações estão além do escopo dessa tarefa.
O JAX-RS suporta beans de sessão stateless e singleton.
É possível incluir anotações JAX-RS na interface local de um bean de sessão. Também, com o EJB 3.1, é possível incluir anotações JAX-RS diretamente em uma classe EJB se o enterprise bean expor uma visualização sem interface.
Com as regras de compactação do EJB 3.1, é possível incluir enterprise beans JAX-RS no arquivo web application archive (WAR) tanto diretamente no diretório WEB-INF/classes quanto usando um arquivo Java archive (JAR) no diretório WEB-INF/lib. É possível declarar um enterprise bean usando anotações, ou usando um descritor de implementação EJB, ou usando ambos, anotações e um descritor de implementação.
Enterprise beans anotados do JAX-RS em um arquivo ejb-jar independente ou separado que está incluído em um EAR não são suportados.
Boas Práticas: Apesar de você poder declarar enterprise beans de diferentes maneiras, uma boa prática é implementar diretamente a interface local de negócios do EJB e sempre declarar a anotação @javax.ejb.Local.
Ao usar esse método, o bean do EJB é necessário para implementar a interface de negócios local, o que elimina erros de digitação nos nomes de método e nas mudanças para tipos de argumento. Ao usar sempre a anotação @javax.ejb.Local, se houver diversas interfaces de negócios sempre, é possível simplesmente incluir a interface de negócios no valor da anotação. Também é possível usar essa abordagem para modificar o enterprise bean usando um descritor de implementação.
bprac
Procedimento
- Crie interfaces locais de enterprise bean para o seu aplicativo enterprise
bean. O exemplo a seguir demonstra uma interface de negócios local simples, a interface local EJB Purchasable, para itens para compra:
pacote com.example.jaxrs;
@javax.ws.rs.Path("itemsForPurchase/{itemID}")
public interface Purchasable {
public int getItemsLeft(String itemID);
@javax.ws.rs.POST
public Order purchase(
@javax.ws.rs.PathParam("itemID") String itemID,
@javax.ws.rs.QueryParam("orderId") String orderID);
}
O método getItemsLeft é um método EJB regular que não está relacionado ao JAX-RS. Uma anotação javax.ws.rs.Path denota o caminho da solicitação de HTTP a usar. Quando uma solicitação HTTP POST é feita para o objeto itemsForPurchase/{itemID}, o ambiente de tempo de execução JAX-RS localiza um bean EJB que imnplementa a interface local Purchasable e chama o método de compra no enterprise bean.
Você ainda pode usar o método de compra fora de uma solicitação de ambiente de tempo de execução JAX-RS. É possível usar injeção ou uma consulta do JNDI para um enterprise bean adquirível e chamar o método de compra com os dois argumentos String, itemID e orderID.
Boas Práticas: Se existirem diversos enterprise beans que implementam uma interface de negócios local, o ambiente de tempo de execução JAX-RS escolhe um bean EJB aleatório para usar quando um pedido de JAX-RS for feito. É uma boa prática ativar apenas uma classe de bean para implementar uma interface local EJB anotado do JAX-RS. Se necessário, crie uma interface local EJB separada, use as anotações JAX-RS na nova interface, e depois modifique os metadados para a classe de bean para que ela implemente a nova interface local EJB.
bprac
- Crie o enterprise bean que implementa a interface de negócios local. O exemplo a seguir ilustra o bean EJB Purchasable:
public int getItemsLeft(String itemID) {
// Retornar o número de itens restantes.
}
public Order purchase(String itemID, String orderId) {
// Incluir o item fornecido no ID do pedido e retorná-lo.
}
}
- Declare que a classe Book é um enterprise bean e implementa uma interface local. Use um dos seguintes métodos para declarar a sua classe como um enterprise bean que implementa a interface local. No exemplo a seguir, a classe Book é declarada um enterprise bean que implementa uma interface local:
- Use as anotações EJB @javax.ejb.Stateless ou @javax.ejb.Singleton na classe Book para especificar que deseja que o EJB seja stateless ou singleton. Também, inclua a anotação @javax.ejb.Local com as interfaces locais como o valor da anotação; por exemplo:
@javax.ejb.Stateless
@javax.ejb.Local(Purchasable.class)
public class Book {
Se você implementou diversas interfaces de negócios locais, inclua as classes da interface no valor da anotação @javax.ejb.Local; por exemplo:
@javax.ejb.Local({Purchasable.class, Rentable.class})
- É possível usar um descritor de implementação para declarar um bean EJB e as interfaces de negócios que ele implementa; por exemplo:
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" version="3.1"
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/ejb-jar_3_1.xsd">
<!--
Esse arquivo deve existir no diretório WEB-INF/
do seu arquivo WAR. Consulte a especificação 20.4 do EJB 3.1 para obter mais detalhes.
-->
<enterprise-beans>
<session>
<ejb-name>Book</ejb-name>
<business-local>com.example.jaxrs.Purchasable</business-local>
<ejb-class>com.example.jaxrs.Book</ejb-class>
<session-type>Stateless</session-type>
</session>
</enterprise-beans>
</ejb-jar>
Se você implementou diversas interfaces de negócios locais, deve incluir elementos locais de negócios em cada interface local na sua definição de bean.
- Se você tem apenas uma interface de negócios local, é possível implementar a interface diretamente; por exemplo:
@javax.ejb.Stateless
public class Book implements Purchasable {
- (opcional) Inclua campos e propriedades do recurso Java EE anotado do @javax.annotation.Resource nas suas classes JAX-RS EJB para acessar facilmente os recursos no seu aplicativo. As injeções Java EE não funcionam em classes Java simples com anotações JAX-RS. Injetar campos e propriedades do recurso Java EE anotado do @javax.annotation.Resource nas suas classes JAX-RS EJB apenas funciona se as suas classes anotadas JAX-RS forem um enterprise bean ou um bean gerenciado Java Context and Dependency Injection (JCDI) (JSR-299); por exemplo:
package com.example.jaxrs;
@javax.ejb.Stateless
@javax.ejb.Local(Purchasable.class)
public class Book implements Purchasable {
@javax.annotation.Resource(name="jdcb/TestDataSource")
private javax.sql.DataSource datasource;
public int getItemsLeft(String itemID) {
// Lê da origem de dados.
// Retorna o número de itens restantes.
}
public Order purchase(String itemID, String orderId) {
// Lê da origem de dados.
// Inclui o item fornecido no ID do pedido e retorná-lo.
}
}
Nesse exemplo, se uma origem de dados está configurada adequadamente com o nome do JNDI correto, um objeto DataSource é injetado na classe de recurso.
- (opcional) Use injeção de JAX-RS @javax.ws.rs.core.Context para obter acesse às informações sobre o pedido. É possível incluir um campo UriInfo @javax.ws.rs.core.Context na sua classe EJB do JAX-RS para acessar informações sobre a URI do pedido; por exemplo:
package com.example.jaxrs;
@javax.ejb.Stateless
@javax.ejb.Local(Purchasable.class)
public class Book implements Purchasable {
@javax.ws.rs.core.Context
private UriInfo uriInfo;
public int getItemsLeft(String itemID) {
// Retornar o número de itens restantes.
}
public Order purchase(String itemID, String orderId) {
// Incluir o item fornecido no ID do pedido e retorná-lo.
}
}
Para ler parâmetros do pedido como @javax.ws.rs.HeaderParam, @javax.ws.rs.QueryParam, e @javax.ws.rs.PathParam, inclua um parâmetro no seu método de recurso; por exemplo:
pacote com.example.jaxrs;
@javax.ws.rs.Path("itemsForPurchase/{itemID}")
public interface Purchasable {
public int getItemsLeft(String itemID);
@javax.ws.rs.POST
public Order purchase(
@javax.ws.rs.PathParam("itemID") String itemID,
@javax.ws.rs.QueryParam("orderId") String orderID);
}
pacote com.example.jaxrs;
@javax.ejb.Stateless
@javax.ejb.Local(Purchasable.class)
public class Book implements Purchasable {
@javax.ws.rs.core.Context
private UriInfo uriInfo;
public int getItemsLeft(String itemID) {
// Retorna o número de itens restantes.
}
public Order purchase(String itemID, String orderId) {
// Os parâmetros do método contêm os valores do pedido.
// Incluir o item fornecido no ID do pedido e retorná-lo.
}
/* O seguinte campo não será configurado. */
@javax.ws.rs.QueryParam("q")
private String willNotWork;
@javax.ws.rs.QueryParam("q")
public void setMyQueryParam(String q) {
/* Essa propriedade não será configurada. */
}
}
Configurações suportadas: As anotações do parâmetro JAX-RS devem ser incluídas nos métodos do recurso na interface de negócios EJB ao usar interfaces de negócios. Elas não podem ser incluídas no bean de implementação.
sptcfg
- Compacte os enterprise beans no diretório WEB-INF/classes do arquivo WAR, ou dentro de um arquivo JAR que está incluído no diretório WEB-INF/lib do seu arquivo WAR.
Quando um cliente faz uma solicitação a um enterprise bean anotado do JAX-RS, o ambiente de tempo de execução do JAX-RS procura e usa uma instância EJB da classe para depois chamar o método do recurso JAX-RS.
Resultados
Você ativou um enterprise bean existente com interfaces locais para que os recursos JAX-RS sejam expostos para consumo.