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

How to request only necessary fields using Spring and Jackson in a REST architecture?

因此,在我们的项目中,我们使用 @JsonView 来排除我们在每个请求中不想要的属性 serialiazed/called。问题是这非常粗糙,每次我们需要不同的东西时,我们都需要创建一个新的视图或在模型上注释,如下例所示:very nice guy with a blog。 我们认为这不是真正的最佳选择,而且是一种漂亮的样板式方法,所以我们希望改变这种逻辑:我们希望请求服务器只响应它想要的内容,而不是服务器只响应它想要的内容客户希望从服务器转移该责任。我不是做一个简单的 $.get,而是传递那个 $.get 的参数,我现在想要的属性(即只有名称和图片,有时是用于编辑的完整信息等)。我知道这是可能的,但我还没有找到使用 Spring 的任何方法。 我们正在使用 Spring 4.2 和 Jackson 2.6.1,并使用 AngularJS 使用 REST,所以这真的很有帮助。关于如何执行此操作或任何指导的任何想法?非常感谢您的帮助!

GET 请求:

{
   username,
   picture
}

并收到 json 响应:

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

类似的东西。

如果 serialization/deserialization 策略不起作用,那么您应该考虑使用生成器。开发你想要的东西会非常简单,但没有魔法。一些替代方案:https://github.com/ralfstx/minimal-json , http://www.javabeat.net/java-json-api-jsr-353/ , https://github.com/Homyk/JsonBuilder/wiki/JsonBuilder-WIKI .

我也需要类似的实现并使用 Jackson 完成了这个。我使用了自定义序列化程序和 java 反射。无需更改模型 classes。

// 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
}

我的 class.

的自定义序列化程序
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();
    }

}

用法:

public class App {

    public static void main(String... args) throws JsonProcessingException, IOException {

        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();

        /* initialize object */
        A a = new A(1, 2, 3);
        /* initialize a new serializer object with wanted properties and add to module */
        module.addSerializer(new ASerializer(new String[]{"_1", "_2"}));

        /* if you want to flush cached serializers */
        DefaultSerializerProvider dsp = (DefaultSerializerProvider) objectMapper.getSerializerProvider();
        dsp.flushCachedSerializers();

        objectMapper.registerModule(module);
        System.out.println(objectMapper.writeValueAsString(a));

    }

}

输出:

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

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

只需传递您感兴趣的字段,然后return根据该字段组成地图。