Представить EJB как JAX-RS из EJB-модуля

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

У меня есть EJB без сохранения состояния в ejb-модуле внутри моего уха, и я хочу представить этот bean-компонент как спокойный интерфейс, используя jax-rs. На первом этапе я аннотировал класс EJB с помощью @Path и @GET. Это не сработало.

Это работает, когда я создаю дополнительный веб-модуль с web.xml, который содержит

<context-param>
    <param-name>resteasy.jndi.resources</param-name>
    <param-value>myear/testService/no-interface,myear/testService2/no-interface</param-value>
</context-param>
<listener>
    <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<servlet>
    <servlet-name>rest</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>rest</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

Я могу предоставить простой класс только с аннотациями, поэтому я не могу поверить, что мне нужно явно настраивать каждый компонент EJB, который я хочу предоставить, в файле конфигурации.

Есть ли способ проще/лучше?

Я работаю с JBoss 6.1


person Laures    schedule 08.09.2011    source источник


Ответы (1)


Никакой конфигурации быть не должно. Если вы хотите взглянуть на другой контейнер — по крайней мере, для справки — вот пример, который предоставляет @Singleton EJB как службу JAX-RS, так и @LocalBean.

Сам компонент использует транзакции, управляемые контейнером, и JPA, а объекты JPA @Entity используются в реальных сообщениях JAX-RS, что фактически превращает EntityManager в транзакционную службу JAX-RS.

Небольшой кусок класса EJB:

@Singleton
@Lock(LockType.WRITE)
@Path("/user")
@Produces(MediaType.APPLICATION_XML)
public class UserService {

    @PersistenceContext
    private EntityManager em;

    @Path("/create")
    @PUT
    public User create(@QueryParam("name") String name,
                       @QueryParam("pwd") String pwd,
                       @QueryParam("mail") String mail) {
        User user = new User();
        user.setFullname(name);
        user.setPassword(pwd);
        user.setEmail(mail);
        em.persist(user);
        return user;
    }

    @Path("/list")
    @GET
    public List<User> list(@QueryParam("first") @DefaultValue("0") int first,
                           @QueryParam("max") @DefaultValue("20") int max) {
        List<User> users = new ArrayList<User>();
        List<User> found = em.createNamedQuery("user.list", User.class).setFirstResult(first).setMaxResults(max).getResultList();
        for (User u : found) {
            users.add(u.copy());
        }
        return users;
    }

А вот фрагмент модульного теста для него (использует Embeddable EJBContainer API):

public class UserServiceTest {
    private static Context context;
    private static UserService service;
    private static List<User> users = new ArrayList<User>();

    @BeforeClass
    public static void start() throws NamingException {
        Properties properties = new Properties();
        properties.setProperty(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE, "true");
        context = EJBContainer.createEJBContainer(properties).getContext();

        // create some records
        service = (UserService) context.lookup("java:global/rest-on-ejb/UserService");
        users.add(service.create("foo", "foopwd", "[email protected]"));
        users.add(service.create("bar", "barpwd", "[email protected]"));
    }

    @Test
    public void list() throws Exception {
        String users = WebClient.create("http://localhost:4204")
                .path("/user/list")
                .get(String.class);
        assertEquals(
            "<users>" +
                "<user>" +
                    "<email>[email protected]</email>" +
                    "<fullname>foo</fullname>" +
                    "<id>1</id>" +
                    "<password>foopwd</password>" +
                "</user>" +
                "<user>" +
                    "<email>[email protected]</email>" +
                    "<fullname>bar</fullname>" +
                    "<id>2</id>" +
                    "<password>barpwd</password>" +
                "</user>" +
            "</users>", users);
    }

Полный исходный код примера здесь. Весь пример состоит всего из трех классов (включая тест) и файла persistence.xml.

person David Blevins    schedule 09.09.2011
comment
Уважаемый @David Blevins, я получаю сообщение об ошибке 404 (страница не найдена) при вызове веб-сервиса при отображении EJB как Rest в weblogic; Мне был добавлен класс, унаследованный от Application, который аннотирован @ApplicationPath(/resources) , и мой класс веб-сервиса не имеет состояния, который аннотирован @Path(/getdata) и он включает простой метод, аннотированный @GET @Path(/getaccount) URL-адрес, который я использовал в Weblogic для вызова этой веб-службы: http://localhost:7001/resources/getdata/getaccount, что приводит к ошибке 404--Not Found б> - person Hosein Aqajani; 30.08.2019