Reputation: 331
I have set up a REST client consuming JSON with Jersey. Firstly according to Baeldung's tutorial with MOXy and secondly according to Vaadin's tutorial with Jackson.
The JSON response from the REST service looks as follows:
{
"DisplayName": "Sixpack, Joe",
"UserID": "joe.sixpack",
"StdLog": "Some text"
}
So I have set up a simple JAXB bean ...
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class DisplayName {
private String displayName;
private String userID;
private String stdLog;
public DisplayName() {
}
public DisplayName(String DisplayName, String UserID, String StdLog) {
this.displayName = DisplayName;
this.userID = UserID;
this.stdLog = StdLog;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getStdLog() {
return stdLog;
}
public void setStdLog(String stdLog) {
this.stdLog = stdLog;
}
}
... added the Maven dependencies ...
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.22.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.5</version>
</dependency>
... and implemented a REST client:
Client client = ClientBuilder.newClient();
URI uri = UriBuilder.fromUri("http://server:2000").path("/path/to/service/" + UriComponent.encode(input_parameter, UriComponent.Type.QUERY_PARAM_SPACE_ENCODED)).build();
WebTarget target = client.target(uri);
DisplayName responseDN = target.request(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).get(DisplayName.class);
However, all the POJO fields are always null when using the MOXy media converter regardless of the annotations and constructors (e.g. no-args constructor) used according to similar issues (e.g. JAX-RS Response Object displaying Object fields as NULL values, Java REST service accepts POJO, but fields are always null).
So I want to use Jackson and adapted the JAXB class ...
import com.fasterxml.jackson.annotation.*;
@JsonInclude(JsonInclude.Include.ALWAYS)
@JsonPropertyOrder({"DisplayName","UserID","StdLog"})
public class DisplayName {
@JsonProperty("DisplayName")
private String displayName;
@JsonProperty("UserID")
private String userID;
@JsonProperty("StdLog")
private String stdLog;
public DisplayName() {
}
@JsonCreator
public DisplayName(@JsonProperty("DisplayName") String DisplayName, @JsonProperty("UserID") String UserID, @JsonProperty("StdLog") String StdLog) {
this.displayName = DisplayName;
this.userID = UserID;
this.stdLog = StdLog;
}
public String getDisplayName() {
return displayName;
}
@JsonProperty("DisplayName")
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getUserID() {
return userID;
}
@JsonProperty("UserID")
public void setUserID(String userID) {
this.userID = userID;
}
public String getStdLog() {
return stdLog;
}
@JsonProperty("StdLog")
public void setStdLog(String stdLog) {
this.stdLog = stdLog;
}
}
... and removed the MOXy dependency and added a dependency for JAXB:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.25.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
However, now I run into the error
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json
and none of the solutions I found did help (e.g. MessageBodyReader not found for media type=application/json, Glassfish :MessageBodyProviderNotFoundException in Jersy Client).
Why? And what is the solution?
Upvotes: 1
Views: 2057
Reputation: 331
Shortly after I had posted the question, I found the explanation and solution in the Jersey User Guide which says:
In order to use Jackson as your JSON (JAXB/POJO) provider you need to register JacksonFeature and a ContextResolver for ObjectMapper, if needed, in your Configurable (client/server).
Since MOXy is the default media library and registered automatically with the WebClient, it will be used unless another media library is registered. Hence, one has to register the Jackson media converter ...
Client client = ClientBuilder.newClient().register(JacksonFeature.class);
... and add the respective Maven dependency:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.25.1</version>
</dependency>
I'm just surprised that neither the tutorials nor the other answers to similar questions mentioned it.
Upvotes: 2