Home > other >  Filter none null value from object in Java
Filter none null value from object in Java

Time:07-07

I have a spring boot a application with some endpoints, one of the endpoints is to search for car options, see below

@PostMapping("/searchCarOptions")
public ResponseEntity<Cars> search(
        @Parameter(description = "some searchRequest") @RequestBody SearchRequest searchRequest) {

    if (searchRequest.getType() != null) {
        //dosomthing
    }
    
    if (searchRequest.getBrand() != null) {
        //dosomthing
    }
    
    if (searchRequest.getCountry() != null) {
        //dosomthing
    }
    
    if (searchRequest.getClient() != null) {
        //dosomthing
    }
    
    if (searchRequest.getAirco() != null) {
        //dosomthing
    }
    
    etc.....

    return ResponseEntity.ok(someService.search(searchRequest));
}

Is there better way to put my searchRequest in a method and return just the filled search criteria and put it for example in a String variable? it will make code cleaner....

Below is my model

public class SearchRequest {

    private String type;
    private String brand;
    private LocalDate date;
    private String country;
    private String client;
    private String airco;
    private String transmission;
    private String seats;
    
    getters and setters
}

CodePudding user response:

What I understand from above is that you are trying to enrich your SearchRequest before passing it to SomeService#search. I think you can implement little bit customised strategy pattern. Let's see how:

Create an interface SearchRequestEnricher like below

public interface SearchRequestEnricher {
    boolean isApplicable(SearchRequest searchRequest);
    void enrich(SearchRequest searchRequest);
}

Create SearchRequestEnricher implementations for each field(I will create only 2 just for example here)

TypeEnricher

@Component
public class TypeEnricher implements SearchRequestEnricher{

    @Override
    public boolean isApplicable(SearchRequest searchRequest) {
        return searchRequest.getType() != null;
    }

    @Override
    public void enrich(SearchRequest searchRequest) {
        //your dosomething business logic
    }
}

BrandEnricher

@Component
public class BrandEnricher implements SearchRequestEnricher{

    @Override
    public boolean isApplicable(SearchRequest searchRequest) {
        return searchRequest.getBrand() != null;
    }

    @Override
    public void enrich(SearchRequest searchRequest) {
        //your dosomething business logic
    }
}

Now you can use these enrichers in your controller

@RestController
public class SearchController {
    private List<SearchRequestEnricher> searchRequestEnrichers;
    
    @PostMapping("/searchCarOptions")
    public ResponseEntity<Cars> search(
            @Parameter(description = "some searchRequest") @RequestBody SearchRequest searchRequest) {
        //enrich your request
        searchRequestEnrichers.stream().filter(searchRequestEnricher -> searchRequestEnricher.isApplicable(searchRequest))
                .forEach(searchRequestEnricher -> searchRequestEnricher.enrich(searchRequest));
        //use enriched request
        return ResponseEntity.ok(someService.search(searchRequest));
    }
}

This way, your controller is clean and it doesn't have any business logic(as it should not have). You are following separation of concern and single responsibility principles. You don't need to touch your controller if you add or remove extra parameter in SearchRequest and would like to validate/enrich them.

Hope this helps.

  • Related