如何在 REST 架构中使用 Spring 和 Jackson 只请求必要的字段?
How to request only necessary fields using Spring and Jackson in a REST architecture?
因此,在我们的项目中,我们使用 @JsonView 来排除我们在每个请求中不想要的属性 serialiazed/called。问题是这非常粗糙,每次我们需要不同的东西时,我们都需要创建一个新的视图或在模型上注释,如下例所示:very nice guy with a blog。
我们认为这不是真正的最佳选择,而且是一种漂亮的样板式方法,所以我们希望改变这种逻辑:我们希望请求服务器只响应它想要的内容,而不是服务器只响应它想要的内容客户希望从服务器转移该责任。我不是做一个简单的 $.get,而是传递那个 $.get 的参数,我现在想要的属性(即只有名称和图片,有时是用于编辑的完整信息等)。我知道这是可能的,但我还没有找到使用 Spring 的任何方法。
我们正在使用 Spring 4.2 和 Jackson 2.6.1,并使用 AngularJS 使用 REST,所以这真的很有帮助。关于如何执行此操作或任何指导的任何想法?非常感谢您的帮助!
GET 请求:
{
username,
picture
}
并收到 json 响应:
{
"id":1,
"username":"john",
"picture":"/john.png"
}
类似的东西。
如果 serialization/deserialization 策略不起作用,那么您应该考虑使用生成器。开发你想要的东西会非常简单,但没有魔法。一些替代方案:https://github.com/ralfstx/minimal-json , http://www.javabeat.net/java-json-api-jsr-353/ , https://github.com/Homyk/JsonBuilder/wiki/JsonBuilder-WIKI .
我也需要类似的实现并使用 Jackson 完成了这个。我使用了自定义序列化程序和 java 反射。无需更改模型 classes。
// my sample object
public class A {
private int _1;
private int _2;
private int _3;
public A(int _1, int _2, int _3) {
this._1 = _1;
this._2 = _2;
this._3 = _3;
}
.. getters .. setters
}
我的 class.
的自定义序列化程序
public class ASerializer extends JsonSerializer<A> {
private final List<String> properties;
public ASerializer(String... properties) {
this.properties = Arrays.asList(properties);
}
@Override
public Class<A> handledType() {
return A.class;
}
@Override
public void serialize(A a, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
/* wanted property list is provided through constructor of serializer */
for (String property : this.properties) {
try {
/* field values are accessed by reflection */
Field field = a.getClass().getDeclaredField(property);
field.setAccessible(true);
Object value = field.get(a);
jgen.writeObjectField(property, value);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(ASerializer.class.getName()).log(Level.SEVERE, null, ex);
}
}
jgen.writeEndObject();
}
}
用法:
public class App {
public static void main(String... args) throws JsonProcessingException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
/* initialize object */
A a = new A(1, 2, 3);
/* initialize a new serializer object with wanted properties and add to module */
module.addSerializer(new ASerializer(new String[]{"_1", "_2"}));
/* if you want to flush cached serializers */
DefaultSerializerProvider dsp = (DefaultSerializerProvider) objectMapper.getSerializerProvider();
dsp.flushCachedSerializers();
objectMapper.registerModule(module);
System.out.println(objectMapper.writeValueAsString(a));
}
}
输出:
{"_1":1,"_2":2}
您的问题看起来非常类似于:
只需传递您感兴趣的字段,然后return根据该字段组成地图。
因此,在我们的项目中,我们使用 @JsonView 来排除我们在每个请求中不想要的属性 serialiazed/called。问题是这非常粗糙,每次我们需要不同的东西时,我们都需要创建一个新的视图或在模型上注释,如下例所示:very nice guy with a blog。 我们认为这不是真正的最佳选择,而且是一种漂亮的样板式方法,所以我们希望改变这种逻辑:我们希望请求服务器只响应它想要的内容,而不是服务器只响应它想要的内容客户希望从服务器转移该责任。我不是做一个简单的 $.get,而是传递那个 $.get 的参数,我现在想要的属性(即只有名称和图片,有时是用于编辑的完整信息等)。我知道这是可能的,但我还没有找到使用 Spring 的任何方法。 我们正在使用 Spring 4.2 和 Jackson 2.6.1,并使用 AngularJS 使用 REST,所以这真的很有帮助。关于如何执行此操作或任何指导的任何想法?非常感谢您的帮助!
GET 请求:
{
username,
picture
}
并收到 json 响应:
{
"id":1,
"username":"john",
"picture":"/john.png"
}
类似的东西。
如果 serialization/deserialization 策略不起作用,那么您应该考虑使用生成器。开发你想要的东西会非常简单,但没有魔法。一些替代方案:https://github.com/ralfstx/minimal-json , http://www.javabeat.net/java-json-api-jsr-353/ , https://github.com/Homyk/JsonBuilder/wiki/JsonBuilder-WIKI .
我也需要类似的实现并使用 Jackson 完成了这个。我使用了自定义序列化程序和 java 反射。无需更改模型 classes。
// my sample object
public class A {
private int _1;
private int _2;
private int _3;
public A(int _1, int _2, int _3) {
this._1 = _1;
this._2 = _2;
this._3 = _3;
}
.. getters .. setters
}
我的 class.
的自定义序列化程序public class ASerializer extends JsonSerializer<A> {
private final List<String> properties;
public ASerializer(String... properties) {
this.properties = Arrays.asList(properties);
}
@Override
public Class<A> handledType() {
return A.class;
}
@Override
public void serialize(A a, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
/* wanted property list is provided through constructor of serializer */
for (String property : this.properties) {
try {
/* field values are accessed by reflection */
Field field = a.getClass().getDeclaredField(property);
field.setAccessible(true);
Object value = field.get(a);
jgen.writeObjectField(property, value);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(ASerializer.class.getName()).log(Level.SEVERE, null, ex);
}
}
jgen.writeEndObject();
}
}
用法:
public class App {
public static void main(String... args) throws JsonProcessingException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
/* initialize object */
A a = new A(1, 2, 3);
/* initialize a new serializer object with wanted properties and add to module */
module.addSerializer(new ASerializer(new String[]{"_1", "_2"}));
/* if you want to flush cached serializers */
DefaultSerializerProvider dsp = (DefaultSerializerProvider) objectMapper.getSerializerProvider();
dsp.flushCachedSerializers();
objectMapper.registerModule(module);
System.out.println(objectMapper.writeValueAsString(a));
}
}
输出:
{"_1":1,"_2":2}
您的问题看起来非常类似于:
只需传递您感兴趣的字段,然后return根据该字段组成地图。