How to marshal JAXBElement into Response?
Asked Answered
F

1

0

My CXF provided REST services usually return javax.ws.rs.core.Response for the usual reason, to encapsulate the result entity data marshaled as XML and a return code:

@GET
@Path("/getPojo")
@Produces("application/xml")
public Response getPojo() {

    SomePojo resultObj = ...;

    Response result = Response.status(200).entity(resultObj).build();

    return result;
}

which requires that SomePojo contains proper annotations:

@XmlRootElement(name = "somePojo")
@XmlAccessorType(XmlAccessType.FIELD)
public class SomePojo implements Serializable {
    ...
}

However, now I am facing a scenario where the annotation convention does not work for me and I have to build my own JAXBElement. How can I include the custom-marshaled JAXBElement in the Response instead of using Response.ResponseBuilder.entity(resultObj), which relies on the annotation configuration? I am marshaling something similar to what is explained here but he's just printing the marshaled XML into the console and I would like to print it into the Response (and not just HttpResponse out).

Fatuity answered 12/1, 2017 at 20:59 Comment(2)
Do you want to marshall yourself and return directly the XML, or do you want to configure CXF to apply a custom marshaller your result objects?Mullane
I'm not 100% sure I understand the question but my gut feeling is to go with the former, marshal myself BUT I still would like to use Response because I want to encapsulate both a return code + objectFatuity
M
1

You can marshall the xml using your custom marshaller and set the resultant XML in the entity of the Response, as String or InputStream

@GET
@Path("/getXML")
@Produces("application/xml")
public Response getXML() {

    String xml = // custom marshall

    Response result = Response.
           status(200).
           entity(xml).
           type("application/xml").
           build();

    return result;
}
Mullane answered 12/1, 2017 at 21:44 Comment(3)
why is type(application/xml") necessary when we declare it in the annotation ?Fatuity
You are building directly the response, not the CFX Response wrapper, so I am not sure whether in this case CXF will update the header properly. To be sure i would have to review the specification ( or test it)Mullane
Reviewed. In this case it is not needed A method for which there is a single-valued Produces is not required to set the media type of representations that it produces: the container will use the value of the Produces when sending a response. see docs.oracle.com/javaee/6/api/javax/ws/rs/Produces.htmlMullane

© 2022 - 2024 — McMap. All rights reserved.