Java Spring MVC中的Jackson场滤波器
我有一个spring启动应用程序,需要从RequestParam中筛选响应体 例如: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
// 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);
}