Search code examples
javajaxbjerseymoxy

Jersey unable to unmarshal object with MOXy (Content is not allowed in prolog)


I have the following method implemented using JAX-RS 2.0 (Jersey):

@PUT
@Path("container/{containername}/catalog")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response updateCatalog(@PathParam("containername") String containerName, 
        @FormDataParam("catalog") SIRFCatalog catalog) throws IOException, URISyntaxException {
    log.info("Unmarshalling config...");
    SIRFConfiguration config = new SIRFConfigurationUnmarshaller().
            unmarshalConfig(new String(Files.readAllBytes(Paths.get(
            SIRFConfiguration.SIRF_DEFAULT_DIRECTORY + "conf.json"))));
    log.info("Creating strategy...");
    StorageContainerStrategy strat = AbstractStrategyFactory.createStrategy(config);
    log.info("Pushing catalog...");
    strat.pushCatalog(catalog, containerName);

    log.info("Sending response...");
    return Response.ok(new URI("sirf/container/" + containerName + "/catalog")).build();
}

I am using Eclipse MOXy and the War file has the jaxb.properties file in the same directory as the compiled class. The contents of the properties file are:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

When I sent an XML file containing a SIRFCatalog everything runs as expected:

curl -i -X PUT -H "Content-Type:multipart/form-data" -F [email protected] http://$OPENSIRF_IP:$OPENSIRF_PORT/sirf/container/philContainer/catalog
HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: application/json
Content-Length: 48
Date: Sat, 10 Sep 2016 18:30:30 GMT

{"value":"sirf/container/philContainer/catalog"}

However, when I send the very same contents in JSON (and I know they are the same because I marshalled the same object to XML and JSON and saved to a.xml and a.json) I get an HTTP 400:

curl -i -X PUT -H "Content-Type:multipart/form-data" -F [email protected] http://$OPENSIRF_IP:$OPENSIRF_PORT/sirf/container/philContainer/catalog
HTTP/1.1 100 Continue

HTTP/1.1 400 Bad Request
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Language: en
Content-Length: 1033
Date: Sat, 10 Sep 2016 18:30:38 GMT
Connection: close

<!DOCTYPE html><html><head><title>Apache Tomcat/8.0.36 - Error report</title><style type="text/css">H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}.line {height: 1px; background-color: #525D76; border: none;}</style> </head><body><h1>HTTP Status 400 - Bad Request</h1><div class="line"></div><p><b>type</b> Status report</p><p><b>message</b> <u>Bad Request</u></p><p><b>description</b> <u>The request sent by the client was syntactically incorrect.</u></p><hr class="line"><h3>Apache Tomcat/8.0.36</h3></body></html>

I suspect that my server is actually using Vanilla JAXB instead of MOXy, but have no idea how to debug that! The tomcat8 logs say Content not allowed in prolog:

10-Sep-2016 18:30:36.902 INFO [http-nio-8080-exec-21] org.glassfish.jersey.filter.LoggingFilter.log 2 * Server has received a request on thread http-nio-8080-exec-21
2 > PUT http://200.144.189.109:8088/sirf/container/philContainer/catalog
2 > accept: */*
2 > content-length: 1755
2 > content-type: multipart/form-data; boundary=----------------------------bb3a9e312931
2 > expect: 100-continue
2 > host: 200.144.189.109:8088
2 > user-agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2

[Fatal Error] :1:1: Content is not allowed in prolog.
10-Sep-2016 18:30:38.386 INFO [http-nio-8080-exec-21] org.glassfish.jersey.filter.LoggingFilter.log 2 * Server responded with a response on thread http-nio-8080-exec-21
2 < 400

Any thoughts?


Solution

  • However, when I send the very same contents in JSON (and I know they are the same because I marshalled the same object to XML and JSON and saved to a.xml and a.json) I get an HTTP 400:

    I suspect the generated json has root node (like in XML) and so you will have to instruct MOxy to not use root node. Please check this link and link as explained by Blaise.

    UPDATE: And yes you will need to specify the type of data in the cURL command as below:

    -F "[email protected];type=application/json"