Java Spring@RestController自定义JSON反序列化器
我想对某些类使用自定义JSON反序列化程序(Role),但无法使其正常工作。只是没有调用自定义反序列化程序 我使用Spring Boot 1.2 反序列化程序:Java Spring@RestController自定义JSON反序列化器,java,spring,rest,jackson,spring-boot,Java,Spring,Rest,Jackson,Spring Boot,我想对某些类使用自定义JSON反序列化程序(Role),但无法使其正常工作。只是没有调用自定义反序列化程序 我使用Spring Boot 1.2 反序列化程序: public class ModelDeserializer extends JsonDeserializer<Role> { @Override public Role deserialize(JsonParser jsonParser, DeserializationContext deserializ
public class ModelDeserializer extends JsonDeserializer<Role> {
@Override
public Role deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
return null; // this is what should be called but it isn't
}
}
@JsonDeserialize
关于角色
@JsonDeserialize(using = ModelDeserializer.class)
public class Role extends Model {
}
Jackson2ObjectMapperBuilder
Java配置中的bean
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.deserializerByType(Role.class, new ModelDeserializer());
return builder;
}
EDIT这可能是由
@RestController
引起的,因为它与@Controller
一起工作。首先,您不需要覆盖Jackson2ObjectMapperBuilder来添加自定义反序列化程序。当您无法添加@JsonDeserialize
注释时,应该使用这种方法。您应该使用@JsonDeserialize
或重写Jackson2ObjectMapperBuilder
缺少的是@RequestBody
注释:
@RestController
public class JacksonCustomDesRestEndpoint {
@RequestMapping(value = "/role", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Object createRole(@RequestBody Role role) {
return role;
}
}
@JsonDeserialize(using = RoleDeserializer.class)
public class Role {
// ......
}
public class RoleDeserializer extends JsonDeserializer<Role> {
@Override
public Role deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
// .................
return something;
}
}
@RestController
公共类JacksonCustomDesRestEndpoint{
@RequestMapping(value=“/role”,method=RequestMethod.POST,consumes=MediaType.APPLICATION\u JSON\u value,products=MediaType.APPLICATION\u JSON\u value)
@应答器
公共对象createRole(@RequestBody角色){
返回角色;
}
}
@JsonDeserialize(使用=roledSerializer.class)
公共阶级角色{
// ......
}
公共类RoleDeserializer扩展JsonDeserializer{
@凌驾
公共角色反序列化(JsonParser jp,反序列化上下文ctxt)引发IOException,JsonProcessingException{
// .................
归还某物;
}
}
还有另一个非常有趣的解决方案,当您想在调用默认反序列化程序之前修改JSON正文时,它会很有帮助。让我们设想一下,您需要为此使用一些额外的bean(使用@Autowire
机制)
让我们想象一下这样的情况,即您拥有以下控制器:
@RequestMapping(value = "/order/product", method = POST)
public <T extends OrderProductInterface> RestGenericResponse orderProduct(@RequestBody @Valid T data) {
orderService.orderProduct(data);
return generateResponse();
}
上面的代码将提供基于fieldproviderType
的动态反序列化,并根据具体实现进行验证。为了更好地理解,请考虑<代码>订单产品> QuestDATABO/<代码>可以是这样的:
public class OrderProductForARequestData implements OrderProductInterface {
@NotBlank(message = "is mandatory field.")
@Getter @Setter
private String providerId;
@NotBlank(message = "is mandatory field.")
@Getter @Setter
private String providerType;
@NotBlank(message = "is mandatory field.")
@Getter @Setter
private String productToOrder;
}
现在让我们想象一下,在执行默认反序列化之前,我们希望以某种方式初始化providerType
(丰富输入)。因此对象将根据OrderProductInterface
中的规则正确反序列化。
为此,您可以通过以下方式修改@配置
类:
//here can be any annotation which will enable MVC/Boot
@Configuration
public class YourConfiguration{
@Autowired
private ObjectMapper mapper;
@Autowired
private ProviderService providerService;
@Override
public void setup() {
super.setup();
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
if (beanDesc.getBeanClass() == OrderProductInterface.class) {
return new OrderProductInterfaceDeserializer(providerService, beanDesc);
}
return deserializer;
}
});
mapper.registerModule(module);
}
public static class OrderProductInterfaceDeserializer extends AbstractDeserializer {
private static final long serialVersionUID = 7923585097068641765L;
private final ProviderService providerService;
OrderProductInterfaceDeserializer(roviderService providerService, BeanDescription beanDescription) {
super(beanDescription);
this.providerService = providerService;
}
@Override
public Object deserializeWithType(JsonParser p, DeserializationContext context, TypeDeserializer typeDeserializer) throws IOException {
ObjectCodec oc = p.getCodec();
JsonNode node = oc.readTree(p);
//Let's image that we have some identifier for provider type and we want to detect it
JsonNode tmp = node.get("providerId");
Assert.notNull(tmp, "'providerId' is mandatory field");
String providerId = tmp.textValue();
Assert.hasText(providerId, "'providerId' can't be empty");
// Modify node
((ObjectNode) node).put("providerType",providerService.getProvider(providerId));
JsonFactory jsonFactory = new JsonFactory();
JsonParser newParser = jsonFactory.createParser(node.toString());
newParser.nextToken();
return super.deserializeWithType(newParser, context, typeDeserializer);
}
}
}
//这里可以是启用MVC/Boot的任何注释
@配置
公共类配置{
@自动连线
私有对象映射器映射器;
@自动连线
私人供应商服务供应商服务;
@凌驾
公共作废设置(){
super.setup();
SimpleModule=新的SimpleModule();
module.setDeserializerModifier(新的BeanDeserializerModifier(){
@凌驾
公共JsonDeserializer modifyDeserializer(反序列化配置、BeanDescription BeanDeserializer、JsonDeserializer反序列化程序){
if(beanDesc.getBeanClass()==OrderProductInterface.class){
返回新的OrderProductInterfacedSerializer(providerService,beanDesc);
}
返回反序列化器;
}
});
映射器注册表模块(模块);
}
公共静态类OrderProductInterfacedSerializer扩展了抽象反序列化程序{
私有静态最终长serialVersionUID=7923585097068641765L;
私人最终供应商服务供应商服务;
OrderProductInterfacedSerializer(roviderService providerService,BeanDescription BeanDescription){
超级(beanDescription);
this.providerService=providerService;
}
@凌驾
公共对象deserializeWithType(JsonParser p,DeserializationContext上下文,TypeDeserializer TypeDeserializer)引发IOException{
ObjectCodec oc=p.getCodec();
JsonNode=oc.readTree(p);
//让我们想象一下,我们有一些提供程序类型的标识符,我们想检测它
JsonNode tmp=node.get(“providerId”);
Assert.notNull(tmp,“'providerId'是必填字段”);
字符串providerId=tmp.textValue();
Assert.hasText(providerId,“'providerId'不能为空”);
//修改节点
((ObjectNode)node.put(“providerType”,providerService.getProvider(providerId));
JsonFactory JsonFactory=新的JsonFactory();
JsonParser newParser=jsonFactory.createParser(node.toString());
newParser.nextToken();
返回super.deserializeWithType(newParser、context、typeDeserializer);
}
}
}
我也需要这样做,唯一的区别是我有一个get方法,在我的pojo对象中,我使用带有@JsonDeserialize的日期类型,但当我运行该方法时,我会得到一个http 400。(春季4.1.7 y杰克逊2.7.4)
public class OrderProductForARequestData implements OrderProductInterface {
@NotBlank(message = "is mandatory field.")
@Getter @Setter
private String providerId;
@NotBlank(message = "is mandatory field.")
@Getter @Setter
private String providerType;
@NotBlank(message = "is mandatory field.")
@Getter @Setter
private String productToOrder;
}
//here can be any annotation which will enable MVC/Boot
@Configuration
public class YourConfiguration{
@Autowired
private ObjectMapper mapper;
@Autowired
private ProviderService providerService;
@Override
public void setup() {
super.setup();
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
if (beanDesc.getBeanClass() == OrderProductInterface.class) {
return new OrderProductInterfaceDeserializer(providerService, beanDesc);
}
return deserializer;
}
});
mapper.registerModule(module);
}
public static class OrderProductInterfaceDeserializer extends AbstractDeserializer {
private static final long serialVersionUID = 7923585097068641765L;
private final ProviderService providerService;
OrderProductInterfaceDeserializer(roviderService providerService, BeanDescription beanDescription) {
super(beanDescription);
this.providerService = providerService;
}
@Override
public Object deserializeWithType(JsonParser p, DeserializationContext context, TypeDeserializer typeDeserializer) throws IOException {
ObjectCodec oc = p.getCodec();
JsonNode node = oc.readTree(p);
//Let's image that we have some identifier for provider type and we want to detect it
JsonNode tmp = node.get("providerId");
Assert.notNull(tmp, "'providerId' is mandatory field");
String providerId = tmp.textValue();
Assert.hasText(providerId, "'providerId' can't be empty");
// Modify node
((ObjectNode) node).put("providerType",providerService.getProvider(providerId));
JsonFactory jsonFactory = new JsonFactory();
JsonParser newParser = jsonFactory.createParser(node.toString());
newParser.nextToken();
return super.deserializeWithType(newParser, context, typeDeserializer);
}
}
}