2

目前我们的 Web 项目需要对一些数据进行匿名化处理。
(例如,像 432-55-1111 这样的安全号码可能显示为 432-55- * *)这些数据可能包含电子邮件、ID、价格、日期等。

需要屏蔽的表名和列保存在数据库中。
我们正在使用 spring security 来判断用户是否可以看到数据。
数据域对象(CMP)可以从 SQL 或 JPQL(命名查询或本机查询)或 JPA 加载方法或大型机中获取。

我们需要找到一种最有效的方式(而不是 DB 端)来动态屏蔽这些数据。
如果我们在 EJB 方法 end 使用拦截器,我们需要注释所有 Object(DTO) 和所有列。那可能是效率低下。
任何人都知道在完成 SQL 执行并执行命名查询(本机查询)时我们如何调用方法(如拦截器),并且我们可以调用方法以通过查询和用户 ID 来屏蔽结果。

或者其他方式。

最好将它放在最低级别,这样其他应用程序(如报告)就不需要单独的解决方案。

我们项目的架构是JSF+Spring+EJB 3.0+JPA 1.0。
我们有很多网络项目。
对于 JPA,一些项目使用 EclipseLink 2.2,一些项目使用 Hibernate。

更新: 关于我们项目的更多信息。我们有很多关于不同功能的 web 项目。所以我们有很多与之相关的 ejb 项目。每个 ejb 都有 DAO 通过调用 JPQL 或 get(class, primarykey) 方法来获取他们的 CMP。如下所示:

Query   query = em.createNamedQuery(XXXCMP.FIND_XXX_BY_NAME);
                query.setHint(QueryHints.READ_ONLY, HintValues.TRUE);
                query.setParameter("shortName", "XXX").getSingleResult();

或者

XXXCMP screen = entityManager.find(XXXCMP.class, id);

新的 EJB 服务代码转换器将数据从 CMP 转换为 DTO。
转换器如下:

/**
 * Convert to CMP.
 * 
 */
CMP convertToCMP(DTO dto, EntityManager em);

/**
 * Convert CMP to domain object with all fields populated, the default scenario is
 * <code>EConvertScenario.Detail</code>.
 * 
 */
DTO convertFromCMP(CMP cmp, EntityManager em);

但是一些老服务使用自己的方法来转换CMP。还有一些用于搜索懒惰的域服务,他们也没有使用转换器。

我们想在 CMP 转换为 DTO 之前屏蔽数据。

4

2 回答 2

0

在这种情况下,您可能会拦截 JSF 的转换情况。此解决方案适用于 JSF 视图,而不适用于报告。

@FacesConverter("AnonymizeDataConverter")
public class AnonymizeDataConverter implements Converter{

    @Override
    public Object getAsObject(FacesContext context, UIComponent component,
        String value) {

        return getAnonymisedData(value);
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component,
            Object value) {

        return getAnonymisedData(value);     
    }

    public static String getAnonymisedData(Object data) {
        if (data == null) 
            return "";

        String value = data.toString().trim();

        if (!value.isEmpty())
            return value.substring(0, value.lenght() - 4) + "**";

        return "";
    }

}
于 2013-01-20T10:51:27.817 回答
0

您可以尝试使用注释EntityListener拦截实体加载到持久性上下文中。@PostLoad

否则,可以在我认为适合屏蔽/格式化等的访问方法(getter/setter)中尝试。

编辑:(基于评论和问题更新)

您可以跨应用程序共享实体/DTO

public String getSomethingMasked(){

   return mask(originalString);
}
  • 数据检索模式在应用程序中并不统一。如果所有应用程序都使用相同的数据库,则必须对其进行泛化。用不同的工具再写同样的东西是没有意义的。每个应用程序可能会在之后应用业务逻辑。

    可能,您可以有一个单独的项目用于与数据库交互,然后将其包含在其他应用程序中以供进一步使用。因此,更改任何内容、调试、增强等将是一个共同点。

  • 您正在使用 Eclipselink、Hibernate 和其他自定义方式来获取数据,并且您需要最少的解决方法,从我的角度来看,这似乎很困难。

    如果可能的话,要么集中数据检索,要么单独进行更改,我认为这是不可行的,会影响一致性。

于 2013-01-13T06:22:47.023 回答