1

SpringBoot Version 2.7.13 Java 11

My Code


package com.chisw.contactservice.validation;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Component
public class PhoneNumbersValidAndUniqueValidator implements ConstraintValidator<PhoneNumbersValidAndUnique, String> {
    private static final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();

    @Autowired
    private ObjectMapper mapper;

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null) {
            return false;
        }

        List<String> phoneNumbers;
        try {
            phoneNumbers = mapper.readValue(value, new TypeReference<ArrayList<String>>() {});
        } catch (JsonProcessingException e) {
            return false;
        }

        try {
            Optional<Phonenumber.PhoneNumber> invalidPhoneNumber = phoneNumbers.stream()
                    .map(phone -> {
                        try {
                            return phoneNumberUtil.parse(phone, null);
                        } catch (NumberParseException e) {
                            throw new RuntimeException(e);
                        }
                    })
                    .filter(phoneNumber -> !phoneNumberUtil.isValidNumber(phoneNumber))
                    .findFirst();

             if (invalidPhoneNumber.isPresent()) {
                 return false;
             }
        } catch (RuntimeException e) {
            return false;
        }

        if (phoneNumbers.stream()
                .map(phoneNumber -> phoneNumber.replaceAll("[\\s\\-()]", ""))
                .distinct()
                .count() != phoneNumbers.size()){
            return false;
        }

        return true;
    }
}

Problem is: @Autowired private ObjectMapper mapper; - inject NULL only in ConstraintValidator In all another components it works and return correct bean ObjectMapper.

I tried solutions from Autowired gives Null value in Custom Constraint validator

Nothing helps me !

1 Answers1

1

Based on this Hibernate Validator in Spring Boot using different ConstraintValidatorManager

I added Configuration

package com.chisw.contactservice;

import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

import javax.validation.Validator;
import java.util.Map;

@Configuration
@Lazy
class ValidatorConfig {

    @Bean
    @Lazy
    public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(final Validator validator) {
        return new HibernatePropertiesCustomizer() {

            @Override
            public void customize(Map<String, Object> hibernateProperties) {
                hibernateProperties.put("javax.persistence.validation.factory", validator);
            }
        };
    }
}