3

I'm having a bad time trying to solve this problem with JAX-RS and I believe that it has something to do with the marshalling/unmarshalling process (that I don't know very much about, I assume), and I want to recreate this:

  1. The REST endpoint to make a post is /rest/register so my services are defined like this:

    @ApplicationPath("/rest")
    public interface RestRegistration {
        @POST
        @Path("/register")
        @Produces(MediaType.APPLICATION_JSON)
        @Consumes(MediaType.APPLICATION_JSON)
        String register(UsernameRegistration usernameAccess, String network) throws RegistrationException;
    
        @POST
        @Path("/register")
        @Produces(MediaType.APPLICATION_JSON)
        @Consumes(MediaType.APPLICATION_JSON)
        String register(EmailRegistration emailAccess, String network) throws RegistrationException;
    }
    
    public class RestRegistrationImpl implements RestRegistration {
        public String register(UsernameRegistration usernameAccess, String network) throws RegistrationException {
            return "StackOverflow example: username=" + usernameAccess.getUser + ", network="+network;
        }
    
        public String register(EmailRegistration emailAccess, String network) throws RegistrationException{
            return "StackOverflow example: email=" + emailAccess.getEmail + ", network="+network;
        }
    
    }
    
  2. It should receive at least two different JSON messages:

    { "usernameAccess" : { "user" : "AUser", "password" : "APass"}, "network" : "Facebook"}
    

    or...

    { "emailAccess" : { "email" : "AnEmail@domain.com", "password" : "APass"}, "network" : "LinkedIn"}
    
  3. The classes are represented by

    public abstract class Registration {
        private Long _id; 
        private String _password; 
        private String _network;
        // usual getters and setters...
    }
    
    public class UsernameRegistration extends Registration {
        private String _user; 
        // usual getters and setters...
    }
    
    public class EmailRegistration extends Registration {
        private String _email; 
        // usual getters and setters...
    }
    

So, my problem now is:

  1. With this implemenationt I keep receiving an HTTP 500 error.
  2. And I'm not sure on how to separate the two JSON nodes: usernameAccess/emailAccess and network.
  3. Also: is there any way on how can I improve using the fact that both classes "UsernameRegistration" and "EmailRegistration" inherit from the same "Registration", making the classes on the "upper" 1. look more elegant?

Is there any bibliography, article or howto someone can hand me over? Thanks in advance! :)

Hugo Tavares
  • 314
  • 4
  • 14
  • Update: Regarding the question 2. of my problems, I just found out that I can't send two different objects on a single POST the way I wanted to. The solution/s can be found here: http://stackoverflow.com/questions/5553218/jax-rs-post-multiple-objects – Hugo Tavares Nov 28 '14 at 16:08
  • 2
    Can you post the error you're receiving and any applicable stacktraces from the server? What JSON provider are you using? – John Ament Nov 28 '14 at 16:44
  • @JohnAment: I'm using Jackson. The error is something like: (Exception) Caused by: ...jackson.map.JsonMappingException: Can not construct instance of ...Registration, problem: abstract types can only be instantiated with additional type information. (Thank you!) ;) – Hugo Tavares Dec 01 '14 at 12:51

1 Answers1

5

In Jackson, your inheritance structure needs to include @JsonTypeInfo and @JsonSubTypes with a @JsonSubTypes.Type for each implementation that you're registering. JsonTypeInfo will require a unique identifier to differentiate the types.

John Ament
  • 11,595
  • 1
  • 36
  • 45
  • I've found it out meanwhile here http://wiki.fasterxml.com/JacksonPolymorphicDeserialization (I wasn't sure if it would be the same problem that was being solved, but after all with that solution I could managed it, even with sub-classes of UserRegistration/EmailRegistration). Thank you again, John. – Hugo Tavares Dec 02 '14 at 12:31
  • is there a way to do this without annotations? because i'm relying on models from a dependency for which i don't have the sources of – xxfast Jan 10 '18 at 02:47
  • You could do it as a custom JAX-RS `MessageBodyReader`/`MessageBodyWriter`, however I would be concerned with trying to use external models this way. I've found it to be a bit of an antipattern, and instead recommend people to come up with their own model representations that are based on your own domain. This way, you only read the attributes you care about and encapsulate a bit better. – John Ament Jan 10 '18 at 03:30