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

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

能钟展
2023-03-14

因此,在我们的项目中,我们使用@JsonView来排除我们在每个请求中不希望被序列化/调用的属性。问题是这是非常粗糙的,每当我们需要不同的东西时,我们都需要创建一个新的视图或在模型上注释,按照这个例子:非常好的家伙和博客。我们认为这并不是一个非常理想的方法,而是一种非常样板式的方法来做到这一点,所以我们希望改变这个逻辑:而不是服务器只响应它想要的东西,我们希望请求服务器只响应客户端想要的东西,从服务器转移这个责任。我不会做一个简单的$.get,而是传递那个$.get的参数,这是我目前想要的属性(即只有名称和图片,有时是编辑的完整信息等)。我知道这是可能的,但我无法找到任何使用Spring执行此操作的方法。我们使用的是Spring 4.2 和杰克逊 2.6.1,并使用 AngularJS 的 REST,所以这真的很有帮助。关于如何做到这一点的任何想法,或任何指导?真的谢谢你的帮助!

获取请求

{
   username,
   picture
}

并接收一个json响应:

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

沿着这些路线。

共有3个答案

翟昊明
2023-03-14

我也需要类似的实现,并使用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();
    }

}

用法:

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}
李光华
2023-03-14

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

东门文斌
2023-03-14

你的问题看起来很像:

Spring架控制器返回特定字段

只需传递您感兴趣的字段,并根据该字段返回合成的地图。

 类似资料:
  • 问题内容: 我已经使用Jackson / JSON对Spring REST进行了很好的设置,并且一切正常。 但是我故意在消息的结构中引入了一个错误,导致400-错误的请求。但是服务器上没有日志输出。我所期望的错误将是“杰克逊未知属性异常”之类的东西,但它被捕获,并且向客户端发送了400错误,但服务器上没有该异常的日志。 我不想明确调试服务器上的所有内容,但是我想要像这样的Spring网络级异常明确

  • 我使用Jackson/JSON设置了SpringREST,一切正常。 但是我故意在消息结构中引入了一个错误,导致400-错误请求。但是服务器上没有日志输出。我期望的错误会是类似“杰克逊未知属性异常”之类的东西,但它被捕获并将400错误发送到客户端,但服务器上没有异常日志。 我不想清楚地调试服务器上的一切,但我希望像这样的Spring网络级异常清楚地标记为错误。 正确的方法是什么? 谢谢

  • 每当我发布到django rest framework(DRF)endpoint时,我都会不断收到响应。但是,考虑到下面的curl示例,我显然指定了一个值。 无论Content-Type(应用程序/json、应用程序/x-wow-form-urlencoded、多部分/form-data)如何,都会发生这种情况。它唯一有效的时间是当我使用DRF网络界面上的“超文本标记语言表单”(相对于“原始数据”

  • 更改TestResource 并向QueryFactory添加 我理解使用请求范围需要。然而,当我运行它时,我得到一个异常,它告诉我 我看不出哪里出了问题。你能给我指出这个配置应该如何正确地完成吗?

  • 从文件中: read_only将其设置为True,以确保在序列化表示时使用该字段,而在反序列化期间更新实例时不使用该字段。 默认为假 required通常情况下,如果反序列化期间未提供字段,则会引发错误。如果反序列化过程中不需要此字段,则设置为false。 默认为True。 因此,我有一个模型,其中有一个字段不可为null,但我希望在pre_save方法中填充它,因此我在serializer中将该

  • 在我的Play(Java)框架项目中,我正在使用Guice进行依赖项注入,并且正在努力理解如何最好地将“会话”的概念与Guice和Play结合使用? 我知道Play是无状态的,除了可以在cookie中存储值之外,实际上没有会话的概念。我对Guice和Play的理解是,虽然Guice文档描述了支持不同的作用域(单例、会话、请求、无作用域),但因为我们正在用每个请求实例化一个新的注入器,所以仅适用于P