4

I want to exclude name and age from my response, but When I receive the JSON payload request I need name and age field - after my business logic, I want to send status and message as part of JSON response. name and age should exclude from that. How can I achieve this in java?

public class Sample {

    private String name;
    private String age;
    private String status;
    private String message;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

My Controller class:

@PostMapping(path = "/testApp", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> test(@RequestBody Sample sample) {
    Sample response = myService.calculate(sample);
    return new ResponseEntity<Object>(response, HttpStatus.OK);
}

My Request

{
    "name": "Mark",
    "age": "48"
}

My Response

{
    "status": "200",
    "message": "success"
}
learn groovy
  • 487
  • 4
  • 11
  • 28
  • 1
    Are you using a framework/package to do the JSON serialization & deserialization for you? Using [Jackson](https://www.baeldung.com/jackson-object-mapper-tutorial) you can annotate either/both getters & setters with `@JsonIgnore` to exclude fields in either direction; You don't need a separate class. It does not take some "tricky hacks"; but it depends on what you're using for your `Java <-> JSON`transformations. – Stephen P Nov 28 '18 at 23:27
  • 1
    There are 3 answers so far that all suggest using two separate classes. I _strongly_ disagree with that approach but have refrained from downvoting the answers. Libraries/frameworks/packages that assist in the `Java <-> JSON` transformations already handle the case you're asking about (different fields for incoming / outgoing JSON) without having two separate classes to be keep in synch with each other (a maintenance nightmare). We use (as I mentioned) Jackson, and have _**never**_ had to create separate classes. I would _answer_, but it wouldn't be helpful if you're not using Jackson. – Stephen P Nov 29 '18 at 00:43
  • Thanks for your response, I'm using Jackson. – learn groovy Nov 29 '18 at 15:54

4 Answers4

4

Using Jackson for Java/JSON serialization and deserialization provides a number of ways to control the JSON that is produced and accepted.

Since you want to omit fields in certain cases, the most straightforward way to do this is with the @JsonIgnore annotation.

@JsonIgnore can be used on fields, getters, and setters (and more) to always ignore the field, ignore on output to JSON, or ignore on JSON->Java deserialization.

Your basic Sample class could ignore message all the time (both when serializing and deserializing) by annotating the field:

public class Sample {
    private String name;
    private String age;
    private String status;
    @JsonIgnore private String message;
}

When you want to omit a field when serializing Java -> JSON you can annotate the getter, when you want to ignore a field when deserializing JSON -> Java you annotate the setter.
So if you want to omit name and age when your Sample object is producing JSON, you'd annotate both those fields

public class Sample {

    private String name;
    private String age;
    private String status;
    private String message;

    @JsonIgnore        // Added Annotation
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @JsonIgnore        // Added Annotation
    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

With those annotations, name and age will be set in the object when you deserialize from JSON, but they will not be output when serializing to JSON, and you need only one class, not separate classes for the request and the response.

Stephen P
  • 14,422
  • 2
  • 43
  • 67
0

I think you should create a separate class for request and response, you can't include two different functionalities in the same class, let's suppose in future in you need to include something in request or response, then again you need to change whole lot of code and if you keep segregation then it will be not a problem.

maddy
  • 129
  • 1
  • 4
0

You can't do it without some tricky hacks. Response and Request don't even share a single field, and from OOP perspective they are different objects, so why mashing them up together?

If you are just experimenting with (de)serialization, then you can try @JsonIgnore on specific setters and getters to manipulate serialization and deserialization. Check this question Ignoring property when deserializing

If you are actually trying to solve the problem writing a clean code then split them into two separate classes.

xagaffar
  • 683
  • 8
  • 16
-1

You should have a Sample class with the name and age fields and a SampleResponse class with only the fields you want to include in the response.

Artanis
  • 561
  • 1
  • 7
  • 26
  • If I do this, then these fields ignore as part of my request also. I tried this option – learn groovy Nov 28 '18 at 22:04
  • I updated my answer, you should always have a seperate pojo for your response, it is best practice. It also solves your issue, win win. – Artanis Nov 28 '18 at 22:29
  • I _emphatically_ disagree with your statement _"you should always have a seperate pojo for your response"_ — that leads to code duplication, and frameworks such as Jackson have solutions that don't require you to use two classes. Jackson's `@JsonIgnore` and the use of `ObjectMapper.addMixIn(...)` obviate the need for duplication. – Stephen P Nov 29 '18 at 00:06
  • You're always going to want a separate response object even if it just holds other objects with the fields you're looking to include in the response. There's no code duplication there. – Artanis Nov 29 '18 at 14:23