Spring Converter не преобразует пользовательский объект - PullRequest
0 голосов
/ 11 марта 2020

Я пытаюсь зашифровать / расшифровать dbField, используя аннотацию конвертера, это , работающий с другими сущностями , где результатом запросов (в репо) является сама сущность. В этом случае я возвращаю пользовательский POJO, а не сущность БД , и dbField (частный контент) не конвертируется должным образом. Может быть, я что-то упускаю.

Информация зашифрована на БД, но я получаю зашифрованную информацию о сервисе, поэтому она не расшифровывается.

Я искал документации, но мне не удалось найти что-либо, касающееся пользовательских запросов и конвертеров.

Ниже вы можете увидеть код. Любую дополнительную информацию, которую я могу предоставить. Спасибо за ваше время.

DbEntity

@Entity
public class History {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Convert(converter = CryptoConverter.class)    
    private String privateContent;

    // getters and setters omitted for clarity
}

Конвертер

@Converter
public class CryptoConverter implements AttributeConverter<String, String> {

    private static final String ALGORITHM = "AES/ECB/PKCS5Padding";
    private static final byte[] KEY = "BLABLAKEY".getBytes();

    @Override
    public String convertToDatabaseColumn(String clientData) {
        if(isBlank(clientData)){
            return clientData;
        }

        Key key = new SecretKeySpec(KEY, "AES");
        try {
            Cipher c = Cipher.getInstance(ALGORITHM);
            c.init(Cipher.ENCRYPT_MODE, key);
            return Base64.getEncoder().encodeToString(c.doFinal(clientData.getBytes()));
        } catch (Exception e) {
            throw new CryptoException(e);
        }
    }

    @Override
    public String convertToEntityAttribute(String dbData) {
        if(isBlank(dbData)){
            return dbData;
        }

        Key key = new SecretKeySpec(KEY, "AES");
        try {
            Cipher c = Cipher.getInstance(ALGORITHM);
            c.init(Cipher.DECRYPT_MODE, key);
            return new String(c.doFinal(Base64.getDecoder().decode(dbData)));
        } catch (Exception e) {
            throw new CryptoException(e);
        }
    }
}

Хранилище

@Repository
public interface HistoryRepository extends JpaRepository<History, Long> {

    @Query(value = "SELECT mh.id, mh.privateContent FROM history mh WHERE mh.account=:account")
    List<HistoryDB> getHistory(@Param("account") final Long account);

}

Пользовательские POJO

public interface HistoryDB {

    String getId();

    String getPrivateContent();
}

1 Ответ

0 голосов
/ 11 марта 2020

Запрос:

@Query("SELECT mh.id AS id, mh.privateContent as privateContent FROM history mh WHERE mh.account = :account")

Интерфейс:

public interface HistoryDB {

    @Value("#{target.id}")
    String getId();

    @Value("#{target.privateContent}")
    String getPrivateContent();

}

Вы не возвращаете целевой объект из вашего запроса, но псевдонимы, которые могут быть неправильно сопоставлены с интерфейсом проекции.

Полагаю, ваш ответ выглядит как объект JSON, все поля которого имеют значение null. (Поправьте меня, если я ошибаюсь).

ОБНОВЛЕНИЕ 1:

Также есть возможность вызывать преобразователь атрибутов вручную из интерфейса проекции с помощью экспонирования компонента:

@Component //Singleton proxy instance in application context (no huge impact)
public class CryptoConverter implements AttributeConverter<String, String> {}

И затем, используя метод проекции:

public interface HistoryDB {

    @Value("#{target.id}") // May omit if works without @Value
    String getId();

    @Value("#{@cryptoConverter.convertToEntityAttribute(target.privateContent)}")
    String getPrivateContent();

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...