1

I have MyEntity class:

@Entity
@Table("entities)
public class MyEntity {

     @ID
     private String name;
     @Column(name="age")
     private int age;
     @Column(name="weight")
     private int weight;

     ...getters and setters..

}

In @RestController there are 2 @GetMapping methods. The first:

@GetMapping
public MyEntity get(){
   ...
   return myEntity;
} 

The second:

@GetMapping("url")   
public List<MyEntity> getAll(){
   ...
   return entities;
}

It's needed to provide:
1. @GetMapping returns entity as it's described in MyEntity class.
2. @GetMapping("url") returns entities like one of its fields is with @JsonIgnore.

UPDATE:

When I return myEntity, client will get, for example:

{
"name":"Alex",
"age":30,
"weight":70
}

I want in the same time using the same ENTITY have an opportunity depending on the URL send to client:

1.

{
    "name":"Alex",
    "age":30,
    "weight":70
}

2.

{
    "name":"Alex",
    "age":30
    }
Donatello
  • 353
  • 6
  • 19
  • 2
    it looks that you need to check tutorials like this one https://spring.io/guides/gs/rest-service/ or this https://spring.io/guides/tutorials/bookmarks/ – Sergey Chepurnov Mar 05 '19 at 03:26
  • @SergeyChepurnov I am sorry for such abstract question. I know hot to work with JPA and entities. I know that it's possible to use @ JsonIgnore on fields and when I return myEntity client will recieve json with all fields except @ JsonIgnore. – Donatello Mar 05 '19 at 04:55
  • But now i need in one method @ GetMapping return myEntity with all fields, but in another method @ GetMapping with another URL I want to return the same myEntity but without some of its fields – Donatello Mar 05 '19 at 04:57
  • I hope JsonView annotation works. – DCO Mar 05 '19 at 08:56

3 Answers3

1

EDIT:

Instead of returning an Entity object, you could serialize it as a Map, where the map keys represent the attribute names. So you can add the values to your map based on the include parameter.

@ResponseBody
public Map<String, Object> getUser(@PathVariable("name") String name, String include) {

    User user = service.loadUser(name);
    // check the `include` parameter and create a map containing only the required attributes
    Map<String, Object> userMap = service.convertUserToMap(user, include);

    return userMap;
}

As an example, if you have a Map like this and want All Details

userMap.put("name", user.getName());
userMap.put("age", user.getAge());
userMap.put("weight", user.getWeight());

Now if You do not want to display weight then you can put only two parameters

userMap.put("name", user.getName());
userMap.put("age", user.getAge());

Useful Reference 1 2 3

Romil Patel
  • 12,879
  • 7
  • 47
  • 76
  • I am sorry for such abstract question. I know how to create working entity, it was just short example. And It is working well. And now I want another @ GetMapping to work as if my entity has @ JsonIgnore on int weight for example – Donatello Mar 05 '19 at 04:54
  • @Donatello can you please give some more details. Are you looking for this https://stackoverflow.com/questions/12505141/only-using-jsonignore-during-serialization-but-not-deserialization – Romil Patel Mar 05 '19 at 05:00
  • I've added details in the question, but idk if it's possible. It would be great – Donatello Mar 05 '19 at 05:02
1

You could create two DTO classes, convert your entity to the appropriate DTO class and return it.

public class MyEntity {
    private String name;
    private int age;
    private int weight;

    public PersonDetailedDTO toPersonDetailedDTO() {
        PersonDetailedDTO person = PersonDetailedDTO();
        //...
        return person;  
    }

    public PersonDTO toPersonDTO() {
        PersonDTO person = PersonDTO();
        //...
        return person;  
    }
}

public class PersonDetailedDTO {
    private String name;
    private int age;
    private int weight;
}

public class PersonDTO {
    private String name;
    private int age;
}

@GetMapping
public PersonDTO get() {
   //...
   return personService.getPerson().toPersonDTO();
}

@GetMapping("/my_url")
public PersonDetailedDTO get() {
   //...
   return personService.getPerson().toPersonDetailedDTO();
}
Sergey Chepurnov
  • 1,397
  • 14
  • 23
1

You could also use JsonView Annotation which makes it a bit cleaner. Define views

public class View {
    static class Public { }
    static class ExtendedPublic extends Public { }
    static class Private extends ExtendedPublic { }
}

Entity

    @Entity
@Table("entities)
public class MyEntity {

     @ID
     private String name;
     @Column(name="age")
     private int age;
     @JsonView(View.Private.class)
     @Column(name="weight")
     private int weight;

     ...getters and setters..

}

And in your Rest Controller

    @JsonView(View.Private.class)
    @GetMapping
    public MyEntity get(){
       ...
       return myEntity;
    } 

    @JsonView(View.Public.class)
    @GetMapping("url")   
    public List<MyEntity> getAll(){
       ...
      return entities;
    }

Already explained here: https://stackoverflow.com/a/49207551/3005093

DCO
  • 1,222
  • 12
  • 24
  • It works stangely. It doens't work like you said, but I can just add @ JsonView(View.Public.class) on fields that I want to see + the same on controller method. And if I need full information I just skip using annotation in controller – Donatello Mar 05 '19 at 15:53
  • Could you explain how Spring understands what to do?Is it just some contract with class structure(public class with static classes inside which could extends each other)? It's defenitely the best way to solve this problem, thank you. – Donatello Mar 05 '19 at 15:58
  • 1
    It is Jackson which converts your entity to JSON. " @JsonView(BasicView.class) which would specify that property annotated would be included when processing (serializing, deserializing) View identified by BasicView.class (or its sub-class). If multiple View class identifiers are included, property will be part of all of them. " http://fasterxml.github.io/jackson-annotations/javadoc/2.1.1/com/fasterxml/jackson/annotation/JsonView.html Its just a simple mapping from a View Class to Entity Method or Field. Like "Only render this field in this view" – DCO Mar 05 '19 at 16:30