Jersey POST 端点在 Websphere 7 上失败

Jersey POST endpoints failing on Websphere 7

我正在使用 Jackson 作为 JSON 提供商将 Jersey 2.6 应用程序部署到 Websphere 7。出于某种原因,只有我定义为 POST 的端点失败了。我所有的 GET 都工作正常并返回正确的 JSON.

这是一个示例端点:

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public void sendEmail (final Email email) {

    logger.info("Sending email {}", email);
    boolean sent = emailService.send(email);

    if (!sent) {
        throw new WebApplicationException(400);
    }
}

下面是 Email 的样子:

@XmlRootElement
public class Email {

    private List<String> recipients;

    private String from;
    private String subject;

    private String body;

    public Email() {

    }

    public Email(List<String> recipients, String from, String subject,
            String body) {

        this.recipients = recipients;
        this.from = from;
        this.subject = subject;
        this.body = body;
    }

    // getters / setters....
}

我发送的每个 POST 都不会成为端点,我在我的 Websphere SystemOut.log 文件中看到了这一点。我狂热地在其他日志文件中搜索其他日志语句,以寻找问题所在的提示,但这就是我能找到的所有内容,而且毫无帮助。任何援助将不胜感激。即使有人可以指出一些隐藏在安装内部的仅 Websphere 日志文件或其他东西:

00000030 webapp        E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E: [Servlet Error]-[Jersey Web Application]: com.ibm.ws.webcontainer.webapp.WebAppErrorReport: Internal Server Error
        at com.ibm.ws.webcontainer.webapp.WebAppDispatcherContext.sendError(WebAppDispatcherContext.java:637)
        at com.ibm.ws.webcontainer.srt.SRTServletResponse.sendError(SRTServletResponse.java:1189)
        at org.glassfish.jersey.servlet.internal.ResponseWriter.commit(ResponseWriter.java:194)
        at org.glassfish.jersey.server.ContainerResponse.close(ContainerResponse.java:412)
        at org.glassfish.jersey.server.ServerRuntime$Responder.release(ServerRuntime.java:667)
        at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:438)
        at org.glassfish.jersey.server.ServerRuntime.run(ServerRuntime.java:265)
        at org.glassfish.jersey.internal.Errors.call(Errors.java:271)
        at org.glassfish.jersey.internal.Errors.call(Errors.java:267)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:319)
        at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:236)
        at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1028)
        at 
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:219)
        at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1661)
        at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:944)
        at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:507)
        at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:181)
        at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3954)
        at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:276)
        at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:945)
        at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1592)
        at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:191)
        at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:453)
        at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:515)
        at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:306)
        at com.ibm.ws.http.channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:84)
        at com.ibm.ws.ssl.channel.impl.SSLReadServiceContext$SSLReadCompletedCallback.complete(SSLReadServiceContext.java:1819)
        at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:175)
        at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
        at com.ibm.io.async.AsyncChannelFuture.run(AsyncChannelFuture.java:205)
        at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1660)org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:373)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)

因此,感谢 peeskillet 的想法,我在 Jersey 创建了一个 ExceptionMapper,它实现了 ThrowableExceptionMapper,希望它能指出我的错误:

@Provider
public class MyExceptionMapper implements
        ExceptionMapper<Throwable> {

    @Override
    public Response toResponse(Throwable ex) {

        System.out.println(ex);
        return Response.status(500).build();
    }
}

事实证明它确实做到了。我的错误是我在发布的 类 中没有无参数构造函数:

Caused by: com.owlike.genson.JsonBindingException: No constructor has been found for type class com.model.User
        at com.owlike.genson.reflect.BeanDescriptor.deserialize(BeanDescriptor.java:96)
        at com.owlike.genson.convert.BeanViewConverter.deserialize(BeanViewConverter.java:105)
        at com.owlike.genson.convert.NullConverter$NullConverterWrapper.deserialize(NullConverter.java:57)
        at com.owlike.genson.convert.CircularClassReferenceConverterFactory$CircularConverter.deserialize(CircularClassReferenceConverterFactory.java:31)
        at com.owlike.genson.reflect.PropertyMutator.deserialize(PropertyMutator.java:30)

我认为这不重要,因为这在本地对我有用。当我们部署到 Websphere 7 集群时,我只看到了这个错误。无论如何,这就是解决我的问题的方法。