将EJB模块中的EJB公开为JAX-RS服务

4

我知道可以使用注解将web模块内的类作为restful接口公开。现在我想做更复杂的事情。

我有一个无状态EJB在我的ear中的ejb模块中,希望使用jax-rs将这个bean暴露为restful接口。首先,我用@Path和@GET注释了EJB类。但它没有起作用。

当我创建一个额外的web模块,并将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。
1个回答

3

不需要任何配置。如果您愿意查看另一个容器的示例用作参考,请看下面的示例,它将@Singleton EJB公开为JAX-RS服务和@LocalBean。

这个bean本身使用容器管理的事务和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;
    }

下面是与之相关的单元测试代码(使用可嵌入的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", "foo@foo.com"));
        users.add(service.create("bar", "barpwd", "bar@bar.com"));
    }

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

示例的完整源代码在这里。整个示例只包括三个类(包括测试)和一个persistence.xml文件。


亲爱的@David Blevins,当我将EJB作为Rest在Weblogic中公开时,调用webservice时出现404错误(页面未找到)。我已经添加了一个从Application继承的类,该类被注释为**@ApplicationPath("/resources"),我的web服务类是无状态的,被注释为@Path("/getdata"),它包括一个简单的方法,被注释为@GET @Path("/getaccount")。我在Weblogic中使用的URL来调用此webservice是:http://localhost:7001/resources/getdata/getaccount,结果是错误404--未找到**。 - Hosein Aqajani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接