36

I have some experience using Jersey < 2.0. Now I am trying to build a war application to provide a JSON Webservice API.

I am now struggling for a considerable amount of time trying to configure Moxy and it seams to be way more complicated than what was adding

    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

to your web.xml back in Jersey < 2.0.

Is there some possibility to just say "please add json support"?

Currently I just get a lot of Internal Server Error errors without any log entries on the server and just think "I have to do something totally wrong, this can't be so hard"

Can anyone give me a hint?

Frederick Roth
  • 2,748
  • 4
  • 28
  • 42
  • Here's Jersey example for working with MOXy & JSON: https://github.com/jersey/jersey/tree/master/examples/json-moxy Here's the Jersey User Guide that describes how to configure Jersey & MOXy to support JSON: https://jersey.github.io/documentation/latest/media.html#json.moxy – Marek Potociar Jul 12 '13 at 12:53

6 Answers6

46

Please use the below dependency which will do it automatically for you.

 <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>2.2.3</version>
   </dependency>
Kalaiselvam M
  • 1,050
  • 1
  • 16
  • 25
  • This is the easiest way to do it. AFAIK, Jackson is the defacto industry standard for JSON web-service output. – devdanke Feb 24 '14 at 05:42
  • Googling this dependency leads to a deprecated github repo, which itself leads to an updated github repo, with a different dependency name: https://github.com/FasterXML/jackson-jaxrs-providers – Noam Ben Ari Apr 24 '14 at 14:30
  • This is the right answer! "jersey-media-json-jackson" artifact includes jackskon 1.9 jar libraries by mistake! – Stefan Dec 15 '14 at 14:28
  • I also had issues with MOXy (which requires my beans served as JSON to have empty constructors, seemingly because of its internal usage of JAXB). Removing MOXy as a dependency and adding this instead solved my issue. – Zero3 Apr 22 '15 at 08:48
13

If you want to define it in your web.xml file then:

JACKSON:

<init-param>
  <param-name>jersey.config.server.provider.classnames</param-name>
  <param-value>org.glassfish.jersey.jackson.JacksonFeature</param-value>
</init-param>

MOXY

<init-param>
  <param-name>jersey.config.server.provider.classnames</param-name>
  <param-value>org.glassfish.jersey.moxy.json.MoxyFeature</param-value>
</init-param>

And if using maven add the following dependency to your pom file

JACKSON

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>your jersey version</version>
</dependency>

MOXY

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-moxy</artifactId>
    <version>your jersey version</version>
</dependency>
ibai
  • 1,143
  • 1
  • 17
  • 28
  • Thank you! I can't understand why this was not in the jersey json migration section of their docs: https://jersey.java.net/documentation/latest/migration.html#mig-1-x-json – Jim Ford May 23 '16 at 14:24
  • How does adding just JSONFeature class work? How does jersey figure if xml annotations on the pojo class should be read or not without specifying the JaxbAnnotationInterpreter? – Andy Dufresne Jul 10 '17 at 11:46
7

You can configure EclipseLink MOXy as the JSON-binding provider by configuring the MOXyJsonProvider class through a JAX-RS Application class.

Example #1

package org.example;

import java.util.*;
import javax.ws.rs.core.Application;
import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;

public class CustomerApplication  extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        HashSet<Class<?>> set = new HashSet<Class<?>>(2);
        set.add(MOXyJsonProvider.class);
        set.add(CustomerService.class);
        return set;
    }

}

Example #2

package org.example;

import java.util.*;
import javax.ws.rs.core.Application;
import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;

public class CustomerApplication  extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        HashSet<Class<?>> set = new HashSet<Class<?>>(1);
        set.add(ExampleService.class);
        return set;
    }

    @Override
    public Set<Object> getSingletons() {
        MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();

        moxyJsonProvider.setAttributePrefix("@");
        moxyJsonProvider.setFormattedOutput(true);
        moxyJsonProvider.setIncludeRoot(true);
        moxyJsonProvider.setMarshalEmptyCollections(false);
        moxyJsonProvider.setValueWrapper("$");

        Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1);
        namespacePrefixMapper.put("http://www.example.org/customer", "cust");
        moxyJsonProvider.setNamespacePrefixMapper(namespacePrefixMapper);
        moxyJsonProvider.setNamespaceSeparator(':');

        HashSet<Object> set = new HashSet<Object>(1);
        set.add(moxyJsonProvider);
        return set;
    }

} 

For More Information

bdoughan
  • 147,609
  • 23
  • 300
  • 400
3

ACtually, it just worked for me, with the PojoMappingFeature param omitted.

Going to:

http://localhost:8080/webapi/myresource/complexObject/foo

yields this json:

{"name":"foo","value1":1374185178829,"value2":42}

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
     see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.example</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/webapi/*</url-pattern>
    </servlet-mapping>
</web-app>

entry point:

package com.example;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 * Root resource (exposed at "myresource" path)
 */
@Path("myresource")
public class MyResource {

    /**
     * Method handling HTTP GET requests. The returned object will be sent
     * to the client as "text/plain" media type.
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getIt() {
        return "Got it!";
    }

    @Path( "complexObject/{name}" )
    @GET
    @Produces( { MediaType.APPLICATION_JSON } )
    public ComplexObject complexObject( @PathParam( "name" ) String name ) {
        return new ComplexObject(name, System.currentTimeMillis(), 42L);
    }
}

bean to jsonize:

package com.example;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 * Root resource (exposed at "myresource" path)
 */
@Path("myresource")
public class MyResource {

    /**
     * Method handling HTTP GET requests. The returned object will be sent
     * to the client as "text/plain" media type.
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getIt() {
        return "Got it!";
    }

    @Path( "complexObject/{name}" )
    @GET
    @Produces( { MediaType.APPLICATION_JSON } )
    public ComplexObject complexObject( @PathParam( "name" ) String name ) {
        return new ComplexObject(name, System.currentTimeMillis(), 42L);
    }
}
marathon
  • 7,881
  • 17
  • 74
  • 137
2

Found this as well working, and was the easiest in resolving the problem (AFAIT)

Include the below dependency in your pom.xml / include the respective JAR file in lib path

<dependency>
    <groupId>com.owlike</groupId>
    <artifactId>genson</artifactId>
    <version>0.99</version>
</dependency

Link here

aksappy
  • 3,400
  • 3
  • 23
  • 49
0

Just use @XmlElement in place of @XmlAttribute (only attribute receives @ prefix, possibly restart your appserver for changed effect!)