Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8439817
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T08:06:29+00:00 2026-06-10T08:06:29+00:00

I am writing a RESTful web service using Java and Jersey, where the service

  • 0

I am writing a RESTful web service using Java and Jersey, where the service will accept either XML or JSON inputs. Jackson is used as the JSON deserializer, and integrated into the Jersey config.

One of the endpoints is a POST request to a URL, where the content can be one of several different Java classes, and there is a common base class. These classes – with XML annotations – are:

@XmlRootElement(name = "action")
@XmlAccessorType(XmlAccessType.NONE)
@XmlSeeAlso({ FirstAction.class, SecondAction.class, ThirdAction.class })
public abstract class BaseAction {
}

@XmlRootElement(name = "first-action")
@XmlAccessorType(XmlAccessType.NONE)
public class FirstAction extends BaseAction implements Serializable {
}

// Likewise for SecondAction, ThirdAction

In my resource I can declare a method like:

@POST
@Path("/{id}/action")
public Response invokeAction(@PathParam("id") String id, BaseAction action) {...}

Then I can POST an XML fragment that looks like <firstAction/> and my method will be invoked with a FirstAction instance. So far so good.

Where I’m struggling is getting the JSON deserialization to work as seamlessly as the XML deserialization. Where the @XmlSeeAlso annotation was critical to get the XML deserialization working properly, it seemed that the equivalent for JSON was @JsonSubTypes. So I annotated the classes like this:

// XML annotations removed for brevity, but they are present as in the previous code snippet
@JsonSubTypes({ @JsonSubTypes.Type(name = "first-action", value = FirstAction.class),
    @JsonSubTypes.Type(name = "second-action", value = SecondAction.class),
    @JsonSubTypes.Type(name = "third-action", value = ThirdAction.class) })
public abstract class BaseAction {
}

@JsonRootName("first-action")
public class FirstAction extends BaseAction implements Serializable {
}

// Likewise for SecondAction, ThirdAction

I then feed it my test input: { "first-action": null } but all I can get is:

“org.codehaus.jackson.map.JsonMappingException: Root name ‘first-action’ does not match expected (‘action’) for type [simple type, class com.alu.openstack.domain.compute.server.actions.BaseAction]”

Unfortunately since I’m trying to be compatible with someone else’s API I can’t change my sample input – { "first-action": null } has to work, and deliver to my method an object of class FirstAction. (The action doesn’t have any fields, which is why null shouldn’t be a problem – it’s the type of the class that’s important).

What’s the correct way to have the JSON deserialization work in the same way as the XML deserialization already is?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T08:06:31+00:00Added an answer on June 10, 2026 at 8:06 am

    I investigated the use of @JsonTypeInfo but ran into problems because I could not alter the input format. The parser absolutely had to be able to handle input { "first-action":null }. This ruled out the possibility of adding an @type or @class property. Using a wrapper object may have worked, but it choked on the null payload.

    A crucial point was that I was using the UNWRAP_ROOT_PROPERTY configuration option. Jackson was absolutely insisting on finding an action property and I could not get it to consider anything else. So, I had to selectively disable UNWRAP_ROOT_PROPERTY for certain domain objects, so that Jackson would be open to parsing alternatives. I modified the project’s ContextResolver.getContext(…) implementation to check for a @JsonRootName annotation – since this only has meaning if wrapping is enabled, I used the presence of this annotation to determine whether to return an object mapper configured with root property wrapping on, or off.

    At this stage, I might have been able to use @JsonTypeInfo(include=JsonTypeInfo.As.WRAPPER_OBJECT, ...), except for the issue with the null payload mentioned above (this is used to indicate that the child object has no properties – if the spec I was working from had given an empty object {} instead then there would not be a problem). So to proceed I needed a custom type resolver.

    I created a new class that extended org.codehaus.jackson.map.TypeDeserializer, with the purpose that whenever Jackson is called to deserialize a BaseAction instance, it will call this custom deserializer. The deserializer will be given a subtypes array, which for BaseAction maps first-action, second-action, etc. to FirstAction.class, etc. The deserializer reads the input stream for the field name, then matches the name to a class. If the next token is an object, then it finds and delegates to the appropriate deserializer for that class, or if it is null it finds the no-args constructor and invokes it to get an object.

    A class that implements org.codehaus.jackson.map.jsontype.TypeResolverBuilder is needed that can build an instance of this previous class, and then the TypeResolverBuilder is given as a @JsonTypeResolver annotation on the BaseAction class.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am writing a RESTful web service using JAXB and Spring MVC. In my
I writing a small restful web service using Zend_Framework. I want to support the
I'm writing some JUnit-based integration tests for a RESTful web service using JerseyTest. The
I am writing a RESTful web service using ASP.NET MVC 3. I am using
I'm writing an iPhone app that interacts with a RESTful web service, and I
I am writing a Spring Restful webservices application using Spring MVC. I have used
I am writing a RESTful web service where in I want to return a
I have a RESTful web service running on Jersey (GlassFish 3.1.1). This one's a
I am writing an Android application that interfaces with a RESTful service. This web
I am in the process of writing a JSON based web service. The service

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.