从 EJB 模块将 EJB 公开为 JAX-RS

发布于 2024-12-03 14:17:55 字数 1066 浏览 3 评论 0原文

我知道我可以仅使用注释将 Web 模块内的类公开为静态接口。现在我想做一些更复杂的事情。

我耳内的 ejb 模块中有一个无状态 EJB,并且希望使用 jax-rs 将该 bean 公开为静态接口。在第一步中,我使用 @Path@GET 注释了 EJB 类。它不起作用。

当我使用 web.xml 创建一个附加的 Web 模块时,它可以工作,其中包含

<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

I know I can expose a class inside a web-module as a restful interface using only annotations. Now I want to do something a little more complex.

I'm having a stateless EJB in an ejb-module inside my ear and want to expose this bean as a restful interface using jax-rs. In the first step I annotated the EJB class with @Path and @GET. It didn't work.

It works when I create an additional web-module with a web.xml that contains

<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>

I can expose a simple class with only annotations, so I can't quite believe that I have to explicitly configure every EJB that I want to expose in a config file.

Is there a simpler/better way?

I'm working with JBoss 6.1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

棒棒糖 2024-12-10 14:17:55

不应该需要任何配置。如果您愿意查看另一个容器(至少出于参考目的),这里有一个将 @Singleton EJB 公开为 JAX-RS 服务和 @LocalBean 的示例。

bean 本身使用容器管理事务和 JPA,以及实际 JAX-RS 消息中使用的 JPA @Entity 对象——有效地将 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 文件。

There shouldn't be any config required. If you're willing to look at another container -- at least for reference purposes -- here's an example that exposes an @Singleton EJB as both a JAX-RS service and @LocalBean.

The bean itself uses Container-Managed Transactions and JPA, with the JPA @Entity objects used in the actual JAX-RS messages -- effectively turning the EntityManager into a transactional JAX-RS service.

Small chunk of the EJB class:

@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;
    }

And here's a chunk of the unit test for it (uses the 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);
    }

Full source of the example here. The entire example is just three classes (that includes the test) and a persistence.xml file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文