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

Spring MVC中的Jackson Field过滤器

方谦
2023-03-14

我有一个spring boot应用程序,需要从RequestParam中筛选响应体

例子:

  // DTO
   public class PersonDTO
   {
      private Long id;
      private String firstName;
      private String lastName;
   }

   // Controller
   public class PersonController
   {
      @GetMapping(value = "/person")
      public ResponseEntity<List<PersonDTO>> getPerson(@RequestParam(required = false) String filters)
      {
         List<PersonDTO> personList = myservoce.getPerson();
         return new ResponseEntity<List<PersonDTO>>(personList, HttpStatus.OK);
      }
   }

客户端查询示例:

返回不带字段过滤器的所有人员

http://localhost:8080/person

[
  {
    "id": 123,
    "firstName": "toto1",
    "lastName": "titi2"
  },
  {
    "id": 345,
    "firstName": "toto2",
    "lastName": "titi2"
  }
]

返回所有的人和响应只包含firstName和lastName:http://localhost:8080/person?filters=firstName, lastName

[
  {
    "firstName": "toto1",
    "lastName": "titi2"
  },
  {
    "firstName": "toto2",
    "lastName": "titi2"
  }
]

我已经找到了这个API"jackson-动态-过滤器",但是过滤器被用作这样的注释:

public class PersonController
{
   @FilterOutAllExcept({"firstName", "lastName"})
   @GetMapping(value = "/person")
   public ResponseEntity<List<PersonDTO>> getPerson( @RequestParam(required = false) String filters )
   {
      List<PersonDTO> personList = myservoce.getPerson();
      return new ResponseEntity<List<PersonDTO>>(personList, HttpStatus.OK);
   }
}

在我的情况下,我不能使用这个API,因为字段过滤器的列表是由客户端管理的,它可以为每个调用而不同,我的实际有效载荷Dto包含很多字段

我还发现了这个API“jackson antpathfilter”,但它不适合我,而且响应类型是MappingJacksonValue,而不是ResponseEntity

知道如何用spring应用程序配置这个用例吗?

共有3个答案

穆季萌
2023-03-14

您可以将Jackson lib的注释@JsonIgnore添加到筛选字段id

public class PersonDTO implements Serializable
{
  @JsonIgnore
  private Long id;
  private String firstName;
  private String lastName;
}
裴意
2023-03-14

这是来自我的web服务,您可以使用此代码并适应您的模型和存储库。从这里,你可以创建一个通用服务,并在任何需要的地方调用修改后的版本。

    @RequestMapping(value = "/entidades/{id}/campos", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "Retrieves requested object fields", response = Entidade.class)
    public ResponseEntity<Map<String, Object>> getFields(@Valid @PathVariable Long id, @RequestParam String campos) {
        final Optional<Entidade> ent = entidadeRepository.findById(id);
        final String[] camposArr = campos.split(",");

        if (ent.isPresent()) {
            final Entidade e = ent.get();
            Map<String, Object> result = new HashMap<>();
            for (String campo : camposArr) {
                String methodName = "get" + (campo.substring(0, 1).toUpperCase() + campo.substring(1));
//                System.out.println(campo);
                try {
                    Method method = e.getClass().getMethod(methodName);
//                    System.out.println(method.invoke(e));
                    result.put(campo, method.invoke(e));
                } catch (Exception err) {
                }

            }
            return new ResponseEntity<>(result, HttpStatus.OK);

        }
        return new ResponseEntity<>(HttpStatus.NOT_FOUND);

    }
爱乐邦
2023-03-14

我找到了暂时的解决办法:

@ControllerAdvice
public class JsonFilterAdvice implements ResponseBodyAdvice<List<?>>
{

   @Override
   public List<?> beforeBodyWrite(
      List<?> arg0,
      MethodParameter arg1,
      MediaType arg2,
      Class<? extends HttpMessageConverter<?>> arg3,
      ServerHttpRequest arg4,
      ServerHttpResponse arg5)
   {
      HttpServletRequest servletRequest = ((ServletServerHttpRequest) arg4).getServletRequest();
      String[] params = servletRequest.getParameterValues("filters");
      if (params != null)
      {
        // parse object and set field to null
      }
      return arg0;
   }

   @Override
   public boolean supports(MethodParameter arg0, Class<? extends HttpMessageConverter<?>> arg1)
   {
      // return true if method parameters contain 'filters' field
      return true;
   }

欢迎提出任何其他建议

 类似资料:
  • 我对和的用途有点困惑。 正如我从文档中理解的,拦截器在请求之间运行。另一方面,Filter在呈现视图之前运行,但在Controller呈现响应之后运行。 那么,拦截器中的和过滤器中的之间的区别在哪里呢?

  • 问题内容: 我的应用程序中有2个过滤器。根据某些条件,我想选择是否执行第二个过滤器。有没有办法做到这一点? 我做了一些谷歌搜索,但没有成功。我希望请求继续执行而不执行第二个过滤器。那可能吗? 任何帮助将不胜感激。 问题答案: 您可以在请求中设置一个属性,然后在第二个过滤器中对其进行检查。 您可以像这样简化上面的代码: 这样,您只需检查属性“ executeSecondFilter”的存在

  • 本文向大家介绍利用SpringMVC过滤器解决vue跨域请求的问题,包括了利用SpringMVC过滤器解决vue跨域请求的问题的使用技巧和注意事项,需要的朋友参考一下 之前写过通过注释的方法解决跨域请求的方法,需要每次都在controll类使用注解,这次通过springmvc的拦截器解决: 继承SpringMVC的类HandlerInterceptor重写preHandle方法,这个方法会在到达

  • 如何在执行查询前过滤ElasticSearch2.2中的文档。我引用了这个页面,但仍然无法框出正确的查询。 https://www.elastic.co/guide/en/elasticsearch/reference/2.2/query-filter-context.html 这就是我想做的…我有很多应该从句,每个有2个必须从句。WOLLE子句中的任何一个都应该匹配以检索文档。我只包括了一个sh

  • 问题内容: 我想删除原始数组(是)中的特定元素。我那个数组,并返回新的数组。但这不会影响此代码中的原始数组。我如何轻松地从原始数组中删除那些元素? 问题答案: 该方法不仅用于收集元素集,而且还用于收集元素集。如果您想通过评估条件来获得一项,那么您还有其他三种选择。,并因此只有当你想对多个项目的操作,你应该考虑使用过滤功能。就需要完成的工作而言,没有一个答案是完整的。他们使用过滤器功能隔离一个集合(

  • 问题内容: 我正在建立一个显示api数据的项目,现在我需要对其进行过滤。 我已经完成了类别过滤器,现在我必须做一个价格范围过滤器,以便这两个过滤器可以一起工作,但是我在努力正确地做到这一点。对于价格范围过滤器,我使用2个输入和一个Submit按钮。 我得到了一系列对象,看起来像这样; 我有状态: 如果我的弯管机状态已更改,则设置状态的功能另外,对于开始状态和结束状态,也有类似的功能当我为价格设置状

  • 问题内容: 我是这个框架的新手,因此练习Angularjs并遵循网站上提供的教程。 有一个示例,我们可以搜索表中存在的数据,示例如下, 在上面的代码中,我可以使用两个不同的输入来搜索手机,即按型号名称搜索和按公司名称搜索,以上代码运行良好, 但是,如果我需要使用选择选项中存在的搜索类型进行搜索,该怎么办? 代码如下 从上面的代码中,您可以看到我正在尝试通过选择框中显示的“姓名”,“公司”或“名称”

  • 问题内容: “过滤后的查询和过滤器”与“根查询和过滤器”之间有什么区别吗?例如 情况1: 情况2: 我在http://elasticsearch-users.115913.n3.nabble.com/Filtered-query-vs-using- filter-outside-td3960119.html中 找到了此讨论,但所引用的URL是404,并且解释过于简洁我。 请示教或提供指出这些区别的