Reputation: 31
I am desperately looking for a way to make JSON serialization with root element to work on JBoss AS 7.1 with RestEasy and Jettison provider enabled.
Although, according to RestEasy documentation, returning of the JSON root element should work, I never retrieve when requesting a REST servlet.
I use an Object Factory:
@XmlRegistry
public class ObjectFactory {
private final static QName _NotificationList_QNAME = new QName("xxx:xxx:xxx", "notificationList");
public NotificationList createNotificationList() {
return new NotificationList();
}
@XmlElementDecl(namespace = "xxx:xxx:xxx", name = "notificationList")
public JAXBElement<NotificationList> createNotificationList(NotificationList value) {
return new JAXBElement<NotificationList>(_NotificationList_QNAME, NotificationList.class, null, value);
}
}
With the following XML object:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "NotificationList", namespace = "xxx:xxx:xxx:xxx", propOrder = {
"any"
})
@XmlRootElement (name = "notificationList" )
public class NotificationList {
@XmlAnyElement(lax = true)
protected List<Object> any;
@XmlElement (name="notificationList")
public List<Object> getAny() {
if (any == null) {
any = new ArrayList<Object>();
}
return this.any;
}
}
I expect a notification list to be returned with root element "notificationList" but I don't get it. I use Jettison provider by default but also switched to Jackson. Both do not work for me.
Maybe it is worth mentioning, the REST method is not returning the object itself but passes a AsynchronousResponse to another object which processes and eventually returen the JSON object bacck to I use AsynchronousResponse when creating the response
Edit: Some more info on the classes actually using NotificationList:
The following REST class consumes a NotificationChannel class (not of interest here) and passes an Asynchronous Response obejct to another classe. This response object eventually returns the NotificationList. In a simplified way, as follows:
@Path("/notificationchannel/v1")
public class NotificationChannelService {
@POST
@Path("/{userid}/channels")
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Mapped(namespaceMap = {
@XmlNsMap(namespace = "XXXX:XXXX:XXXX:XXXX", jsonName = "notificationChannel")
})
public void createNotificationChannel(
final @Suspend(10000) AsynchronousResponse response,
final JAXBElement<NotificationChannel> ncParam,
@PathParam("userid") String userID) {
NotificationManager nMan = new NotificationManager(resp);
}
}
The response is created and returned as follows:
public class NotificationManager {
public NotificationManater(AsynchronousResponse resp){
//dostuff
notificationList = objectFatory.creatNotificationList();
//add notification object (also defined int ObjectFactory)
notificaitonList.addObject(messageNotification)
notificaitonList.addObject(statusNotification)
notificaitonList.addObject(inviteNotification)
//dostuff
resp.setResponse(Response.created(UriBuilder.fromUri(nc.getResourceURL()).build())
.entity(notificationList)
.type(MediaType.APPLICATION_JSON)
.build());
}
}
On client side, i expect the following response:
{"notificationList": {
"inboundMessageNotification": {"inboundMessage": {
"destinationAddress": "tel:+19585550100",
"inboundMMSMessage": {"subject": "Who is RESTing on the beach?"},
"link": {
"href": "http://example.com/exampleAPI/v1/messaging/inbound/subscriptions/sub123",
"rel": "Subscription"
},
"messageId": "msg123",
"resourceURL": "http://example.com/exampleAPI/v1/messaging/inbound/registrations/reg123/messages/msg123 ",
"senderAddress": "tel:+19585550101"
}},
"presenceNotification": {
"callbackData": "1234",
"link": {
"href": "http://example.com/exampleAPI/v1/presence/tel%3A%2B19585550101/subscriptions/presenceSubscriptions/ tel%3A%2B19585550100/sub001",
"rel": "PresenceSubscription"
},
"presence": {"person": {"mood": {"moodValue": "Happy"}}},
"presentityUserId": "tel:+19585550100",
"resourceStatus": "Active"
}
}}
But i do get this (no RootElement name, no notification object name):
{
{
"destinationAddress": "tel:+19585550100",
"inboundMMSMessage": {"subject": "Who is RESTing on the beach?"},
"link": {
"href": "http://example.com/exampleAPI/v1/messaging/inbound/subscriptions/sub123",
"rel": "Subscription"
},
"messageId": "msg123",
"resourceURL": "http://example.com/exampleAPI/v1/messaging/inbound/registrations/reg123/messages/msg123 ",
"senderAddress": "tel:+19585550101"
},
{
"callbackData": "1234",
"link": {
"href": "http://example.com/exampleAPI/v1/presence/tel%3A%2B19585550101/subscriptions/presenceSubscriptions/ tel%3A%2B19585550100/sub001",
"rel": "PresenceSubscription"
},
"presence": {"person": {"mood": {"moodValue": "Happy"}}},
"presentityUserId": "tel:+19585550100",
"resourceStatus": "Active"
}
}
Upvotes: 1
Views: 1762
Reputation: 1091
I faced the exact same issue and the problem is that the json provider based on Jackson (resteasy-jackson-provider) is actually taking over the serialization (due to the implicit module dependency). What I did was to use a specific deployment descriptor META-INF/jboss-deployment-structure.xml with the following content.
<jboss-deployment-structure>
<deployment>
<exclusions>
<module name="org.jboss.resteasy.resteasy-jackson-provider" />
</exclusions>
<dependencies>
<module name="org.jboss.resteasy.resteasy-jettison-provider" />
</dependencies>
</deployment>
</jboss-deployment-structure>
It will force the container to switch to the jettison provider for your application.
Upvotes: 1