我正在使用 spring 编写休息服务MVC产生JSON回复。它应该允许客户端仅选择响应中的给定字段,这意味着客户端可以将他感兴趣的字段作为 url 参数提及,例如?fields=field1,field2
.
使用 Jackson 注释并不能提供我想要的东西,因为它不是动态的,而且 Jackson 中的过滤器似乎也没有足够的前景。
到目前为止,我正在考虑实现一个自定义消息转换器来解决这个问题。
还有其他更好的方法来实现这一目标吗?我希望这个逻辑不与我的服务或控制器耦合。
从 Spring 4.2 开始,@JsonFilter
MappingJacksonValue 支持
- Issue : SPR-12586:支持杰克逊@JsonFilter https://jira.spring.io/browse/SPR-12586
- 犯罪 :ca06582 https://github.com/spring-projects/spring-framework/commit/ca06582f2af2e31b23031d8650148d95129ce4a1?ts=4
您可以直接将 PropertyFilter 注入到控制器中的 MappingJacksonValue 中。
@RestController
public class BookController {
private static final String INCLUSION_FILTER = "inclusion";
@RequestMapping("/novels")
public MappingJacksonValue novel(String[] include) {
@JsonFilter(INCLUSION_FILTER)
class Novel extends Book {}
Novel novel = new Novel();
novel.setId(3);
novel.setTitle("Last summer");
novel.setAuthor("M.K");
MappingJacksonValue res = new MappingJacksonValue(novel);
PropertyFilter filter = SimpleBeanPropertyFilter.filterOutAllExcept(include);
FilterProvider provider = new SimpleFilterProvider().addFilter(INCLUSION_FILTER, filter);
res.setFilters(provider);
return res;
}
或者您可以通过 ResponseBodyAdvice 声明全局策略。下面的例子通过“exclude”参数实现过滤策略。
@ControllerAdvice
public class DynamicJsonResponseAdvice extends AbstractMappingJacksonResponseBodyAdvice {
public static final String EXCLUDE_FILTER_ID = "dynamicExclude";
private static final String WEB_PARAM_NAME = "exclude";
private static final String DELI = ",";
private static final String[] EMPTY = new String[]{};
@Override
protected void beforeBodyWriteInternal(MappingJacksonValue container, MediaType contentType,
MethodParameter returnType, ServerHttpRequest req, ServerHttpResponse res) {
if (container.getFilters() != null ) {
// It will be better to merge FilterProvider
// If 'SimpleFilterProvider.addAll(FilterProvider)' is provided in Jackson, it will be easier.
// But it isn't supported yet.
return;
}
HttpServletRequest baseReq = ((ServletServerHttpRequest) req).getServletRequest();
String exclusion = baseReq.getParameter(WEB_PARAM_NAME);
String[] attrs = StringUtils.split(exclusion, DELI);
container.setFilters(configFilters(attrs));
}
private FilterProvider configFilters(String[] attrs) {
String[] ignored = (attrs == null) ? EMPTY : attrs;
PropertyFilter filter = SimpleBeanPropertyFilter.serializeAllExcept(ignored);
return new SimpleFilterProvider().addFilter(EXCLUDE_FILTER_ID, filter);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)