1

我正在尝试让 Jersey 2.3 + Moxy 与我的自定义对象一起工作。当我从这些对象生成 JSON 时一切正常,但是当我想通过 POST 使用它们时拒绝工作。先上代码:

自定义对象:

@XmlRootElement
public class ContentAction extends Action {

    private String contentType;
    private Integer contentLength;

    public ContentAction() {
        setType(ActionType.CONTENT);
    }

    public String getContentType() {
        return contentType;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    public Integer getContentLength() {
        return contentLength;
    }

    public void setContentLength(Integer contentLength) {
        this.contentLength = contentLength;
    }
}

资源片段(路径在类上声明):

@POST
@Produces(JsonHelper.JSON_UTF8)
public Action saveAction(@QueryParam("action") ContentAction action) throws IOException {
    ActionEntity entity = actionConverter.toEntity(action);
    entity.setBeacon(beaconService.findById(action.getBeacon().getId()));

    return actionConverter.convert(actionService.save(entity));
}

API调用者(负责发送请求的类):

URI uri = buildUri(path, params);

HttpPost httpPost = new HttpPost(uri);
httpClient.execute(httpPost);

buildUri 只是从地址和参数创建 URI 操作转换为 JSON 如下:mapper.writeValueAsString(action)

还有一个例外:

org.glassfish.jersey.server.internal.inject.ExtractorException: Error unmarshalling JAXB object of type "class com.kontakt.platform.apicommon.model.ContentAction".
    at org.glassfish.jersey.server.internal.inject.JaxbStringReaderProvider$RootElementProvider$1.fromString(JaxbStringReaderProvider.java:195)
    at org.glassfish.jersey.server.internal.inject.AbstractParamValueExtractor.convert(AbstractParamValueExtractor.java:138)
    at org.glassfish.jersey.server.internal.inject.AbstractParamValueExtractor.fromString(AbstractParamValueExtractor.java:129)
    at org.glassfish.jersey.server.internal.inject.SingleValueExtractor.extract(SingleValueExtractor.java:83)
    at org.glassfish.jersey.server.internal.inject.QueryParamValueFactoryProvider$QueryParamValueFactory.provide(QueryParamValueFactoryProvider.java:88)
    at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:81)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:121)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:195)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:353)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:343)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
    at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.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:318)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:235)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:983)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:359)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1008)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)
Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.]
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:335)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:512)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:209)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:175)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:140)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:123)
    at org.glassfish.jersey.server.internal.inject.JaxbStringReaderProvider$RootElementProvider$1.fromString(JaxbStringReaderProvider.java:190)
    ... 40 more
Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:441)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368)
    at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1388)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:998)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:607)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:116)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:489)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:835)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1210)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:568)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:203)
    ... 44 more

当我删除 @XmlRootElement 时,Jersey 尝试使用字符串参数(如果添加)从构造函数创建对象 = 不自动创建 bean。

我已经坚持了两天了,我会非常感谢任何帮助。

4

3 回答 3

0

我认为问题在于您需要设置内容类型。由于您没有指定内容类型,因此 jersey 假设它正在接收 xml,但实际上是 json。错误消息来自 jaxb 试图读取 xml 标头并查找无效字符。尝试使用 jersey 客户端而不是 http 帖子。此外,我认为您可能会更改您的 @Produces(MediaType.APPLICATION_JSON) 以保持一致性。

@Produces(MediaType.APPLICATION_JSON)

示例邮政编码

最重要的部分是我正在设置我要发布的类型 (type(MediaType.Application_JSON))。

WebResource webResource = createRestClient(true).resource(
             REST_BASE_PATH + "/service");

ClientResponse response = webResource.type(MediaType.APPLICATION_JSON)
            .accept(MediaType.APPLICATION_JSON)
            .post(ClientResponse.class, contentActionObject);

Assert.assertTrue(response.getStatus() == 200);

如果您确实需要使用 HttpPost 对象,那么应该有一个配置选项来设置 http 标头。我已经使用 HttpUrlConnection 完成了这项工作。您必须将内容类型设置为 application/json 而不是 xml。

HttpURLConnection connection = null;
connection = (HttpURLConnection) new URL(requestUrl).openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/xml");
connection.setRequestProperty("Content-Type", "application/xml");
于 2013-10-11T16:45:50.073 回答
0

我知道这有点老了,但我在使用 Jersey 2.3 + Moxy 时遇到了基本相同的问题。相同的场景和相同的异常正在发生。唯一的区别是我的 POST 方法注释为:

@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)

我确实发现,当我在请求正文中传递相同的 JSON 表示而不是作为查询参数时,它被成功解组。这需要将您的 POST 方法声明更改为:

public Action saveAction(ContentAction action)

不确定这是否适合您。如果你找到了一个解决方案,我很想听听它是什么。

于 2013-10-31T20:08:19.570 回答
0

EclipseLink MOXy将被 Jersey 选为 JSON 绑定提供者,用于遵循以下模式的媒体类型。

  • */json(即应用程序/json和文本/json)
  • / +json

根据您的例外情况,似乎媒体类型已表示为JsonHelper.JSON_UTF8与此模式不匹配。

于 2013-10-11T18:11:49.740 回答