Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey 2 InjectLink is ignored

I'm creating a new Jersey 2.21, Jackson 2.6.1 REST server (I tried with Jersey 2.19 and Jackson 2.5.3 as well) and a want to use @InjectLink to provide HATEOAS links (like 'self') for my callers. The most basic app (taken from Jersey doc and Jersey sample apps) isn't working, and I can't figure out why.

I started by taking the basic Widgets class from the Jersey doc, but the JSON or XML returned is just an empty structure.

XML:

<Widgets/>

JSON:

{}

Widgets.java

package org.glassfish.jersey.examples.linking;

import java.net.URI;
import java.util.List;

import javax.ws.rs.core.Link;
import javax.xml.bind.annotation.XmlRootElement;

import org.glassfish.jersey.linking.InjectLink;
import org.glassfish.jersey.linking.InjectLinks;

@XmlRootElement()
public class Widgets {
    @InjectLink(resource=WidgetsResource.class)
    URI u;

    @InjectLinks({@InjectLink(resource=WidgetsResource.class, rel = "self")})
    List<Link> links;

    public Widgets() {}
}

I put a breakpoint in the resource code and examined the object being returned. it.links and it.u are both null. There's nothing injected.

WidgetsResource.java

@Path("widgets")
public class WidgetsResource {
    @GET
    public Widgets get() {
        Widgets it = new Widgets();
        return it;
    }
}

Maven dependencies:

<dependencies>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>${jersey.version}</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.ext</groupId>
        <artifactId>jersey-declarative-linking</artifactId>
        <version>${jersey.version}</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.el</artifactId>
        <version>2.2.4</version>
    </dependency>
    <dependency>
        <groupId>javax.el</groupId>
        <artifactId>javax.el-api</artifactId>
        <version>2.2.4</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-joda</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-xml-provider</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-yaml-provider</artifactId>
        <version>${jackson.version}</version>
    </dependency>
</dependencies>

<properties>
    <jersey.version>2.21</jersey.version>
    <jackson.version>2.6.1</jackson.version>
</properties>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    id="WebApp_ID" version="3.1">
    <display-name>Server</display-name>
    <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>org.glassfish.jersey.examples.linking.Server</param-value>
    </init-param>
    </servlet>

    <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/v1/*</url-pattern>
    </servlet-mapping>

</web-app>

The application object:

package org.glassfish.jersey.examples.linking;

import org.glassfish.jersey.linking.DeclarativeLinkingFeature;
import org.glassfish.jersey.server.ResourceConfig;

public class Server extends ResourceConfig {
    public Server() {
        packages("org.glassfish.jersey.examples.linking",
            "com.fasterxml.jackson.jaxrs")
        .register(DeclarativeLinkingFeature.class);
    }
}

It appears that the @InjectLink(s) annotations are simply being ignored. There must be some magic setting I'm missing, but I've done everything the Jersey doc says to do.

I tried with both Servlet 2.x (shown) and Servlet 3.x (using @ApplicationPath) and that made no difference.

Some of you will notice from my package names that I also tried the slightly more advanced, but no more successful, Jersey declarative linking example (https://github.com/jersey/jersey/tree/master/examples/declarative-linking). Some of the basic fields were returned, but all of the injected links were missing or null.

.../Server/rest/v1/items/1 produced:

{
  "id": "1",
  "nextId": "2",
  "prevId": "0",
  "prev": true,
  "next": true
}

FYI - I'm running Java 1.8.0_60, Eclipse Mars, and Tomcat 8.0.26. There are no errors, no warnings and no runtime messages. I'm completely stumped. Anyone have any pointers???

like image 849
snojcb Avatar asked Aug 31 '15 02:08

snojcb


1 Answers

I have added the following to my servlet config:

`<init-param>
        <param-name>jersey.config.server.provider.classnames</param-name>
        <param-value>
            org.glassfish.jersey.linking.DeclarativeLinkingFeature
        </param-value>
    </init-param>'

and the links were rendered in the json response.

like image 130
Alex Nago Avatar answered Sep 20 '22 08:09

Alex Nago