【问题标题】:Java JSON RESTful web services - Filtering fieldsJava JSON RESTful Web 服务 - 过滤字段
【发布时间】:2013-09-19 13:13:56
【问题描述】:

场景

  • Jersey/JacksonJson 用于我的 RESTful Web 服务请求。
  • 具有 X、Y、Z 属性的实体 A。
  • 2 个 RESTful 请求。
  • 请求 1 应在 JSON 响应中返回具有 X、Y 属性的实体 A
  • 请求 2 应在 JSON 响应中返回具有 X、Y、Z 属性的实体 A
  • 实体 A 的配置使得属性 Z 使用 @JsonIgnore,因此它不会在 JSON 响应中返回

问题

如果在实体中将属性 Z 设置为 @JsonIgnore,如何在请求 2 中返回属性 Z?除了使用@JsonIgnore 之外,还有更好的方法来动态执行此操作吗? 下面是一些“演示”代码来帮助澄清我的问题。

@Entity
Class A implements Serializable {
  String X;
  String Y;
  String Z;

  @JsonIgnore
  public String getZ() {
    return Z;
  }
}

@Path("form")
Class Request {
    @GET
    @Path("request1")
    @Produces({"application/json"})
    public A request1() {
      return A;
    }

    @GET
    @Path("request2")
    @Produces({"application/json"})
    public A request2() {
      return A;
    }
}

【问题讨论】:

  • 将 Z 放入子类 B 并从 request2 返回 B?
  • 有类的泛化和特化正如Kevin所说,Jackson会自动创建JSON对应的对象。它对我有用。

标签: java json rest jackson


【解决方案1】:

你可以使用@JsonView注解。

类似:

public class Views {
    public static class BasicView {
    }

    public static class FullView extends BasicView {
    }
}

然后上课A

  @JsonView(Views.BasicView.class)
  public String getX() {
    return X;
  }


  @JsonView(Views.BasicView.class)
  public String getY() {
    return Y;
  }


  @JsonView(Views.FullView.class)
  public String getZ() {
    return Z;
  }

当您必须返回 JSON 时,您必须使用基于自定义视图的ObjectWriters 对它们进行序列化:

public static final ObjectWriter basicObjectWriter = objectMapper
            .writerWithView(Views.BasicView.class);
public static final ObjectWriter fullObjectWriter = objectMapper
            .writerWithView(Views.FullView.class);

那么,如果你写basicObjectWriter.writeValueAsString(responseObject),它只会写XYfullObjectWriter.writeValueAsString(responseObject) 将写入 XYZ

【讨论】:

  • 这也是一个有效的解决方案,但我想远离手动序列化对象。谢谢。
【解决方案2】:

如果您不需要发送空值,您可以将不想发送的变量设置为空,并设置杰克逊忽略空属性。这样,在 request1 上,您可以将 Z 设置为 null。 另一种方法是使用扩展对您的类进行建模,但我不知道 Jackson 在这种情况下是否可以轻松解析。

【讨论】:

  • 这就是我最终要做的。我用@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 注释了我所有的域类。我删除了所有 @JsonIgnore 注释。
【解决方案3】:

您可以尝试使用 Jackson 的 BeanSerializerModifier 来实现此目的。为了动态排除属性,您需要扩展 BeanSerializerModifier 并适当地实现 changeProperties 方法。以下代码 sn -p 适用于有问题的示例:

public class CustomBeanSerializerModifier extends BeanSerializerModifier
{
    private String path;

    public CustomBeanSerializerModifier(String path)
    {
        this.path = path;
    }

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
            BeanDescription desc, List<BeanPropertyWriter> inputProperties)
    {
        List<BeanPropertyWriter> outputProperties = new ArrayList<>();
        for (BeanPropertyWriter property : inputProperties) {
            if (path.startsWith("request1") && property.getType().getRawClass().equals(A.class)) {
                if (property.getName().equals("Z")) {
                    continue;
                }
            }
            outputProperties.add(property);
        }
        return super.changeProperties(config, desc, outputProperties);
    }
}

如下插入杰克逊的ObjectMapper(使用Module):

public class CustomModule extends Module
{
    private String path;

    public CustomModule(String path)
    {
        this.path = path;
    }

    @Override
    public void setupModule(SetupContext context)
    {
        context.addBeanSerializerModifier(new CustomBeanSerializerModifier(path));
    }

    // Other overridden methods
}

ObjectMapper objectMapper = new ObjectMapper();
String path = getJerseyPath();
CustomModule module = new CustomModule(path);
objectMapper.registerModule(module);

// Call objectMapper.writeValue() to serialize stuff

This question 处理在泽西岛使用自定义杰克逊代码(ObjectMapper 的形式)。

希望这会有所帮助!

【讨论】:

    【解决方案4】:

    你说你正在使用 Jersey/JAX-RS,所以你 Yoga 应该特别感兴趣。

    Yoga 扩展了 JAX-RS 和 SpringMVC RESTful 服务器以提供 GData 和 LinkedIn 样式的字段选择器。

    • 选择您想在通话时查看的字段
    • 在单个调用中导航实体关系以获取复杂视图

    【讨论】:

      猜你喜欢
      • 2019-09-22
      • 1970-01-01
      • 2015-03-08
      • 2012-05-18
      • 1970-01-01
      • 2012-01-09
      • 2014-09-01
      • 2023-03-30
      • 1970-01-01
      相关资源
      最近更新 更多