0

我正在创建一个简单的 RESTful 服务

@Path("/book")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Stateless
public class RestBookService {
    @PersistenceContext(unitName="bookPU")
    private EntityManager em;

    @Context
    protected UriInfo uriInfo;

    @POST
    public Response createBook(Book book) {
        if (book == null)
            throw new BadRequestException();
        em.persist(book);
        URI bookUri = uriInfo.getAbsolutePathBuilder().path(book.getId() + "").build();
        return Response.created(bookUri).build();
    }
}

这本书是简单的 JPA 实体

@Entity
@XmlRootElement
public class Book {

    static Logger log = Logger.getLogger(Book.class.getName());

    public static final String FIND_ALL = "Book.find_all";

    @Id
    @GeneratedValue
    private int id;

    @Column(nullable=false)
    private String title;

    @Column
    private Float price;
}

//只是给出一个相关的代码。有getter/setter和构造函数

我在 Glassfish 4.1 上使用 Maven 部署服务 我正在使用 Jersey Container 2.13 Hibernate 4.3.5 Final Mysql 5.1

当我尝试使用 cURL 创建一本书时,如下所示

curl -X POST --data-binary "<book><price>12.5</price><title>Book Title</title></book>" -H "Content-Type: application/xml" http://localhost:8080/book-service/rs/book -v 

它抛出以下异常。

  StandardWrapperValve[jersey-serlvet]: Servlet.service() for servlet jersey-serlvet threw exception
java.lang.IllegalStateException: Not inside a request scope.
    at jersey.repackaged.com.google.common.base.Preconditions.checkState(Preconditions.java:149)
    at org.glassfish.jersey.process.internal.RequestScope.current(RequestScope.java:228)
    at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:156)
    at org.jvnet.hk2.internal.MethodInterceptorImpl.invoke(MethodInterceptorImpl.java:74)
    at org.jvnet.hk2.internal.MethodInterceptorInvocationHandler.invoke(MethodInterceptorInvocationHandler.java:62)
    at com.sun.proxy.$Proxy239.getAbsolutePathBuilder(Unknown Source)
    at com.services.bookrestservice.rest.RestBookService.createBook(RestBookService.java:44)

[还有另一个与此类似的问题,但我做了与答案中给出的完全相同的事情,但我仍然得到了例外。另外,我已经浏览了https://java.net/jira/browse/JERSEY-2241但它似乎处于解决状态,分辨率无法重现。]

有人能帮帮我吗。

编辑1

正如@HankCa 所建议的,我已从无状态注释更改为 RequestScoped 注释。它现在抛出以下异常。

'javax.persistence.TransactionRequiredException
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper.doTxRequiredCheck(EntityManagerWrapper.java:161)
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper.doTransactionScopedTxCheck(EntityManagerWrapper.java:151)
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper.persist(EntityManagerWrapper.java:281)
    at com.services.bookrestservice.rest.RestBookService.createBook(RestBookService.java:44)
' 

不知道为什么会出现这个异常,因为它已经在持久化上下文中。

编辑2

@HankCa 建议我进行以下更改。

已移除

@Context
protected UriInfo uriInfo;

并将方法签名更新为

@POST
public Response createBook(Book book, @Context UriInfo uriInfo) {

该服务按预期工作。感谢汉克卡的帮助。

4

1 回答 1

0

是的,我盯着这个看太久了,我的解决方案就像你在Why is my Jersey JAX-RS server throwing a IllegalStateException about not being in RequestScope? . 这是一年前的事了,我还没有再打它(虽然我已经离开 EJB 领域有一段时间了)所以我会尽力而为。

具体来说,我会制作这些模组:

  • 添加@RequestScoped
  • 将 放入@Context UriInfo uriInfo方法或类中。最后,我似乎采用了如下方法:

这是代码(这是将列表与代码分开的一行,因此代码显示为代码!)

@Path("/user")
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({ MediaType.APPLICATION_JSON })
@RequestScoped
public class UserResource {    
    ...
    @PermitAll
    @POST
    public Response signupUser(CreateUserRequest request, @Context UriInfo uriInfo) {
        AuthenticatedUserToken token = userService.createUser(request, Role.authenticated);
        verificationTokenService.sendEmailRegistrationToken(token.getUserId());
        URI location = uriInfo.getAbsolutePathBuilder().path(token.getUserId()).build();
        return Response.created(location).entity(token).build();
    }

我希望这会有所帮助!

干杯,

bbos

于 2014-12-09T11:07:46.790 回答