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

修改REST API响应以仅包括查询参数中请求的字段

公冶弘壮
2023-03-14

我想发送只包含GET api请求字段的响应。减少响应的总大小。

例如,默认行为,当请求特定字段时

GET /v1/users/

{
   "data" : 
     [
        {
            "name" : "User1",
            "phone" : "800-999-9999",
            "city" : "XYZ1",
            "country" : "PQR1"
        },
        {
            "name" : "User2",
            "phone" : "800-999-9999",
            "city" : "XYZ2",
            "country" : "PQR2"
         }
     ]
}

用例,其中所需字段作为查询参数传递

GET /v1/users/?fields=name,city

{
   "data" : 
     [
        {
            "name" : "User1",
            "city" : "XYZ1"
        },
        {
            "name" : "User2",
            "city" : "XYZ2"
         }
     ]
}

遇到”https://github.com/monitorjbl/json-view“。但被球队击落。

如何使用spring boot实现此功能?使用java微服务的组织如何实现此功能?谢谢

共有2个答案

微生毅
2023-03-14

以下是另一种方法:

假设1:我认为最好将控制器的返回类型定义为域对象,让spring单独处理它到JSON的转换(不像@Alexander Pavlov的答案)。对于一般代码的可读性,对于像swagger这样的工具来说,IMO更好,因为它可以内省控制器,并且应该知道应该返回什么。

假设2:用户类中没有原语。

好的,现在控制器显然调用了一些“服务”,对数据库进行一些查询,或者通常执行一些逻辑,最终生成用户列表(您返回给客户机的列表)。返回对象应该如下所示:

class Users {

     private List<User> data;
}

class User { // + constructors, getters, setters, etc.
   private String name;
   private String city;
   private String phone;
   private String country;    
}

在这种情况下,在服务中,您可以在不希望返回的字段中放置“null”:

User user = new User("John", "LA", null, null); // you only have name and city

现在,您可以将注释@JsonAccde(包括。NON_NULL)类User上的,这将指示Jackson根本不将值为null的字段包含到序列化响应中。

如果希望全局应用此行为,可以配置ObjectMapperbean:

 ObjectMapper mapper = new ObjectMapper();
 mapper.setSerializationInclusion(Include.NON_NULL);
林念
2023-03-14

方法1:将对象转换为映射,删除多余的键,将映射转换为Json

@GetMapping("/v1/users")
@ResponseBody
public List<Map> getUsers(@RequestParam(required = false) Set<String> fields) { 
    List<User> users = ...;
    ObjectMapper oMapper = new ObjectMapper();
    return users.stream().map(u -> oMapper.convertValue(u, Map.class))
       .peek(map -> { 
          if (fields != null) map.keySet().retainAll(fields)
       })
       .collect(Collectors.toList());
}

方法二:使用Gson

@GetMapping("/v1/users")
@ResponseBody
public String getUsers(@RequestParam(required = false) Set<String> fields) { 
    List<User> users = ...;
    Gson gson = new GsonBuilder()
            .setExclusionStrategies(new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(FieldAttributes f) {
                    return f.getDeclaringClass().equals(User.class)
                             && fields != null 
                             && !fields.contains(f.getFieldName())
                            ;
                }

                @Override
                public boolean shouldSkipClass(Class<?> clazz) {
                    return false;
                }
            }).create();
    return gson.toJson(users); 
}

遇到”https://github.com/monitorjbl/json-view“。但被球队击落。

顺便说一句,Jackson支持@JsonView注释,但不允许根据需要动态包含/排除字段。您可以定义字段子集,然后返回这些子集

public class Views {
    public static class Short {
    }
}

public class User {
    @JsonView(Views.Short.class)
    public String city;

    @JsonView(Views.Short.class)
    public String name;

    public String phone;

    public String country;
}

@GetMapping("/v1/users")
@ResponseBody
public String getUsers(@RequestParam(required = false) boolean shortView) { 
    List<User> users = ...;
    ObjectMapper mapper = new ObjectMapper();
    if (shortView) mapper = mapper.writerWithView(Views.Short.class);
    return mapper.writeValueAsString(users);
}
 类似资料:
  • 自1.14.0开始,zuul网关支持动态修改请求参数。即在网关修改客户端传递过来的参数,然后发送到微服务端。 客户端参数{"name": "jim"} --> zuul中修改为{"name": "Lucy"} --> 微服务端将收到{"name": "Lucy"} 使用场景:客户端请求参数经过加密,在网关解密后,再次发送明文参数给微服务端 如何使用 在网关springboot启动函数中添加如下代

  • 我有一个apikey“令牌”,它必须在每个请求中作为查询参数提供。我如何设置翻新,以便始终在请求中包含此查询参数? 我当前将内标识作为默认参数提供: 但是由于我知道每个请求都需要相同的令牌,所以在我创建的每个请求函数中必须提供它作为默认参数,这感觉是多余的。我如何设置reverfit来用默认的查询参数修饰每个传出的请求? 这是我如何构建reverfit2实例的: 我认为在调用.build()之前,

  • 我创建了一个带有参数的API,如下所示: 我在body->表单数据中传递了。 然后我在《邮递员》上得到了这样一条消息: 有人知道为什么会有这个消息吗?我们如何在Rest API请求中传递一个映射作为参数?我们怎样才能通过邮递员传递地图?

  • 问题内容: 因此,像往常一样,我尝试在SO上找到这个问题,但还是没有运气。 我知道答案是“是的,您可以修改req对象”,但是关于req对象参数什么也没说。 例如,以下代码将引发错误: 错误: 我想这与没有“ SET”方法的属性有关,或者与之类似。 在某些情况下可以派上用场。 一种将快速链接转换为完整请求并代理这些请求的服务。 只需修改参数,然后再将其发送给您不想修改的其他功能。 问题 是,有没有办

  • 我依赖于retrofit2,该retrofit2配置为使用RxJava包装响应,并使用GSon解析它们。 我在用Reterfit做Rest服务。 search REST服务返回一个JSON null 它为我的接口生成服务,并使用解析响应,并用包装它。 然后我获得服务: 请注意,我不编写这个服务的代码,因为retrofit工作时,它使用我的接口()注释自动生成服务。 如果用户使用执行搜索调用,则不会

  • 在SQL中,使用字符串连接进行参数化查询非常简单。例如,我根据预设的参数(带有列名的字符串)从DB表中获取必要的列 我如何用这个做同样的事情(你也可以做你自己的例子)查询DSL请求: 在此查询中,我得到了整个表。

  • 我有一个查询字符串,可以是: 编辑:参数值的长度可以大于2 有人知道在String.ReplaceAll([regex],[replace])中使用什么好的regex表达式吗?

  • 本文向大家介绍springcloud 中 zuul 修改请求参数信息的方法,包括了springcloud 中 zuul 修改请求参数信息的方法的使用技巧和注意事项,需要的朋友参考一下 Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器.   Zuul功能: 认证 压力测试 金丝雀测试 动态路由 负载削减 安全 静态响应处理 主动/主动交换管理 Zuul的规则引擎允许通过任何JVM