当前位置: 首页 > 知识库问答 >
问题:

自定义BeanProperty tyFilter-仅序列化字符串的一部分

燕英逸
2023-03-14

我急需帮助。我目前正在对内容API中的资源进行一些安全限制,其中我需要根据SecurityContext包括属性、截断属性(如果它们是String.class)或从序列化的对象中删除属性。

我使用 Jackson 作为我的 json 序列化程序,并选择使用 Bean 属性筛选器来检查是否应序列化每个属性。

现在删除和包含选项非常简单,要么我序列化bean,要么不序列化。

但是截断选项有点糟糕。这是我到目前为止对属性序列化所做的。

@Override
public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider provider, BeanPropertyWriter writer) throws Exception {
    switch (determineFilterAction(writer)) {
        case INCLUDE_UNMODIFIED:
            writer.serializeAsField(bean, jgen, provider);
            break;
        case INCLUDE_TRUNCATED:
            Object value = writer.get(bean);
            if (!(value instanceof String)) {
                throw new UnsupportedOperationException("Annotation indicates truncate on " + writer.toString() + " which is not a string, but a " + value.getClass().getSimpleName() + " and is unsupported");
            }
            JsonSerializer oldSerialzer= writer.getSerializer();
            writer.assignSerializer(new TruncateStringJsonSerializer());
            writer.serializeAsField(bean, jgen, provider);
            writer.assignSerializer(oldSerialzer);
            break;
        case REMOVE:
            // do nothing
            break;
    }
}

问题是,BeanPropertyWriter里有一个警卫。assignSerializer()方法,这将不允许我为该属性切换新的自定义序列化程序。

有什么方法可以连接并修改bean值吗?或者我必须重写工厂和BeanPropertyWriter才能重写assignSerializer()方法(以避免序列化程序保护)?

我不能只是用一个特殊的编写器注释我的属性,因为序列化的对象不知道任何关于SecurityContext的信息,所以没有办法将securityContext注入到自定义序列化器中。

有没有任何方法可以使这个截断选项发生(而不会使它变得太粗糙)?

提前致谢。

最好的问候,马丁。

更新

根据StaxMan的回答,我更新了这个方法,使其看起来像这样,而且似乎有效。至少我所有的测试都运行正常。将在开发应用服务器上进行进一步测试。

@Override
public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider provider, BeanPropertyWriter writer) throws Exception {
    switch (determineFilterAction(writer)) {
        case INCLUDE_UNMODIFIED:
            writer.serializeAsField(bean, jgen, provider);
            break;
        case INCLUDE_TRUNCATED:
            Object value = writer.get(bean);
            if (!(value instanceof String)) {
                throw new UnsupportedOperationException("Annotation indicates truncate on " + writer.toString() + " which is not a string, but a " + value.getClass().getSimpleName() + " and is unsupported");
            }
            String valueString = (String) value;
            jgen.writeFieldName(writer.getName());
            jgen.writeString(StringUtils.abbreviate(valueString, MAX_LENGTH));
            break;
        case REMOVE:
            // do nothing
            break;
    }
}

共有1个答案

岳俊雅
2023-03-14

不,甚至不要尝试调用 assignSerializer:这在多线程环境中是一个坏主意 - 该序列化程序只有一个实例,即使您可以调用它,在同时完成两个序列化的情况下,它也只会导致您出现奇怪的异常。

但也许您应该考虑从不同的方向来处理这个问题:既然您已经找到了<code>字符串JsonSerializer或任何东西。

 类似资料:
  • 我需要编写一个方法,它接受一些对象、给定对象的类中存在的一些字段名和一些字段值。该值是字段的JSON序列化形式。该方法将获取该值并相应地反序列化它,如下所示: (我实际上只需要检索反序列化的值,而不需要重新设置它,但这使它成为一个更好的示例。)只要Jackson默认的反序列化足够,这就行了。现在让我们假设我有一个带有自定义(de)序列化程序的类: 一个可能的解决方案是手动检查注释。但是,我真的不想

  • 问题内容: 我知道如何在Jackson中使用自定义序列化程序(通过扩展),但是我希望默认序列化程序可用于除1个字段之外的所有字段,我想使用自定义序列化程序覆盖该字段。 注释不是一种选择,因为我正在序列化一个生成的类(来自Thrift)。 编写自定义杰克逊序列化程序时,如何仅指定要覆盖的某些字段? 更新: 这是我要序列化的类: 上面的类有很多特质,其中大多数使用本机类型。我只想覆盖自定义序列化程序中

  • 问题 你想通过 format() 函数和字符串方法使得一个对象能支持自定义的格式化。 解决方案 为了自定义字符串的格式化,我们需要在类上面定义 __format__() 方法。例如: _formats = { 'ymd' : '{d.year}-{d.month}-{d.day}', 'mdy' : '{d.month}/{d.day}/{d.year}', 'dmy' :

  • easyopen序列化使用fastjson处理json,xstream处理xml。现在我们来自定义实现一个json处理: 新建一个类JsonFormatter,实现ResultSerializer接口 public class JsonFormatter implements ResultSerializer { @Override public String serialize(

  • 问题内容: 我有一个对象,其中包含一些要序列化的不可序列化字段。它们来自我无法更改的单独API,因此使它们可序列化不是一种选择。主要问题是Location类。它包含我需要的四个可以序列化的东西,所有整数。如何使用read / writeObject创建可以执行以下操作的自定义序列化方法: 我怎样才能做到这一点? 问题答案: Java支持自定义序列化。阅读“自定义默认协议”部分。 去引用: 但是,有

  • 有没有一种方法可以使用Jackson JSON处理器来执行自定义字段级别的序列化?例如,我想让 注意,age=25被编码为数字,而favoritenumber=123被编码为字符串。Jackson将编组为一个数字。在这种情况下,我希望将favoriteNumber编码为字符串。