Я хочу сделать динамический запрос, который отвечает на следующие API остальные, например:
api/misra?sourceCodeCategory=3rd party&sourceCodeCategory=New Code&guidelineSeverity=required&buildId=72
Для этого я создал класс MisraSpecification:
public class MisraSpecification implements Specification<MisraMessages> {
private MultiValueMap<String, String> selectedParameters;
public MisraSpecification(MultiValueMap<String, String> selectedParameters) {
this.selectedParameters = selectedParameters;
}
@Override
public Predicate toPredicate(Root<MisraMessages> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();
Predicate result;
Predicate buildIdPredicate;
if (selectedParameters.get("buildId") != null) {
for (String buildId : selectedParameters.get("buildId")) {
predicates.add(cb.equal(root.get("fileName"), buildId));
}
}
buildIdPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
predicates.clear();
Predicate fileNamePredicate;
if (selectedParameters.get("fileName") != null) {
for (String fileName : selectedParameters.get("fileName")) {
predicates.add(cb.equal(root.get("fileName"), fileName));
}
}
fileNamePredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
predicates.clear();
Predicate messageSeverityPredicate;
if (selectedParameters.get("messageSeverity") != null) {
for (String messageSeverity : selectedParameters.get("messageSeverity")) {
predicates.add(cb.equal(root.get("messageSeverity"), messageSeverity));
}
}
messageSeverityPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
predicates.clear();
Predicate guidelineSeverityPredicate;
if (selectedParameters.get("guidelineSeverity") != null) {
for (String guidelineSeverity : selectedParameters.get("guidelineSeverity")) {
predicates.add(cb.equal(root.get("guidelineSeverity"), guidelineSeverity));
}
}
guidelineSeverityPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
predicates.clear();
Predicate requirementPredicate;
if (selectedParameters.get("requirement") != null) {
for (String requirement : selectedParameters.get("requirement")) {
predicates.add(cb.equal(root.get("requirement"), requirement));
}
}
requirementPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
predicates.clear();
Predicate sourceCodeCategoryPredicate;
if (selectedParameters.get("sourceCodeCategory") != null) {
for (String sourceCodeCategory : selectedParameters.get("sourceCodeCategory")) {
predicates.add(cb.equal(root.get("sourceCodeCategory"), sourceCodeCategory));
}
}
sourceCodeCategoryPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
predicates.clear();
Predicate functionalityPredicate;
if (selectedParameters.get("functionality") != null) {
for (String functionality : selectedParameters.get("functionality")) {
predicates.add(cb.equal(root.get("functionality"), functionality));
}
}
functionalityPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
predicates.clear();
Predicate subFunctionalityPredicate;
if (selectedParameters.get("subFunctionality") != null) {
for (String subFunctionality : selectedParameters.get("subFunctionality")) {
predicates.add(cb.equal(root.get("subFunctionality"), subFunctionality));
}
}
subFunctionalityPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
predicates.clear();
Predicate supplierPredicate;
if (selectedParameters.get("supplier") != null) {
for (String supplier : selectedParameters.get("supplier")) {
predicates.add(cb.equal(root.get("supplier"), supplier));
}
}
supplierPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
predicates.clear();
Predicate asilLevelPredicate;
if (selectedParameters.get("asilLevel") != null) {
for (String asilLevel : selectedParameters.get("asilLevel")) {
predicates.add(cb.equal(root.get("asilLevel"), asilLevel));
}
}
asilLevelPredicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
predicates.clear();
result = cb.and(cb.or(fileNamePredicate, messageSeverityPredicate, guidelineSeverityPredicate, requirementPredicate,
sourceCodeCategoryPredicate, functionalityPredicate, subFunctionalityPredicate, supplierPredicate, asilLevelPredicate));
return cb.and(result);
}
}
А это мой контроллер
@GetMapping("/misra")
public Page<MisraMessages> applyFilter(@PageableDefault(value = 10, page = 0) Pageable pageable,
@RequestParam(value = "buildId", required = true) String buildId,
@RequestParam MultiValueMap<String, String> selectedParameters) {
//add the build to the selected map values
List<String> build = new ArrayList<String>();
build.add(buildId);
selectedParameters.put("buildId", build);
//apply filter
Page<MisraMessages> listWithMisraMessageAfterFilter = misraMessagesService.findAllMisraByFilters(pageable, selectedParameters);
Когда я применяю фильтр, результат, в этом случае, частично удовлетворительный. SourceCodeCategory - это «третье лицо» или «Новый код», но GuidelineSeverity не учитывает фильтр. Я получаю объекты с большим количеством значений для SourceCodeCategory ... Я тестировал, и в контроллере я получаю правильное значение для GuidelineSeverity. У вас есть решение моей проблемы? :)