Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring MVC中的Jackson场滤波器_Java_Json_Spring_Spring Mvc_Jackson - Fatal编程技术网

Java Spring MVC中的Jackson场滤波器

Java Spring MVC中的Jackson场滤波器,java,json,spring,spring-mvc,jackson,Java,Json,Spring,Spring Mvc,Jackson,我有一个spring启动应用程序,需要从RequestParam中筛选响应体 例如: // DTO public class PersonDTO { private Long id; private String firstName; private String lastName; } // Controller public class PersonController { @GetMapping(va

我有一个spring启动应用程序,需要从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);
      }
   }
返回所有person,响应仅包含firstName和lastName:

我发现了这个API,但过滤器用作注释,如下所示:

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,因为字段过滤器的列表是由客户端管理的,对于每个调用和我的实际有效负载数据,它可能是不同的,以包含大量字段

我也发现了这个API,但它对我不起作用,而且响应类型是MappingJacksonValue,而不是ResponseEntity>


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

我找到了这个临时解决方案:

@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;
   }
欢迎任何其他建议

您可以将Jackson lib的注释@JsonIgnore添加到过滤器字段id:


这来自我的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);

    }

PersonDto只是一个例子!在本例中,过滤器可以是一些字段id&firstName-lastName&firstName-id-firstName….的组合。。。。因此,如果我们为特定字段添加注释@JsonIgnore,过滤器就不能是动态的,请看我的回答,这里也有同样的问题。我不敢相信没有一个干净简单的方法可以做到这一点。除了你写的答案,你有没有找到其他解决这个问题的方法?我试图更改spring配置来检索ObjectMapper,并在调用ResponseEntity返回之前对其进行配置,但是我还遇到了其他一些奇怪的问题,我不知道如何解决,这让我觉得这不是解决问题的正确方法。我在下面添加了一个临时解决方案
@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;
   }
public class PersonDTO implements Serializable
{
  @JsonIgnore
  private Long id;
  private String firstName;
  private String lastName;
}
    @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);

    }