简体   繁体   中英

Spring WebFlux Reactor - Updating Object In Flux

Given following method:

Flux<Person> getAllPerson(Criteria criteria) 

How do i process the flux by changing a field in each of the Person object in the flux?

getAllPerson(criteria)
                .map(person -> person.setLastUpdated(new Date())

The setLastUpdated(new Date()) returns void

I've tried a lot of different ways but i can't figure out the way to make it compile, for eg:

getAllPerson(criteria)
                .map(person -> {
                     person.setLastUpdated(new Date())
                     return person;
                 });

You can use the doOnNext operator which is intended to execute this kind of side-effect operations.

Although, generally it is a better approach to keep the Person class immutable and when you would need to modify something you would just create a copy of it, in that case you would be able to use the map operator as expected.

Your second example:

getAllPerson(criteria)
            .map(person -> {
                 person.setLastUpdated(new Date())
                 return person;
             });

...won't compile, but only because it's missing a semicolon on the setLastUpdated() line.

However, by far the best thing to do here (as suggested already) is to make your Person class immutable. You can then use the "wither" pattern (either using lombok or your own implementation) to simply do:

getAllPerson(criteria)
            .map(person -> person.withLastUpdated(new Date()));

If you can't make Person immutable (either because it's an external library, or its mutability is simply too baked into existing code), then all is not lost. You can still produce an immutable wrapper quite easily, eg:

class ImmutablePerson {
    Person person;

    public ImmutablePerson(Person p) {
        this.person = p;
    }

    public Person withFirstName(String name) {
        return new Person(name, person.getLastName(), person.getLastUpdated());
    }

    public Person withLastName(String name) {
        return new Person(person.getFirstName(), name, person.getLastUpdated());
    }

    public Person withLastUpdated(Date date) {
        return new Person(person.getFirstName(), person.getLastName(), date);
    }

    public String getFirstName() {return person.getFirstName();}
    public String getLastName() {return person.getLastName();}
    public Date getLastUpdated() {return person.getLastUpdated();}
    public Person toPerson() {return new Person(person.getFirstName(), person.getLastName(), person.getLastUpdated());}
}

You can then just map to ImmutablePerson in the first step of your reactive chain like so:

getAllPerson(criteria)
        .map(ImmutablePerson::new)
        .map(p -> p.withLastUpdated(new Date()))
        //etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM