Dependência Maven da biblioteca (https://github.com/tkaczmarzyk/specification-arg-resolver):
<dependency>
<groupId>net.kaczmarzyk</groupId>
<artifactId>specification-arg-resolver</artifactId>
<version>2.6.2</version>
</dependency>
-
Criar uma classe de configuração (exemplo:
configs/ResolverConfig.java
):@Configuration public class ResolverConfig extends WebMvcConfigurationSupport { @Override protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { argumentResolvers.add(new SpecificationArgumentResolver()); PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver(); argumentResolvers.add(resolver); super.addArgumentResolvers(argumentResolvers); } }
-
Criar uma classe com os templates (que são interfaces) de specification (exemplo:
specifications/SpecificationTemplate.java
):public class SpecificationTemplate { @And({ @Spec(path = "courseLevel", spec = Equal.class), @Spec(path = "courseStatus", spec = Equal.class), @Spec(path = "name", spec = Like.class) }) public interface CourseSpec extends Specification<CourseModel> {} }
- Nessa classe de template, deve ser criado uma interface para cada tipo de entidades na qual se deseja utilizar o specification. O filtro é aplicado com a anotação
@Spec
, que deve possuir o nome da coluna desejada nopath
e o tipo de filtro nospec
, conforme mostrado no código acima. - Além disso, é possível a anotação
@Spec
estar dentro da anotação@And
ou@Or
, variando conforme a necessidade de combinar todos os filtros aplicados ou aceitar apenas um desses filtros.
- Nessa classe de template, deve ser criado uma interface para cada tipo de entidades na qual se deseja utilizar o specification. O filtro é aplicado com a anotação
-
Estender o
JpaSpecificationExecutor
no repositório JPA da(s) entidade(s) que irá(ão) utilizar os filtros de specification:public interface CourseRepository extends JpaRepository<CourseModel, UUID>, JpaSpecificationExecutor<CourseModel> {}
-
Receber como parâmetro no controller o template e utilizar como parâmetro na consulta desejada (neste exemplo, o
findAll()
):public List<CourseModel> getAllCourses(SpecificationTemplate.CourseSpec courseSpec) { return courseRepository.findAll(courseSpec); }
- Como o repositório passou a estender o
JpaSpecificationExecutor
, o métodofindAll(Specification<T> spec)
passou a ficar disponível para ser usado automaticamente.
- Como o repositório passou a estender o
Exemplo de requisição com filtros (cURL):
$ curl --location --request GET 'http://localhost:8082/courses?courseStatus=INPROGRESS&courseLevel=BEGINNER'