本文介绍了在Spring Boot中使用内容类型application / x-www-form-urlencoded的请求的自定义反序列化器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为 application / x-www-form-urlencoded 类型的请求中的某些参数编写自定义反序列化器,就像在<$ c类型的请求中使用的一样c $ c> application / json ,带有 @JsonDeserialize(使用= AbcDeserializer.class)批注。我正在使用spring boot和Jackson,尽管我发现这里没有使用Jackson。

I want to write a custom deserializer for some parameters in the requests of type application/x-www-form-urlencoded like used in case of requests of type application/json, with @JsonDeserialize(using = AbcDeserializer.class) annotation. I am using spring boot and Jackson, although I figured out that Jackson is not used here.

我试图弄清楚spring默认情况下如何反序列化对象。

I tried figuring out how spring deserializes object by default. But couldn't find a way.

spring如何反序列化 application / x-www-form-urlencoded 默认情况下?

How does spring deserialize a request of type application/x-www-form-urlencoded by default?

我是否可以覆盖此反序列化,最好在需要特殊处理的参数上使用一些注释?

Can I override this deserialization, preferrably by using some annotation on parameters that need special handling?

推荐答案

我的解决方案基于自定义 ConditionalGenericConverter 。它与 @ModelAttribute 一起使用。让我们看看整个实现。

My solution is based on custom ConditionalGenericConverter. It works with @ModelAttribute. Let's see whole implementation.

应用程序引导程序示例。

Application bootstrap example.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@SpringBootApplication
public class DemoApplication {

    @Configuration
    public class WebConfig extends WebMvcConfigurerAdapter {

        @Override
        public void addFormatters(FormatterRegistry registry) {
            registry.addConverter(new Base64JsonToObjectConverter());
        }
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

这是自定义注释。

Here is custom annotation.

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Base64Encoded {
}

接下来,我们需要实现转换器。如您所见,转换器仅转换 String -> Object ,其中 Object 字段必须使用 Base64Encoded 注释进行注释。

Next we need implementation of the converter. As you can see, converter converts only String -> Object, where Object field must be annotated with Base64Encoded annotation.

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Base64;
import java.util.Collections;
import java.util.Set;

@Component
public class Base64JsonToObjectConverter implements ConditionalGenericConverter {

    private final ObjectMapper objectMapper;
    private final Base64.Decoder decoder;

    public Base64JsonToObjectConverter() {
        this.objectMapper = new ObjectMapper();
        this.decoder = Base64.getDecoder();
    }

    @Override
    public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
        return targetType.hasAnnotation(Base64Encoded.class);
    }

    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
        return Collections.singleton(new ConvertiblePair(String.class, Object.class));
    }

    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        if (source == null) {
            return null;
        }
        String string = (String) source;

        try {
            byte[] decodedValue = this.decoder.decode(string);

            return this.objectMapper.readValue(decodedValue, targetType.getType());
        } catch (IllegalArgumentException | IOException e) {
            throw new ConversionFailedException(sourceType, targetType, source, e);
        }
    }
}

以下是POJO的示例(请参阅带注释的字段)和REST控制器。

Here is an example of POJO (see the annotated field) and REST controller.

import com.example.demo.Base64Encoded;

public class MyRequest {

    private String varA;

    @Base64Encoded
    private B varB;

    public String getVarA() {
        return varA;
    }

    public void setVarA(String varA) {
        this.varA = varA;
    }

    public B getVarB() {
        return varB;
    }

    public void setVarB(B varB) {
        this.varB = varB;
    }
}



import com.example.demo.domain.MyRequest;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @RequestMapping(path = "/test", method = RequestMethod.POST)
    public MyRequest test(@ModelAttribute MyRequest myRequest) {
        return myRequest;
    }
}

这篇关于在Spring Boot中使用内容类型application / x-www-form-urlencoded的请求的自定义反序列化器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 20:03