禁用每个 ObjectMapper 的字段序列化
Disable field serialization per ObjectMapper
我正在使用 application/json
Content-Type(服务器)开发 REST 应用程序。我也在为它开发 REST 客户端库(客户端)。服务器和客户端都使用相同的 Jackson 注释 classes/resources.
我的一个服务器用例包括添加一个应该是只写的字段(只启用反序列化)。我这样做:
public class MyClass {
@JsonProperty(access = WRITE_ONLY)
private String field;
...
}
但是,由于此 class 也在客户端使用,因此我无法将值发送到此字段,因为序列化处理会跳过它。我希望客户端能够序列化该字段。服务器和客户端使用单独的对象映射器。
我可以使用 JsonSerializer<MyClass>
的单独实现并将其设置为对象映射器,但这意味着我必须手动序列化所有其他字段。我不要这个。
我想知道,是否有某种方法可以指示对象映射器(或向其中注入一些东西)以不同方式处理此类字段?
当您在两侧使用通用模型 classes 时:客户端和服务器,您可以使用 com.fasterxml.jackson.databind.Module
class 及其实现来注册所有差异。如果某些 Jackson
配置仅在一侧可用,您可以将其移至 MixIn classes/interfaces 并仅在给定一侧注册。
简单示例:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.IOException;
public class ClientServerApp {
public static void main(String[] args) throws IOException {
// Client side
ObjectMapper clientMapper = JsonMapper.builder().build();
// create payload on client side
MyClass instance = new MyClass(1, "fieldValue");
String payload = clientMapper.writeValueAsString(instance);
// send to server
System.out.println("Send: " + payload);
// ..
// Server side
ObjectMapper serverMapper = JsonMapper.builder()
.addModule(new ServerModule())
.build();
MyClass deserialized = serverMapper.readValue(payload, MyClass.class);
System.out.println("Deserialized: " + deserialized);
System.out.println("Payload on server side: " + serverMapper.writeValueAsString(deserialized));
}
}
class ServerModule extends SimpleModule {
public ServerModule() {
setMixInAnnotation(MyClass.class, MyClassServerMixIn.class);
// add other configuration
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class MyClass {
private int id;
private String field;
}
interface MyClassServerMixIn {
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
String getField();
}
以上代码打印:
Send: {"id":1,"field":"fieldValue"}
Deserialized: MyClass(id=1, field=fieldValue)
Payload on server side: {"id":1}
如您所见,只有 ObjectMapper
在客户端可以序列化 field
属性.
我正在使用 application/json
Content-Type(服务器)开发 REST 应用程序。我也在为它开发 REST 客户端库(客户端)。服务器和客户端都使用相同的 Jackson 注释 classes/resources.
我的一个服务器用例包括添加一个应该是只写的字段(只启用反序列化)。我这样做:
public class MyClass {
@JsonProperty(access = WRITE_ONLY)
private String field;
...
}
但是,由于此 class 也在客户端使用,因此我无法将值发送到此字段,因为序列化处理会跳过它。我希望客户端能够序列化该字段。服务器和客户端使用单独的对象映射器。
我可以使用 JsonSerializer<MyClass>
的单独实现并将其设置为对象映射器,但这意味着我必须手动序列化所有其他字段。我不要这个。
我想知道,是否有某种方法可以指示对象映射器(或向其中注入一些东西)以不同方式处理此类字段?
当您在两侧使用通用模型 classes 时:客户端和服务器,您可以使用 com.fasterxml.jackson.databind.Module
class 及其实现来注册所有差异。如果某些 Jackson
配置仅在一侧可用,您可以将其移至 MixIn classes/interfaces 并仅在给定一侧注册。
简单示例:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.IOException;
public class ClientServerApp {
public static void main(String[] args) throws IOException {
// Client side
ObjectMapper clientMapper = JsonMapper.builder().build();
// create payload on client side
MyClass instance = new MyClass(1, "fieldValue");
String payload = clientMapper.writeValueAsString(instance);
// send to server
System.out.println("Send: " + payload);
// ..
// Server side
ObjectMapper serverMapper = JsonMapper.builder()
.addModule(new ServerModule())
.build();
MyClass deserialized = serverMapper.readValue(payload, MyClass.class);
System.out.println("Deserialized: " + deserialized);
System.out.println("Payload on server side: " + serverMapper.writeValueAsString(deserialized));
}
}
class ServerModule extends SimpleModule {
public ServerModule() {
setMixInAnnotation(MyClass.class, MyClassServerMixIn.class);
// add other configuration
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class MyClass {
private int id;
private String field;
}
interface MyClassServerMixIn {
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
String getField();
}
以上代码打印:
Send: {"id":1,"field":"fieldValue"}
Deserialized: MyClass(id=1, field=fieldValue)
Payload on server side: {"id":1}
如您所见,只有 ObjectMapper
在客户端可以序列化 field
属性.