1

I have got 2 classes - 2 entities - Book and BookRentals. BookRentals takes Book object inside.

I want to ignore one of attribute from Book inside BookRentals. This is available attribute. I've got method that is rensponsible for finding all rentals. Output in JSON looks like this:

[
    {
        "id": 1,
        "book": {
            "id": 1,
            "title": "Krzyżacy",
            "author": "Henryk Sienkiewicz",
            "category": "powieść historyczna",
            "available": false
        },
        "user": {
            "id": 2,
            "name": "piotri",
            "password": "123"
        }
    }
]

As you can see, available is not necesessary here, but I cant make @JsonIgnore in Book class, because this variable is needed in finding all books:

[
    {
        "id": 1,
        "title": "Krzyżacy",
        "author": "Henryk Sienkiewicz",
        "category": "powieść historyczna",
        "available": false
    }
]

Book class:

package bookrental.model.book;

import lombok.*;

import javax.persistence.*;
import javax.validation.constraints.NotNull;

@Entity
@Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    @NotNull
    private String title;
    @NotNull
    private String author;
    @NotNull
    private String category;
    private boolean available;

    public Book(String title, String author, String category, boolean available) {
        this.title = title;
        this.author = author;
        this.category = category;
        this.available = available;
    }
}

BookRentals class

package bookrental.model.book;

import bookrental.model.account.User;
import lombok.*;

import javax.persistence.*;

@Entity
@Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor

public class BookRentals {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    @OneToOne
    private Book book;
    @OneToOne
    private User user;

    public BookRentals(Book book, User user) {
        this.book = book;
        this.user = user;
    }
}

How am I supposed to do that?

pipilam
  • 587
  • 3
  • 9
  • 22

2 Answers2

0

You can use a Mixin to change the serialization behaviour for a class. In your case, create a mixin which ignores the 'available' property:

public interface RentalBookMixin {
    @JsonIgnore
    boolean isAvailable();
}

Now you can enable the mixin on the ObjectMapper when you serialize BookRentals:

 ObjectMapper mapper = new ObjectMapper();
 mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector());
 mapper.addMixInAnnotations(Book.class, RentalBookMixin.class);

When serializing single Books, omit this mixin so the 'available' property gets serialized again.

Peter Walser
  • 15,208
  • 4
  • 51
  • 78
  • Well, I should create interface and which class implements it? This is the only method that interface should contain? Where should I add ObjectMapper, in which class? – pipilam Dec 18 '18 at 09:33
  • The interface is not implemented by anyone - it just serves for Jackson as a primary source for the JSON property configuration, overriding those on your Book class. The ObjectMapper configuration depends on the framework you use (JEE, Spring, ...), usually a default ObjectMapper is supplied, which can be overridden. – Peter Walser Dec 18 '18 at 10:32
  • For more details see https://github.com/FasterXML/jackson-docs/wiki/JacksonMixInAnnotations – Peter Walser Dec 18 '18 at 10:35
  • unfortunately, cant make it :( I don't know where to what write. – pipilam Dec 18 '18 at 13:48
0

You can use ResponseEntity and JsonSerializer (include and exclude) jackson to do the same.

return new JSONSerializer().transform(new DateTransformer("MM/dd/yyyy HH:mm:ss"), java.util.Date.class).include("field1").exclude("field2").serialize(pojoObject);

And then from the controller return response like below.

return new ResponseEntity<String>(new JSONSerializer().transform(new DateTransformer("MM/dd/yyyy HH:mm:ss"), java.util.Date.class).include("field1").exclude("field2").serialize(pojoObject), headers,HttpStatus.OK);

Your controller method will look something like below.

@RequestMapping(value = "/getUser", method = RequestMethod.GET,produces="application/json")
    @ResponseBody
    public ResponseEntity<String> getUser(@RequestParam(value = "userId", required = true) String userId)
    {

        User user = userService.findByUserId(userId);
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json; charset=utf-8");
        return new ResponseEntity<String>(new JSONSerializer().transform(new DateTransformer("MM/dd/yyyy HH:mm:ss"), java.util.Date.class).include("field1").exclude("field2").serialize(user), headers,HttpStatus.OK);
    }
Alien
  • 15,141
  • 6
  • 37
  • 57
  • Why do I need date here? Im working with spring boot, so @ResponseBody, headers are not necessary too, I think. So my Service method should looks like this: https://pastebin.com/tPUQe4DT ? I cannot resolve symbol of JSONSerializer and DateTransfomer. – pipilam Dec 18 '18 at 09:41
  • date transform is used to manipulate the date patterns..if you dont want to use can remove it. @ResponseBody needed if you are not using Restcontroller. and for JSONSerializer you should import it from import flexjson.JSONSerializer; and ensure that you have net.sf.flexjson flexjson 2.1 in pom.xml – Alien Dec 18 '18 at 09:57
  • hey, everything works fine, but I cant get rid of class property from JSON. It looks this: https://pastebin.com/3xSBgmiw How am I supposed to exclude it? In pastebin I paste also method. – pipilam Dec 18 '18 at 22:37
  • exclude ("*.class") – Alien Dec 19 '18 at 04:12