Dropwizard/Jersey is giving "Unable to process JSON" message on GET request

14,750

Solution 1

Looks like your json marshaller is not able to marshall google's Optional class. Try to return Company from the controller, and not Optional:

@GET
@Path("/{id}")
@UnitOfWork
public Company getById(@PathParam("id") LongParam id) {
    return companyDAO.findById(id.get()).get();
}

Solution 2

I was getting the error Unable to Process JSON. Troubleshooted more than 4 hours until I found the problem.

The error is caused because of Enum getter.

If you are using Enum fields/getters/setters in your POJO, Jackson will fail to map your JSON to Java Object, and it will crash, leading to the mentioned error.

Share:
14,750
Admin
Author by

Admin

Updated on June 28, 2022

Comments

  • Admin
    Admin almost 2 years

    I'm trying to make my first simple project with Dropwizard. I have a MySQL-database, and the idea is to get the data (companies) from there and represent it as JSON. I have followed the Getting started page by Dropwizard and this tutorial to get connected to database with Hibernate.

    The idea is that URL "/companies" serves all the companies as JSON, and it is working fine.

    URL "/companies/{id}" is supposed to give a single company with given id, but every request gives code 400 and message "Unable to process JSON". The details field in the response says

    "No serializer found for class jersey.repackaged.com.google.common.base.Present and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) )"

    If I give an id of company that does not exist in database, the class in mentioned message changes to

    jersey.repackaged.com.google.common.base.Absent

    The company class is here:

    public class Company {
        @ApiModelProperty(required = true)
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private long id;
    
        @Column(name = "name")
        private String name;
    
        @Column(name = "address")
        private String address;
    
        @Column(name = "zipcode")
        private String zipCode;
    
        @Column(name = "email")
        private String eMail;
    
        @Column(name = "mobile")
        private String mobile;
    
        public Company() {
    
        }
    
        public Company (String name, String address, String zipCode, String eMail, String mobile) {
            this.name = name;
            this.address = address;
            this.zipCode = zipCode;
            this.eMail = eMail;
            this.mobile = mobile;
        }
    
        @JsonProperty
        public long getId() {
            return id;
        }
    
        @JsonProperty
        public void setId(long id) {
            this.id = id;
        }
    
        @JsonProperty
        public String getName() {
            return name;
        }
    
        @JsonProperty
        public void setName(String name) {
            this.name = name;
        }
    
        @JsonProperty
        public String getAddress() {
            return address;
        }
    
        @JsonProperty
        public void setAddress(String address) {
            this.address = address;
        }
    
        @JsonProperty
        public String getZipCode() {
            return zipCode;
        }
    
        @JsonProperty
        public void setZipCode(String zipCode) {
            this.zipCode = zipCode;
        }
    
        @JsonProperty
        public String geteMail() {
            return eMail;
        }
    
        @JsonProperty
        public void seteMail(String eMail) {
            this.eMail = eMail;
        }
    
        @JsonProperty
        public String getMobile() {
            return mobile;
        }
    
        @JsonProperty
        public void setMobile(String mobile) {
            this.mobile = mobile;
        }
    
     }
    

    DAO is here:

    public class CompanyDAO extends AbstractDAO<Company> {
    
        public CompanyDAO(SessionFactory sessionFactory) {
            super(sessionFactory);
        }
        public List<Company> findAll() {
            return list(namedQuery("com.webapp.project.core.Company.findAll"));
        }
    
        public Optional<Company> findById(long id) {
            return Optional.fromNullable(get(id));
        }
    }
    

    Application class:

    public class HelloWorldApplication extends Application<HelloWorldConfiguration> {
        public static void main(String[] args) throws Exception {
            new HelloWorldApplication().run(args);
        }
    
        @Override
        public String getName() {
            return "hello-world";
        }
        /**
         * Hibernate bundle.
         */
        private final HibernateBundle<HelloWorldConfiguration> hibernateBundle
                = new HibernateBundle<HelloWorldConfiguration>(
                        Company.class
                ) {
                    @Override
                    public DataSourceFactory getDataSourceFactory(
                            HelloWorldConfiguration configuration
                    ) {
                        return configuration.getDataSourceFactory();
                    }
                };
    
    
    
        @Override
        public void initialize(Bootstrap<HelloWorldConfiguration> bootstrap) {
            bootstrap.addBundle(new SwaggerBundle<HelloWorldConfiguration>() {
                @Override
                protected SwaggerBundleConfiguration getSwaggerBundleConfiguration(HelloWorldConfiguration sampleConfiguration) {
                    return sampleConfiguration.getSwaggerBundleConfiguration();
                }
            });
            bootstrap.addBundle(hibernateBundle);
        }
    
        @Override
        public void run(HelloWorldConfiguration configuration,
                        Environment environment) {
    
            final CompanyDAO companyDAO = new CompanyDAO(hibernateBundle.getSessionFactory());
            environment.jersey().register(new CompaniesResource(companyDAO));
            environment.jersey().register(new JsonProcessingExceptionMapper(true));
        }
    
    }
    

    Configuration class:

    public class HelloWorldConfiguration extends Configuration {
    
        @Valid
        @NotNull
        private DataSourceFactory database = new DataSourceFactory();
    
        @NotNull
        private SwaggerBundleConfiguration swaggerBundleConfiguration;
    
    
        @JsonProperty("swagger")
        public void setSwaggerBundleConfiguration (SwaggerBundleConfiguration conf) {
            this.swaggerBundleConfiguration = conf;
        }
    
        @JsonProperty("swagger")
        public SwaggerBundleConfiguration getSwaggerBundleConfiguration () {
            return swaggerBundleConfiguration;
        }
    
        @JsonProperty("database")
        public void setDataSourceFactory(DataSourceFactory factory) {
            this.database = factory;
        }
    
        @JsonProperty("database") 
        public DataSourceFactory getDataSourceFactory() {
            return database;
        }
    
    }
    

    Resource class:

    @Path("/companies")
    @Api("Companies")
    @Produces(MediaType.APPLICATION_JSON)
    public class CompaniesResource {
        private CompanyDAO companyDAO;
    
        public CompaniesResource(CompanyDAO companyDAO) {
            this.companyDAO = companyDAO;
        }
    
        @GET
        @ApiOperation(
                value = "Gives list of all companies",
                response = Company.class,
                code = HttpServletResponse.SC_OK
        )
        @UnitOfWork
        public List<Company> findAll () {
            return companyDAO.findAll();
        }
    
        @GET
        @Path("/{id}")
        @UnitOfWork
        public Optional<Company> getById(@PathParam("id") LongParam id) {
            return companyDAO.findById(id.get());
        }
    }
    

    I would be happy for any responses!

  • Admin
    Admin about 8 years
    Thanks for your reply and stopping me from beating my head to wall. I tried like you told and noticed that there was no get()-method for Optional class, which made me realize that I had wrong class imported. I had imported jersey.repackaged.com.google.common.base.Optional, and the correct one was com.google.common.base.Optional.
  • gmaslowski
    gmaslowski about 8 years
    Glad it somehow helped.
  • Admin
    Admin over 2 years
    Not exactly true. You can use @JsonProperty (com.fasterxml.jackson.annotation) on your enums and pass a valid String representation to allow your POJO to have Enum values.