我有一个如下控制器,
@RequestMapping(value = "rest/v1/tester")
public class TestController {
@RequestMapping(value = "/search", method = RequestMethod.GET)
public ResponseEntity<SampleResults> search(@ModelAttribute("criteria")SampleCriteria criteria) throws Exception {
SampleResults sampleResults = sampleService.search(criteria);
return new ResponseEntity<>(sampleResults, OK);
}
}
我有另一个这样的控制器,
@RequestMapping(value = "rest/v1/second")
public class SecondTestController {
@RequestMapping(value = "/search", method = RequestMethod.GET)
public ResponseEntity<SampleResults> search(@ModelAttribute("criteria")SampleCriteria criteria) throws Exception {
SampleResults sampleResults = secondsampleService.search(criteria);
return new ResponseEntity<>(sampleResults, OK);
}
}
我的结果结构如下:
public class SampleResults extends Results<SearchSummary, Sample> {
}
这从结果类扩展:
public class Results<SUMMARY,RESULTS> {
private SUMMARY summary;
private List<RESULTS> results;
/*Constructors, getters and setters*/
}
现在,我要在结果字段中设置的模型是
@JsonDeserialize(as = SampleImpl.class)
public interface Sample {
Long getId();
void setId(Long id);
String getName();
void setName(String name);
int getAge();
void setAge(int age);
}
public class SampleImpl implements Sample {
private Long id;
private String name;
private int age;
/* Getters and Setters */
}
现在对于上面提到的TestController,我想显示json响应中的所有字段,而在SecondTestController中,我想屏蔽(不显示)json响应中的age属性。我怎样才能在春天实现这一目标。任何帮助非常感谢!
答案 0 :(得分:1)
您考虑过@JsonView
了吗?
它是supported by Spring MVC,允许您根据序列化的上下文过滤字段。
首先定义您的观点:
public class View {
interface SampleView { }
interface SampleViewWithAge extends SampleView { }
}
然后使用所需的视图注释您的字段:
public class SampleImpl implements Sample {
@JsonView(View.SampleView.class)
private Long id;
@JsonView(View.SampleView.class)
private String name;
@JsonView(View.SampleViewWithAge.class)
private int age;
// Getters and setters
}
最后注释处理程序在序列化响应时使用视图:
@JsonView(View.SampleView.class)
@RequestMapping(value = "/search", method = RequestMethod.GET)
public ResponseEntity<SampleResults> search() {
...
}
@JsonView(View.SampleViewWithAge.class)
@RequestMapping(value = "/search", method = RequestMethod.GET)
public ResponseEntity<SampleResults> searchWithAge() {
...
}
答案 1 :(得分:1)
我认为最简单的方法是使用杰克逊@JsonFilter
,如果你想要它是动态的。
例如,这里可能是Spring Boot的例子:
您的文件:
@JsonFilter("myFilter")
class Document {
private field1;
private field2;
}
修改默认配置的HttpMessageConverter:
@Configuration
class WebMvcConfiguration extends WebMvcConfigurationSupport {
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for(HttpMessageConverter<?> converter: converters) {
if(converter instanceof MappingJackson2HttpMessageConverter) {
ObjectMapper mapper = ((MappingJackson2HttpMessageConverter)converter).getObjectMapper();
mapper.setFilterProvider(new SimpleFilterProvider().addFilter("myFilter", SimpleBeanPropertyFilter.serializeAll()));
}
}
}
}
默认情况下,此过滤器将序列化全部。此步骤是强制性的,如果您没有指定它,当控制器尝试生成对象响应时,您将会遇到一个他不知道myFilter
的异常。
然后,在您的控制器中,这是您的所有字段序列化的常规端点(使用先前声明的过滤器):
@RequestMapping(value = "path/document", method = RequestMethod.GET)
public Document getDocumentWithAllFields() {
return new Document("val1","val2");
}
//result : {"field1":"val1","field2":"val2"}
现在,端点具有相同的对象,只有一些字段被序列化:
@RequestMapping(value = "path/document", method = RequestMethod.GET)
public MappingJacksonValue getDocumentWithSomeFields(@RequestParam String[] fields) {
MappingJacksonValue wrapper = new MappingJacksonValue(new Document("val1","val2"));
FilterProvider filterProvider = new SimpleFilterProvider().addFilter("myFilter",
SimpleBeanPropertyFilter.filterOutAllExcept(fields));
wrapper.setFilters(filterProvider);
return wrapper;
}
//result : {"field1":"val1"} (with 'fields' being a coma separated list, containing here just "field1"
答案 2 :(得分:0)
使用必填字段覆盖模态类中的toString方法,并在第二个控制器方法中将其转换为json,如下所示。
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
//get yourObject
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(yourObject);
答案 3 :(得分:0)
公共类BeanFilterCustom {
public Object filterBean(Object object,String someBeanFilter) {
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.filterOutAllExcept("","");
FilterProvider filters = new SimpleFilterProvider()
.addFilter(someBeanFilter, filter);
MappingJacksonValue mapping = new MappingJacksonValue(object);
mapping.setFilters(filters);
return mapping.getValue();
}
}
答案 4 :(得分:-1)
您可以在不希望包含在JSON中的字段上使用@JsonIgnore
。
public class SampleImpl implements Sample {
private Long id;
private String name;
@JsonIgnore
private int age;
/* Getters and Setters */
}