我正在尝试使用转换器注释来加密/解密 dbField,这是处理其他实体,其中查询的结果(在存储库上)是实体本身。在本例中,我返回自定义 POJO,而不是数据库实体,并且 dbField(私有(private)内容)未按应有的方式进行转换。也许我错过了一些东西。
信息正在数据库上加密,但我在服务上获取加密信息,因此它没有被解密。
我搜索了文档,但找不到有关自定义查询和转换器的任何内容。
下面您可以看到代码。我可以提供任何进一步的信息。感谢您抽出时间。
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();
}
最佳答案
查询:
@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();
}
您不会从查询中返回目标实体,而是返回可能尚未正确映射到投影接口(interface)的别名。
我猜您的响应看起来像 JSON 对象,其中所有字段的值为 null。 (如果我错了请纠正我)。
更新1:
还可以通过转换器的 bean 暴露从投影接口(interface)手动调用属性转换器:
@Component //Singleton proxy instance in application context (no huge impact)
public class CryptoConverter implements AttributeConverter<String, String> {}
然后使用它的投影方法:</p>
public interface HistoryDB {
@Value("#{target.id}") // May omit if works without @Value
String getId();
@Value("#{@cryptoConverter.convertToEntityAttribute(target.privateContent)}")
String getPrivateContent();
}
关于java - Spring转换器不转换自定义实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60638653/