如何筛选从spring rest web服务返回的json响应
如何筛选从spring rest web服务返回的json响应。如何筛选从spring rest web服务返回的json响应
当使用调用customEvents时,我只需要输出eventId和Event名称。当询问特定事件我需要 发送事件的全部细节。
Class CustomEvent{
long id;
String eventName;
Account createdBy;
Account modifiedBy;
..
}
Class Account{
long id;
String fname;
String lname;
....
}
@Controller
public class CustomEventService
{
@RequestMapping("/customEvents")
public @ResponseBody List<CustomEvent> getCustomEventSummaries() {}
@RequestMapping("/customEvents/{eventId}")
public @ResponseBody CustomEvent getCustomEvent(@PathVariable("eventId") Long eventId) {}
}
我该如何达到上述目的?目前我正在使用spring 3.1。它是否支持3.1版本以上版本或更高版本
我可以想到两种解决方案,它们都利用了Jackson的mixin功能。
如果您所描述的内容将被复制到代码的其他部分,则第一个解决方案要复杂得多,但这是一个非常棒的方法,请参阅this链接。 会发生什么是你定义了一个方面,它应用了你在JsonFilter注解中设置的特定混合(在你的情况下是CustomEventMixin)。
第二种解决方案是简单得多,并包括使用在自己的杰克逊对象映射器(而不是委托该责任字符串),如下面的代码
@Controller
public class EventController {
private ObjectMapper objectMapper = new ObjectMapper();
public EventController(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
objectMapper.addMixInAnnotations(CustomEvent.class, CustomEventMixin.class);
}
@RequestMapping("/customEvents")
@ResponseBody
public String suggest() {
return objectMapper.writeValueAsString(getCustomEvents(), new TypeReference<List<CustomEvent>>() {});
}
}
在您需要定义根据CustomEventMixin两种情况杰克逊规则
UPDATE:
一个例子的混合类将是(说你要忽略ID)
public interface CustomEventMixin {
String name;
@JsonIgnore
String id;
}
您可以使用@JsonFilter进行存档。
POJO的:
@JsonFilter("myFilter")
public class User {
....
}
控制器:
public String getUser(
@RequestParam(value="id") String id,
@RequestParam(value="requiredFields",required=false) String requiredFields
) throws JsonParseException, JsonMappingException, IOException {
//Get User
User user = userService.getUser(id);
//Start
ObjectMapper mapper = new ObjectMapper();
// and then serialize using that filter provider:
String json="";
try {
if (requiredFields!= null) {
String[] fields = requiredFields.split("\\,");
FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter",
SimpleBeanPropertyFilter.filterOutAllExcept(new HashSet<String>(Arrays
.asList(fields))));
json = mapper.filteredWriter(filters).writeValueAsString(user);//Deprecated
} else {
SimpleFilterProvider fp = new SimpleFilterProvider().setFailOnUnknownId(false);
mapper.setFilters(fp);
json =mapper.writeValueAsString(user);
}
} catch (JsonGenerationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return json;
}
获取网址:..... &使用requiredfields = ID,名字,年龄
可以使用@JsonView注释本目的。但不幸的是,它仅适用于4.x及更高版本。
这是我知道的最彻底的方法:
public class View {
public interface Summary {}
public interface Details extends Summary{}
}
Class CustomEvent{
@JsonView(View.Summary.class)
long id;
@JsonView(View.Summary.class)
String eventName;
@JsonView(View.Details.class)
Account createdBy;
@JsonView(View.Details.class)
Account modifiedBy;
}
@Controller
public class CustomEventService
{
@JsonView(View.Summary.class)
@RequestMapping("/customEvents")
public @ResponseBody List<CustomEvent> getCustomEventSummaries() {}
@RequestMapping("/customEvents/{eventId}")
public @ResponseBody CustomEvent getCustomEvent(@PathVariable("eventId") Long eventId) {}
}
请记住,由不具备@JsonView注释默认字段也序列化。这就是为什么你需要注解他们。
欲了解更多信息,请阅读:https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring
我有我的现有项目类似的要求。作为单个对象被多个控制器使用,引入视图是一种痛苦。这也不是一个干净的解决方案来实现过滤器。所以我决定在发送给客户端之前,从Controller中的DTO中清除这些值。所以我自己的方法(这可能需要更多的执行时间)来解决这个问题。
public static void includeFields(Object object, String... includeFields) {
for (PropertyDescriptor propertyDescriptor : PropertyUtils.getPropertyDescriptors(object)) {
if (!Arrays.asList(includeFields).contains(propertyDescriptor.getName())) {
clearValues(object, propertyDescriptor);
}
}
}
public static void excludeFields(Object object, String... includeFields) {
for (PropertyDescriptor propertyDescriptor : PropertyUtils.getPropertyDescriptors(object)) {
if (Arrays.asList(includeFields).contains(propertyDescriptor.getName())) {
clearValues(object, propertyDescriptor);
}
}
}
private static void clearValues(Object object, PropertyDescriptor propertyDescriptor) {
try {
if(propertyDescriptor.getPropertyType().equals(boolean.class)) {
PropertyUtils.setProperty(object, propertyDescriptor.getName(), false);
} else {
PropertyUtils.setProperty(object, propertyDescriptor.getName(), null);
}
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
//TODO
e.printStackTrace();
}
}
缺点是boolean
字段将总是具有值,从而将存在于所述有效载荷。至少这帮助我给出了动态解决方案并减少了有效载荷中的许多领域。
PropertyUtils在哪里? –
该类是'org.apache.commons.beanutils.PropertyUtils',你可以在'commons-beanutils.jar'中找到它。 – Maz
您是否使用Jackson映射到JSON与MappingJacksonHttpMessageConverter或MappingJackson2HttpMessageConverter? – geoand
从getCustomEventSummaries()返回'Map '是什么问题?或者将'CustomEvent'的所有其他特性设置为'null'。 –
我正在使用MappingJackson2HttpMessageConverter – Sam