Java 如何在REST体系结构中使用Spring和Jackson只请求必要的字段?

Java 如何在REST体系结构中使用Spring和Jackson只请求必要的字段?,java,json,hibernate,spring-mvc,jackson,Java,Json,Hibernate,Spring Mvc,Jackson,因此,在我们的项目中,我们使用@JsonView来排除我们不希望在每个请求中序列化/调用的属性。问题是这是非常粗糙的,每次我们需要一些不同的东西时,我们都需要在模型上创建一个新的视图或注释,如下示例:。 我们认为这并不是一个真正的最佳方法,也是一个非常简单的方法,因此我们希望改变这种逻辑:服务器不只是响应它想要的,我们希望请求服务器只响应客户端想要的,将这种责任从服务器移开。我不做简单的$.get,而是传递该$.get的参数。获取我现在想要的属性(即,只有名称和图片,有时是用于编辑的完整信息等)

因此,在我们的项目中,我们使用@JsonView来排除我们不希望在每个请求中序列化/调用的属性。问题是这是非常粗糙的,每次我们需要一些不同的东西时,我们都需要在模型上创建一个新的视图或注释,如下示例:。 我们认为这并不是一个真正的最佳方法,也是一个非常简单的方法,因此我们希望改变这种逻辑:服务器不只是响应它想要的,我们希望请求服务器只响应客户端想要的,将这种责任从服务器移开。我不做简单的$.get,而是传递该$.get的参数。获取我现在想要的属性(即,只有名称和图片,有时是用于编辑的完整信息等)。我知道这是可能的,但我还没有找到使用Spring实现这一点的任何方法。 我们正在使用Spring 4.2和Jackson 2.6.1,并使用AngularJS使用其余部分,因此这将非常有用。有没有关于如何做到这一点的想法或指导?真的谢谢你的帮助

获取请求:

{
   username,
   picture
}
并接收json响应:

{  
   "id":1,
   "username":"john",
   "picture":"/john.png"
}

沿着这条线。

如果序列化/反序列化策略不起作用,那么你应该考虑使用Builder。这将是相当直接的发展你想要的,但没有魔术。一些替代方案:,,。

我也需要类似的实现,并使用Jackson实现了这一点。我使用了自定义序列化程序和java反射。不需要更改模型类

// my sample object
public class A {

    private int _1;
    private int _2;
    private int _3;

    public A(int _1, int _2, int _3) {
        this._1 = _1;
        this._2 = _2;
        this._3 = _3;
    }
    .. getters .. setters
}
我的类的自定义序列化程序

public class ASerializer extends JsonSerializer<A> {

    private final List<String> properties;

    public ASerializer(String... properties) {
        this.properties = Arrays.asList(properties);
    }

    @Override
    public Class<A> handledType() {
        return A.class;
    }

    @Override
    public void serialize(A a, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {

        jgen.writeStartObject();
        /* wanted property list is provided through constructor of serializer */
        for (String property : this.properties) {
            try {
                /* field values are accessed by reflection */
                Field field = a.getClass().getDeclaredField(property);
                field.setAccessible(true);
                Object value = field.get(a);
                jgen.writeObjectField(property, value);
            } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
                Logger.getLogger(ASerializer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        jgen.writeEndObject();
    }

}
产出:

{"_1":1,"_2":2}

您的问题看起来非常类似于:


只需传递您感兴趣的字段,然后根据这些字段返回合成的映射。

这与过滤掉我不想给出的字段没有什么不同,因为我仍然需要单独构建每个请求。我使用了一些泛型类型,所以这不是一个很好的解决方法。另外,序列化和反序列化工作正常,我只想过滤掉我不想为每个请求接收的字段。也不是必须为每个对象设置视图的样板,这很麻烦,甚至让人更头疼……它将使您能够构建逻辑,返回请求中指定的字段,而不是使用spring在服务器上指定的字段。这个逻辑可以被提取到一个我相信的方法中,而不是复制。这听起来像是过滤器()的一个用途,但我没有使用它们,所以不能给出正确的答案。@araqnid是的,我正在使用这些过滤器。但是我需要定义我在自己的模型类(在hibernate/ORM映射上)上为视图提供的内容,然后我需要指定一个控制器来返回这些视图。我想颠倒这种逻辑,分别请求每个信息,而不必在服务器上定义它。这仍然是常见的方法吗?
{"_1":1,"_2":2}