Jersey 2 + Jackson Annotation / #JsonIgnore - java

EDIT: Being more specific now i noticed a conflict i want to use BOTH dependencies below:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>2.27</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.3.1</version>
</dependency>
Basically, I am trying to ignore a property (#JsonIgnore), but none of my Jackson annotations are working. Even the #JsonProperty. I tried to add the #JsonIgnore in getters and setters methods, but same behavior.
I also tried to follow official documentation, and tried different libraries
import org.codehaus.jackson.annotate.JsonIgnore; (Same Behavior)
import com.fasterxml.jackson.annotation.JsonIgnore; (Same Behavior)
I see similar posts like #12595351
My Response from the Controller, should not display the Revoked. Attribute, but i got this response:
Actual Response
{
"accessToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqb2huLmRvZUBleGFtcGxlLmNvbSIsImlzcyI6ImpvaG4uZG9lQGV4YW1wbGUuY29tIiwiaWF0IjoxNTI1MzI1Nzk1LCJleHAiOjE1MjUzMzI5OTV9.uri3pRwXQHHG09F-wM40qfuRMRVu_WBK3HlfquGvwYc",
"expiresAt": "2018-05-03T07:36:35.087Z[UTC]",
"expiresIn": 7199,
"issuedAt": "2018-05-03T05:36:35.087Z[UTC]",
"refreshToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqb2huLmRvZUBleGFtcGxlLmNvbSIsImlzcyI6ImpvaG4uZG9lQGV4YW1wbGUuY29tIiwiaWF0IjoxNTI1MzI1Nzk1LCJleHAiOjE1MjU5MzA1OTV9.xj2oytAVwiAIR8U2upJkPH_BdORuJUNbiicvuvGFz0w",
"revoked": false,
"type": "Bearer"
}
Expected Response
{
"accessToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqb2huLmRvZUBleGFtcGxlLmNvbSIsImlzcyI6ImpvaG4uZG9lQGV4YW1wbGUuY29tIiwiaWF0IjoxNTI1MzI1Nzk1LCJleHAiOjE1MjUzMzI5OTV9.uri3pRwXQHHG09F-wM40qfuRMRVu_WBK3HlfquGvwYc",
"expiresAt": "2018-05-03T07:36:35.087Z[UTC]",
"expiresIn": 7199,
"issuedAt": "2018-05-03T05:36:35.087Z[UTC]",
"refreshToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqb2huLmRvZUBleGFtcGxlLmNvbSIsImlzcyI6ImpvaG4uZG9lQGV4YW1wbGUuY29tIiwiaWF0IjoxNTI1MzI1Nzk1LCJleHAiOjE1MjU5MzA1OTV9.xj2oytAVwiAIR8U2upJkPH_BdORuJUNbiicvuvGFz0w",
"type": "Bearer"
}
pom.xml (Using Maven)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wedhany.fimper</groupId>
<artifactId>fimper</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>fimper</name>
<build>
<finalName>fimper</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>de.mkammerer</groupId>
<artifactId>argon2-jvm</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<version>9.0.1</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>5.0.7</version>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>2.27</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring4</artifactId>
<version>2.27</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-jdk-http</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.17.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.9.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>Development</id>
<dependencies>
<dependency>
<groupId>com.github.blocoio</groupId>
<artifactId>faker</artifactId>
<version>1.2.7</version>
</dependency>
</dependencies>
</profile>
</profiles>
<properties>
<jersey.version>2.27</jersey.version>
<springframework.version>4.3.16.RELEASE</springframework.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
Token.java (My Model)
package com.wedhany.models;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.wedhany.models.enums.token.GrantType;
import com.wedhany.models.enums.token.Type;
import java.util.Date;
public class Token {
/**
* Attributes
*/
private String accessToken;
private String refreshToken;
#JsonIgnore
private boolean revoked;
#JsonProperty("expires_at")
private Date expiresAt;
private Date issuedAt;
private GrantType grantType;
private Type type;
private User user;
/**
* #return Token TTL in seconds.
*/
public long getExpiresIn() {
return this.expiresAt.getTime() < new Date().getTime()
? 0
: (this.expiresAt.getTime() - new Date().getTime()) / 1000;
}
/**
* #return Token that will grant authentication and authorization.
*/
public String getAccessToken() {
return accessToken;
}
/**
* #param accessToken Token string.
*/
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
/**
* #return Token used to request a new token.
*/
public String getRefreshToken() {
return refreshToken;
}
/**
* #return Invalid token if true.
*/
public boolean isRevoked() {
return revoked;
}
/**
* #param revoked True for invalid.
*/
public void setRevoked(boolean revoked) {
this.revoked = revoked;
}
/**
* #param refreshToken Refresh token.
*/
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
/**
* #return Token's expiration date.
*/
public Date getExpiresAt() {
return expiresAt;
}
/**
* #param expiresAt Token's expiration date.
*/
public void setExpiresAt(Date expiresAt) {
this.expiresAt = expiresAt;
}
/**
* #return Date where the token was requested.
*/
public Date getIssuedAt() {
return issuedAt;
}
/**
* #param issuedAt Date where the token was requested.
*/
public void setIssuedAt(Date issuedAt) {
this.issuedAt = issuedAt;
}
/**
* #return Type of the token.
*/
public Type getType() {
return type;
}
/**
* #param type Type of the token.
*/
public void setType(Type type) {
this.type = type;
}
/**
* #return How the token was claimed.
*/
public GrantType getGrantType() {
return grantType;
}
/**
* #param grantType Set token type of grant.
*/
public void setGrantType(GrantType grantType) {
this.grantType = grantType;
}
/**
* #return Owner of the token
*/
public User getUser() {
return user;
}
/**
* #param user Token's owner.
*/
public void setUser(User user) {
this.user = user;
}
}
AuthenticationController
package com.wedhany.controllers;
import com.wedhany.exceptions.AuthorizationException;
import com.wedhany.models.Token;
import com.wedhany.models.User;
import com.wedhany.services.AuthenticationService;
import org.springframework.beans.factory.annotation.Autowired;
import javax.security.sasl.AuthenticationException;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#Path("auth")
public class AuthenticationController {
#Autowired
private AuthenticationService authenticationService;
#POST
#Path("login")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response login(User user, #HeaderParam("user-agent") String userAgent) throws Exception {
try {
// Authenticate the user using the credentials provided
this.authenticationService.authenticate(user.getEmail(), user.getPassword());
// Issue a token for the user
Token token = this.authenticationService.issueToken(user.getEmail(), userAgent);
// Return the token on the response
return Response.ok(token).build();
} catch (AuthorizationException e) {
return Response.status(Response.Status.UNAUTHORIZED).build();
} catch (AuthenticationException e) {
return Response.status(Response.Status.FORBIDDEN).build();
}
}
#POST
#Path("refresh")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response refresh(Token token, #HeaderParam("user-agent") String userAgent) throws AuthenticationException {
return Response.status(Response.Status.CREATED)
.entity(this.authenticationService.refresh(token.getRefreshToken(), userAgent))
.build();
}
#POST
#Path("register")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response register(User user) {
user = authenticationService.save(user);
return Response.status(Response.Status.CREATED)
.entity(user)
.build();
}
}

Choose either one of the following but not both:
<!-- JSON-B (JSR-347) support -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>2.27</version>
</dependency>
<!-- Jackson 2.x support -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.27</version>
</dependency>
Both Jackson and JSON-B provide JSON from/to Java binding:
Jackson is a quite mature library for JSON processing. It's flexible and has a fair number of extensions modules.
JSON-B is also referenced as JSR-347. It's an specification for JSON binding. The actual implementation will be provided by Eclipse Yasson, which is the reference implementation of the JSR-347.
If you want go for jersey-media-json-jackson, you are supposed to use Jackson annotations. To ignore a property, for instance, use #JsonIgnore.
If you want to go for jersey-media-json-binding, you are supposed to use JSON-B annotations. To ignore a property, for instance, use #JsonbTransient.
You are using jersey-bom, a dependency management artifact that consolidate and centralize the management of dependency versions (without actually adding the dependencies to the project).
So you don't need to specify the version of the org.glassfish.jersey artifacts. Use one of the following (without version):
<!-- JSON-B (JSR-347) support -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
</dependency>
<!-- Jackson 2.x support -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
See more details here and here.

The following code works for me with jackson version 2.8.10
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonIgnoreExample {
private static class BeanWithIgnore {
#JsonIgnore
public int id;
public String name;
public BeanWithIgnore(int id, String name) {
this.id = id;
this.name = name;
}
}
public static void main(String[] args) throws JsonProcessingException {
BeanWithIgnore bean = new BeanWithIgnore(1, "My bean");
String result = new ObjectMapper().writeValueAsString(bean);
System.out.println(result); // {"name":"My bean"}
}
}

Basically the jersey-media-json-binding and jersey-media-json-jackson have similar behavior. You can't use both at the same time. The reason the jersey-media-json-jackson was not working it is because the provider which have more priority is the jersey-media-json-binding.

I don't know the whole configuration of your project so one think you can do that is, create manually JSON and then send to response like:
ObjectMapper maper = new ObjectMapper();
return Response.ok(maper.writer().withDefaultPrettyPrinter().writeValueAsString(tokenObject));
It will work like manual conversion without using auto serialization by Jersey.
Note: This thing is not recommendable but it should work.
You need this dependency for conversion:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>

This works for me, I have these libs in my pom.xml:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${org.glassfish.jersey.core.version}</version>
<scope>provided</scope>
</dependency>
<!-- ************** Jackson XML and JSON API ************************* -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>${org.glassfish.jersey.core.version}</version>
<scope>provided</scope>
</dependency>
Just remove that property from your class and add this annotation:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown=true)
public class Token {
// ... keep only the properties you want to map
this will tell Jackson to only bind the properties which you actually have in your class ignoring all the rest that might be present in the JSON output.

Related

Jersey Rest Web Service with POJO Mapping remove fields with null values from JSON String [SOLVED]

I have a Jersey Rest Web Service and I would like to send json response removing all fields with null values from json response.
I'm using
#JsonInclude(JsonInclude.Include.NON_NULL)
but it doesn't work at both class and attribute level.
My resource class contain this function:
#RolesAllowed("ADMIN")
#Path("/test")
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
#ApiOperation(value = "test Create", response = TestResponse.class)
public Response Create(TestRequest request, #Context ContainerRequestContext context) {
TestResponse resp = new TestResponse();
resp.setValueA("Value A");
return Response.ok().entity(resp).build();
}
TestResponse class contain:
#ApiModel("TestResponse")
#JsonInclude(JsonInclude.Include.NON_NULL)
public class TestResponse{
#JsonProperty
private String valueA;
#JsonProperty
private String valueB;
#ApiModelProperty(value = "Value A", example = "value A")
public String getValueA(){
return valueA;
}
public SetValueA(String valueA){
this.valueA = valueA;
}
#ApiModelProperty(value = "Value B", example = "value B")
public String getValueB(){
return valueB;
}
public SetValueB(String valueB){
this.valueB = valueB;
}
}
my JSON response contain:
{"valueA":"ValueA","valueB":null}
but I would like to send back this JSON:
{"valueA":"ValueA"}
this is my application class:
#ApplicationPath("/rest")
public class App extends ResourceConfig {
public App() {
packages("it.ivan");
// Register Auth Filter here
register(AuthenticationFilter.class);
register(StartupHandler.class);
register(MultiPartFeature.class);
register(new LoggingFeature(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME),
Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ANY, 10000));
BeanConfig beanConfig = new BeanConfig();
beanConfig.setTitle("Ivan Rest Application");
beanConfig.setVersion("1.0.0");
beanConfig.setBasePath("/rest/");
beanConfig.setResourcePackage("it.ivan");
beanConfig.setScan(true);
register(beanConfig);
register(io.swagger.jaxrs.listing.ApiListingResource.class);
register(io.swagger.jaxrs.listing.SwaggerSerializers.class);
register(io.swagger.jaxrs.config.DefaultJaxrsConfig.class);
Swagger swagger = new Swagger();
swagger.securityDefinition("basicAuth", new BasicAuthDefinition());
new SwaggerContextService().updateSwagger(swagger);
}
}
this is my pom.xml file:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>it.ivan</groupId>
<artifactId>TestRest</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>TestRest</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jersey.version>2.33</jersey.version>
<slf4j.version>1.7.29</slf4j.version>
</properties>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>com.owlike</groupId>
<artifactId>genson</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20201115</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.4.0-b180830.0359</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jersey2-jaxrs</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
UPDATE... ISSUE SOLVED...
I removed this dependecy:
<dependency>
<groupId>com.owlike</groupId>
<artifactId>genson</artifactId>
<version>1.6</version>
</dependency>
and I added this one:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>

An attempt was made to call a method that does not exist. STS

When i run the STS(SpringBoot) application i get the below error:
The attempt was made from the following location: org.apache.catalina.authenticator.AuthenticatorBase.startInternal(AuthenticatorBase.java:1321)
The following method did not exist:
javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;
The method's class, javax.servlet.ServletContext, is available from the following locations:
jar:file:/home/talha/.m2/repository/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar!/javax/servlet/ServletContext.class
jar:file:/home/talha/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/9.0.33/tomcat-embed-core-9.0.33.jar!/javax/servlet/ServletContext.class
It was loaded from the following location:
file:/home/talha/.m2/repository/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar
The suggestion in the ide is:
Action:
Correct the classpath of your application so that it contains a single, compatible version of javax.servlet.ServletContext
I guess there is something wrong with my pom.xml the code is as below:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.uni</groupId>
<artifactId>authorize</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>authorize</name>
<description>API for user registration and login with validation</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.mail/javax.mail -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-mongodb -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.jsontoken</groupId>
<artifactId>jsontoken</artifactId>
<version>1.0</version>
</dependency>
<!-- Thanks for using https://jar-download.com -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>authrize</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The main dependencies causing the error are:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.jsontoken</groupId>
<artifactId>jsontoken</artifactId>
<version>1.0</version>
</dependency>
I get the error only after adding the above dependencies, the need to add the dependencies is the below class:
package com.uni.authorize.service;
import java.security.InvalidKeyException;
import java.security.SignatureException;
import java.util.List;
import org.joda.time.DateTime;
import org.joda.time.Instant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import com.google.gson.JsonObject;
import com.uni.authorize.model.TokenKeys;
import com.uni.authorize.pojo.TokenObject;
import com.uni.authorize.repository.TokenKeysRepository;
import com.uni.authorize.service.CreateToken;
import net.oauth.jsontoken.JsonToken;
import net.oauth.jsontoken.crypto.HmacSHA256Signer;
#Configuration
public class CreateToken {
private static final Logger LOGGER = LoggerFactory.getLogger(CreateToken.class);
private static final String ISSUER = "UnI United Tech";
#Autowired
TokenKeysRepository tokenKeyRepository;
public TokenObject createToken(String userId) {
List<TokenKeys> tokenList = tokenKeyRepository.findAll();
TokenKeys tokenKeys = tokenList.get(0);
long accessTokenValidity = tokenKeys.getAccessTokenValidity();
long refreshTokenValidiry = tokenKeys.getRefreshTokenValidity();
String accessTokenKey = tokenKeys.getAccessKey();
String refreshTokenKey = tokenKeys.getRefreshKey();
String accessToken = generateAccessToken(userId, accessTokenKey, accessTokenValidity);
String refreshToken = generateRefreshToken(userId, refreshTokenKey, refreshTokenValidiry);
TokenObject tokenObject = new TokenObject();
tokenObject.setAccess_token(accessToken);
tokenObject.setRefresh_token(refreshToken);
tokenObject.setToken_type("bearer");
tokenObject.setExpires_in(accessTokenValidity);
tokenObject.setScope("read write trust");
return tokenObject;
}
private String generateAccessToken(String userId, String accessTokenKey, long accessTokenValidity) {
HmacSHA256Signer signer;
try {
signer = new HmacSHA256Signer(ISSUER, null, accessTokenKey.getBytes());
} catch (InvalidKeyException e) {
throw new RuntimeException(e);
}
// Configure JSON token
JsonToken token = new net.oauth.jsontoken.JsonToken(signer);
// token.setAudience(AUDIENCE);
DateTime dateTime = new DateTime();
long dateTimeMillis = dateTime.getMillis();
// DateTime currentTimeDateTime = new DateTime(dateTimeMillis);
// DateTime expiryTimeDateTime = new DateTime(dateTimeMillis + accessTokenValidity);
Instant currentTimeInstant = new org.joda.time.Instant(dateTimeMillis);
Instant expirationTimeInstant = new org.joda.time.Instant(dateTimeMillis + accessTokenValidity);
LOGGER.debug("Current Time Instant" + currentTimeInstant);
LOGGER.debug("Expiration Tine Instant" + expirationTimeInstant);
token.setIssuedAt(currentTimeInstant);
token.setExpiration(expirationTimeInstant);
// Configure request object, which provides information of the item
JsonObject request = new JsonObject();
request.addProperty("userId", userId);
JsonObject payload = token.getPayloadAsJsonObject();
payload.add("info", request);
try {
return token.serializeAndSign();
} catch (SignatureException e) {
throw new RuntimeException(e);
}
}
private String generateRefreshToken(String userId, String refreshTokenKey, long refreshTokenValidiry) {
HmacSHA256Signer signer;
try {
signer = new HmacSHA256Signer(ISSUER, null, refreshTokenKey.getBytes());
} catch (InvalidKeyException e) {
throw new RuntimeException(e);
}
// Configure JSON token
JsonToken token = new net.oauth.jsontoken.JsonToken(signer);
// token.setAudience(AUDIENCE);
DateTime dateTime = new DateTime();
long dateTimeMillis = dateTime.getMillis();
// DateTime currentTimeDateTime = new DateTime(dateTimeMillis);
// DateTime expiryTimeDateTime = new DateTime(dateTimeMillis + refreshTokenValidiry);
Instant currentTimeInstant = new org.joda.time.Instant(dateTimeMillis);
Instant expirationTimeInstant = new org.joda.time.Instant(dateTimeMillis + refreshTokenValidiry);
LOGGER.debug("Current Time Instant" + currentTimeInstant);
LOGGER.debug("Expiration Tine Instant" + expirationTimeInstant);
token.setIssuedAt(currentTimeInstant);
token.setExpiration(expirationTimeInstant);
// Configure request object, which provides information of the item
JsonObject request = new JsonObject();
request.addProperty("userId", userId);
JsonObject payload = token.getPayloadAsJsonObject();
payload.add("info", request);
try {
return token.serializeAndSign();
} catch (SignatureException e) {
throw new RuntimeException(e);
}
}
}
Please help me resolve this issue.
Thanks in advance
getVirtualServerName() was added in Servlet 3.1, but you included servlet-api-2.5.jar is your application.
Options:
Change your dependencies to include servlet-api-3.1.jar (or later)
Remove the servlet-api-2.5.jar dependency, since the correct version is included in the Embedded Tomcat file (tomcat-embed-core-9.0.33.jar).
Actually, you should never ship servlet-api.jar with your application, since it will be provided by the Servlet Container. Seems you're missing <scope>provided</scope> in your dependency tag for the servlet-api file.
I solved a similar issue by adding dependencyManagement.
Here is an example of my code where a version of org.springframework.cloud was the problem:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Spring boot controller endpoints not enabled?

I have inherited a Spring Boot microservice which does not have a Service or API layer, it is behaving in a HATEOAS style.
This is not an optimal architecture and needs to be changed into MVC.
Currently all repository methods are accessed directly using the #RepositoryRestResource annotation.
The plan is to refactor this and add Controllers and a API layer (DTOs), however after adding a controller, swagger is not showing the Rest controllers
Also to note that when debugging the controller endpoint, it is not actually reached. It is being bypassed, which is another clue.
#CrossOrigin
#RestController
#RequestMapping("/fixing")
public class FixingController {
private final FixingRepository fixingRepository;
#Autowired
FixingController(final FixingRepository fixingRepository) {
this.fixingRepository = checkNotNull(fixingRepository, "Fixing Repository cannot be null");
}
/**
* Builds a list of Fixing strings from the database
* #return list
*/
#RequestMapping(value = "/", method = RequestMethod.GET)
public List<String> getAllFixings() {
final List<String> fixingList = new ArrayList<>();
for (Fixing fixing : fixingRepository.findAll()) {
String name = fixing.getName();
fixingList.add(name);
}
return fixingList;
}
}
This is the spring swagger config
#Configuration
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.regex("/api.*"))
.build();
}
}
The repository (note no #RepositoryRestResource annotation)
public interface FixingRepository extends JpaRepository<Fixing, Long> {
#Override
Fixing findOne(Long id);
#Override
List<Fixing> findAll();
}
When I rebuild and start the service, the controller is not shown. It only shows all the entities and their repository methods.
POM dependencies
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- included explicitly to avoid javadoc generation error
due to a conflict with a class used by #Transactional annotation -->
<dependency>
<groupId>javax.interceptor</groupId>
<artifactId>javax.interceptor-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>8.0.12</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-data-rest</artifactId>
<version>2.8.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>1.5.13.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.6.2</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-storage</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
</dependencies>
Any ideas what is causing this? There is nothing else I can see in the config which is preventing this from working
The issue is with your SwaggerConfig. You are only selecting a subset of your APIs (either the JPA repository sourced or your RestController sourced) via this :
.paths(PathSelectors.regex("/api.*"))
I replicated your scenario and I just commented the path selection out and I can see both type of APIs. Note that you can also use a custom predicate for selecting the paths:
#Configuration
#Import({SpringDataRestConfiguration.class})
public class SwaggerConfig {
#Autowired
#SuppressWarnings({"UnusedDeclaration"})
private ServletContext servletContext;
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.pathProvider(relativePath())
.select()
.apis(RequestHandlerSelectors.any())
// .paths(paths2())
.build();
}
// Select only a few
private Predicate<String> paths2() {
return and(
(regex("/fixing.*")),
(regex("/api.*")));
}
// Exclude these
private Predicate<String> paths() {
return and(
not(regex("/error.*")),
not(regex("/metrics.*")),
not(regex("/jolokia.*")),
not(regex("/health.*")),
not(regex("/env.*")),
not(regex("/metrics.*")),
not(regex("/info.*")),
not(regex("/mappings.*")),
not(regex("/trace.*")),
not(regex("/dump.*")),
not(regex("/heapdump.*")),
not(regex("/configprops.*")),
not(regex("/beans.*")),
not(regex("/autoconfig.*")),
not(regex("/logfile.*")),
not(regex("/shutdown.*")),
not(regex("/actuator.*")));
}
}
Sample Rest Controller:
#CrossOrigin
#RestController
#RequestMapping("/fixing")
public class FixingController {
/**
* Builds a list of Fixing strings from the database
* #return list
*/
#RequestMapping(value = "/", method = RequestMethod.GET)
public List<String> getAllFixingsViaRestController() {
final List<String> fixingList = new ArrayList<>();
fixingList.add("foo");
fixingList.add("bar");
return fixingList;
}
}
Now my Swagger UI looks like this; you can see both the JPA Repository contributed REST APIs and the RestController contributed API (/fixing path):

Cant get Providers to work Jersey

I've googled and tried but I cant get Providers to work in my project.
POM.XML:
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>9.0.0.M1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
My Filter:
package xxxxxxx
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.DatatypeConverter;
#Provider
public class BasicAuthFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext requestContext)
throws IOException {
String authorization = requestContext.getHeaderString("Authorization");
if (!auth(authorization)) {
requestContext.abortWith(Response
.status(Response.Status.UNAUTHORIZED)
.entity("User cannot access the resource.")
.build());
}
}
private Boolean auth(String authorization)
throws UnsupportedEncodingException {
if (authorization != null && authorization.startsWith("Basic")) {
String base64Credentials = authorization
.substring("Basic".length()).trim();
byte[] decoded = DatatypeConverter
.parseBase64Binary(base64Credentials);
final String[] values = new String(decoded, "UTF-8").split(":", 2);
if (values.length == 2 && values[0].equals("usuario")
&& values[1].equals("senha")) {
return true;
}
}
return false;
}
}
My ResourceConfig class:
import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
import xxx.providers.BasicAuthFilter;
import xxx.resource.LogParserResource;
#ApplicationPath("rest")
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
register(BasicAuthFilter.class);
register(MyResource.class);
}
}
Filter is not triggered. Anything wrong in my configuration?
WEB.XML is empty and the Resource is working fine. Any suggestions??
Thanks.
i noticed, that this dependency is not the version of the other ones:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19</version>
</dependency>
you could try to use:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.22.1</version>
</dependency>
and then notice the documentation:
Important
Servlet 2.x API does not provide a way how to programmatically read
the filter mappings. To make application deployed using filter work
correctly, either Servlet 3.x container must be used
(jersey-container-servlet instead of jersey-container-servlet-core),
or the context path of the app needs to be defined using init
parameter jersey.config.servlet.filter.contextPath.
see: https://jersey.java.net/documentation/latest/deployment.html#deployment.servlet

Spring MVC 4.1.x RestFul Service throwing Not Acceptable for Json

I have made a Rest Service using Spring MVC4.1.X, but whenever I try to return Json o/p to browser iam getting the following error
The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
Iam using #Response body for auto conversion of a Java pojo into JSON objects. I have tried almost all the solution given on stackoverflow .
my controller class
package com.spring.rest.ambulance;
import java.io.IOException;
import net.sf.json.JSONObject;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.spring.dao.AmbulanceDAO;
import com.spring.dao.AmbulanceDAOImpl;
import com.spring.model.Ambulance;
#RestController
#RequestMapping("/Ambulance")
public class AmbulanceRestController {
#Autowired
private AmbulanceDAO ambulanceDAO;
#RequestMapping(value = "/hello", method = RequestMethod.GET)
public #ResponseBody String getAllUsers(ModelMap model) {
String jsonData = "[{\"id\":\"3253123\",\"firstname\":\"Chris\",\"lastname\":\"Johnson\",\"address\":\"211, Geoffrey Drive\",\"city\":\"Newark\",\"phone\":\"999-888-6666\",\"email\":\"chrisj#yahoo.com\"},{\"id\":\"67643837\",\"firstname\":\"Bill\",\"lastname\":\"Derkson\",\"address\":\"201, Sleepy Hollow Drive\",\"city\":\"Newark\",\"phone\":\"999-777-2222\",\"email\":\"billd#gmail.com\"}]";
return jsonData;
}
#RequestMapping(value = "/{id}")
public #ResponseBody Ambulance getAmbulanceProviders(ModelMap model,
#PathVariable("id") int Id) {
String jsonData = null ;
Ambulance ambulance = ambulanceDAO.getById(Id);
ObjectMapper objmapper = new ObjectMapper();
try {
jsonData = objmapper.writeValueAsString(ambulance);
//System.out.println(objmapper.writeValueAsString(ambulance));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return ambulance;
}
Entity being returned
package com.spring.model;
import org.codehaus.jackson.map.ObjectMapper;
public class Ambulance {
private int ID;
private String vehicleNumber;
private String ambulanceType;
private String ambulanceProviderName;
/**
* #return the iD
*/
public int getID() {
return ID;
}
/**
* #param iD
* the iD to set
*/
public void setID(int iD) {
ID = iD;
}
/**
* #return the vehicleNumber
*/
public String getVehicleNumber() {
return vehicleNumber;
}
/**
* #param vehicleNumber
* the vehicleNumber to set
*/
public void setVehicleNumber(String vehicleNumber) {
this.vehicleNumber = vehicleNumber;
}
/**
* #return the ambulanceType
*/
public String getAmbulanceType() {
return ambulanceType;
}
/**
* #param ambulanceType
* the ambulanceType to set
*/
public void setAmbulanceType(String ambulanceType) {
this.ambulanceType = ambulanceType;
}
/**
* #return the ambulanceProviderName
*/
public String getAmbulanceProviderName() {
return ambulanceProviderName;
}
/**
* #param ambulanceProviderName
* the ambulanceProviderName to set
*/
public void setAmbulanceProviderName(String ambulanceProviderName) {
this.ambulanceProviderName = ambulanceProviderName;
}
#Override
public String toString() {
return "{ID="+ID+",AmbulanceProvderName="+ambulanceProviderName+",AmbulanceType="+ambulanceType+",VehicleNumber="+vehicleNumber+"}";
}
}
DAO Ambulance get by Id
public Ambulance getById(int id) {
// TODO Auto-generated method stub
Ambulance ambulance = new Ambulance();
/* JdbcTemplate jdbcTemplate = new JdbcTemplate();
System.out.println(dataSource);
jdbcTemplate.setDataSource(dataSource);*/
System.out.println(jdbcTemplate.getDataSource());
String sql = "SELECT * FROM AMBULANCE WHERE AMBULANCEID = ?";
ambulance = (Ambulance)jdbcTemplate.queryForObject(sql,new Object[] { id }, new AmbulanceRowMapper());
return ambulance;
}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>SpringWebAppRestServices</groupId>
<artifactId>SpringWebAppRestServices</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
Originally this issue occurs when the request sends an accept header that differs from the response's content-type. I don't know if this is the case, there's not enough source provided.
However, another a bit more trickier situation when the same error occurs is when the framework is not able to convert the response to an appropriate representation, e.g. on account of bad getters/setters or missing dependencies.
In the code you posted I see an issue with your dependencies. Spring 4.1 needs minimum Jackson 2.1, and in the version Jackson 2 and above a package change occurred from codehaus to fasterxml. Replace the two of your Jackson dependencies with the following one
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.1.2</version>
</dependency>
or better yet go for a newer version. Single dependency is enough it will transitively pull com.fasterxml.jackson.core:jackson-annotations:jar and com.fasterxml.jackson.core:jackson-core:jar
I think you might have to ensure that your Request is having the following in your header:
GET
Accept: application/json

Categories