39

How can I get @JsonIgnore to work I have a class. And even if I put the annotation there it has no effect on the output. I am using Jackson.

public class QuestionBlock implements ComparableByID{


    int ID;

    String title;
    String description;
    boolean deleted;
    boolean isDraft;
    boolean visible;
    Timestamp modifiedDate;
    String modifiedBy;


    private List<Question> questions =  new ArrayList<>();

    @JsonIgnore
    private List<Survey> surveys =  new ArrayList<>();

    ...

    @JsonIgnore
    public List<Survey> getSurveys() {
        return surveys;
    }

    @JsonIgnore
    public void setSurveys(List<Survey> surveys) {
        this.surveys = surveys;
    }

}

This is my Controller method:

@RequestMapping(value = "/questionBlock/{id}",produces = "application/json;charset=UTF-8")
    @ResponseBody
    public QuestionBlock getQuestionBlock(@PathVariable("id") int id) {
        return surveyService.getQuestionBlock(id);
    }

Here is my servlet-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <mvc:annotation-driven />


    <mvc:resources mapping="/resources/**" location="/resources/" />
    <mvc:resources location="/, classpath:/META-INF/web-resources/"
        mapping="/resources/**" />

    <context:property-placeholder location="classpath*:META-INF/*.properties" />


    <context:component-scan base-package="com.adam.czibere" />



    <bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="myDataSource" name="dataSource">
        <property name="driverClassName" value="${database.driverClassName}" />
        <property name="url" value="${database.url}" />
        <property name="username" value="${database.username}" />
        <property name="password" value="${database.password}" />
        <property name="testOnBorrow" value="true" />
        <property name="testOnReturn" value="true" />
        <property name="testWhileIdle" value="true" />
        <property name="timeBetweenEvictionRunsMillis" value="1800000" />
        <property name="numTestsPerEvictionRun" value="3" />
        <property name="minEvictableIdleTimeMillis" value="1800000" />
        <property name="validationQuery" value="SELECT 1" />
    </bean>


    <bean id="mySessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource" />
        <property name="packagesToScan">
            <array>
                <value>com.adam.czibere</value>
            </array>
        </property>
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.MySQLDialect
            </value>
        </property>
    </bean>

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory" />
    </bean>


    <tx:annotation-driven transaction-manager="transactionManager"/>

<bean
        class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="mediaTypes">
            <map>
                <entry key="html" value="text/html" />
                <entry key="json" value="application/json" />
            </map>
        </property>
        <property name="viewResolvers">
            <list>
                <bean
                    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                    <property name="prefix" value="/WEB-INF/views/" />
                    <property name="suffix" value=".jsp" />
                </bean>
            </list>
        </property>
        <property name="defaultViews">
            <list>
                <bean
                    class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
                    <property name="prefixJson" value="false" />
                    <property name="objectMapper" ref="jacksonObjectMapper" />
                </bean>
            </list>
        </property>
    </bean>
    <bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean
                    class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
                    <property name="prefixJson" value="false" />
                    <property name="supportedMediaTypes" value="application/json" />
                </bean>
            </list>
        </property>
    </bean>
</beans>
czadam
  • 1,827
  • 1
  • 18
  • 31
  • When you say it does nothing, it would be helpful to state what is happening and what you expected to be happening. I'm working on the assumption here that you are receiving a JSON response and that all fields are in that response. You expect the @JsonIgnore attribute to be causing 'qSurveys' to be hidden. – Steve Nov 10 '13 at 21:14
  • yes, I want to the Surveys not to be shown in the response. – czadam Nov 10 '13 at 21:22
  • Why do you keep adding @JsonIgnore annotations to the example code above in the wrong places? There should only be one, and that should be on the 'get' method. – Steve Nov 10 '13 at 21:30
  • And are you getting valid JSON being returned containing the results of all the other 'get' methods? – Steve Nov 10 '13 at 21:31
  • I tried to put it on the get method only, it was not working. And yes I am getting a valid JSON containing the results of all the other 'get' methods. – czadam Nov 10 '13 at 21:42
  • Possible duplicate: http://stackoverflow.com/questions/10085088/jackson-annotations-being-ignored-in-spring – Andrei Nicusan Nov 10 '13 at 21:44
  • It probably is a duplicate of that question. I was about to say that there should be no mention of Jackson in the servlet-context.xml because it is automatically used by Spring in newer versions. – Steve Nov 10 '13 at 21:46

10 Answers10

96

I have finally found a solution. I changed the import statement from

import com.fasterxml.jackson.annotate.JsonIgnore;  // com. instead of org.

to

import org.codehaus.jackson.annotate.JsonIgnore;

Basically you have to make sure you are using the same class everywhere.

Darren Parker
  • 1,772
  • 1
  • 20
  • 21
czadam
  • 1,827
  • 1
  • 18
  • 31
  • 12
    Why are you using two implementations of Jackson in one project? You should choose one. – Michał Ziober Nov 10 '13 at 23:48
  • 2
    Had the same problem. Had fasterxml.jackson in my POM but also Jersey that brings codehaus.jackson as a dependency. – Nic Jul 20 '14 at 01:16
  • 4
    I had to do the opposite but this post helped me to notice I had two Jackson implementations in my pom.xml. – madth3 Aug 06 '14 at 23:27
  • Thanks a lot! I got same problem writing a mapreduce project. then I found I was using `org.apache.htrace.fasterxml.jackson.databind.ObjectMapper` instead of `com.fasterxml.jackson.databind.ObjectMapper` in hadoop mapper class, so my annotation never works until I changed the import. I depend on ide auto completion to much, sometimes it show me the wrong class. – at15 Nov 22 '15 at 13:28
  • 1
    The actual reason why that happened is that the codehaus dependency has more precedence in your maven dependencies that the fasterxml one. One way to solve this is to specify the wanted implementation in a higher level of precedence: In the application module. – EliuX Apr 28 '17 at 01:29
  • For me this is the correct answer also. I'm new to jax-rs dev so it took me a bit to figure this out. I had only one definition in my POM.xml file, but it turns out in my web.xml file there was an init-param definition with the other package name. – notmystyle Apr 12 '20 at 19:24
17

The annotation should only be on the 'get' methods. You seem to have @Json... annotations on your private fields.

Steve
  • 9,270
  • 5
  • 47
  • 61
8

If you are using an implementation of Jackson and its annotations are not working it's probably because you have another dependency of jackson with better precedence. Hence if you want to assure that certain implementation of jackson prevales (IMHO the best choice is the one that you have all classes already annotated with, because probably it came with other dependencies) specify this dependency in the pom of the application module. So if you have in multiple modules all your entities annotated with

import com.fasterxml.jackson.annotate.JsonIgnore;  // note: com. instead of org.

Instead of replacing all imports just specify the corresponding dependency in the application pom:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>

This will clarify to Spring Boot that this is the implementation you want to use.

Darren Parker
  • 1,772
  • 1
  • 20
  • 21
EliuX
  • 11,389
  • 6
  • 45
  • 40
6

Putting @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) before the field declaration solved the problem for me.

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private List<Survey> surveys =  new ArrayList<>();

I'm using jackson version 2.11.3

Pedro Blandim
  • 385
  • 3
  • 7
3

I added @Getter(onMethod_=@JsonIgnore) for boolean.

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true) 
public class TestClass    {

    
     @JsonIgnore 
    private String name;
    
     @Getter(onMethod_=@JsonIgnore) 
    private boolean isValid; 

}
anson
  • 1,436
  • 14
  • 16
1

I faced this issue in my project and finally I got the solution.

Replace the dependency...

    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-jaxrs</artifactId>
        <version>1.9.13</version>
    </dependency>

Import : com.fasterxml.jackson.annotation.JsonIgnore;

I hope, It will work.

1

In my case JsonIgnore was not working only on dates. Then I understood that was because of @JsonFormat() that I was using to define the format of date. Removing that solved the issue.

Nitin Pareek
  • 57
  • 1
  • 7
1

If @JsonProperty("fieldName") is also present on the field along with @JsonIgnore, the latter is ignored. This could happen, for instance, in generated code.

@Generated("jsonschema2pojo")
public MyGeneratedClass {
    // ...
    @JsonProperty("label")          // This overrides @JsonIgnore
    @JsonIgnore(true)               // Doesn't work
    @Field(name = "label")
    private java.lang.String label;
    // ...
}

From the documentation of JsonIgnore:

... if only particular accessor is to be ignored ..., this can be done by annotating other not-to-be-ignored accessors with JsonProperty (or its equivalents).

aksh1618
  • 2,245
  • 18
  • 37
0

You Need to change your org.codehaus.jackson version. I am currently using 1.1.1 version in which @JsonIgonre is not working. I changed it with 1.9.13 then @JsonIgnore is working fine.

    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-jaxrs</artifactId>
        <version>1.1.1</version>
    </dependency>

    Change to 

   <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-jaxrs</artifactId>
        <version>1.9.13</version>
    </dependency>

And Java Code is :-

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.codehaus.jackson.annotate.JsonIgnore;

@Entity
@Table(name="users")
public class Users implements Serializable{

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;
    private String username;
    private String firstname;
    @JsonIgnore
    private String lastname;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

}
Pankaj Verma
  • 39
  • 1
  • 7
0

I faced the same issue while working with spring and hibernate. The reason for this was that in entity class I was using org.codehaus.jackson.JsonIgnore and in spring I was using com.fasterxml.jackson.jaxrs.JsonIgnore. Fix to any one library in both layers and problem will disappear.

tanson
  • 82
  • 3