在 Spring HTTPMessageConverter 中获取 HTTP 请求参数

Get HTTP request parameters in Spring HTTPMessageConverter

我正在使用 Spring 的 AbstractHttpMessageConverter 来实例化我自己的对象。

转换器

    public class PaypalIPNHttpMessageConverter extends AbstractHttpMessageConverter<IPNMessage> {

    public PaypalIPNHttpMessageConverter() {
        super(MediaType.APPLICATION_FORM_URLENCODED, MediaType.TEXT_PLAIN);
    }

    @Override
    protected boolean supports(Class<?> clazz) {
        return clazz == IPNMessage.class;
    }

    @Override
    protected IPNMessage readInternal(Class<? extends IPNMessage> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        //Converts HTTPRequest into map<string,string> that IPNMessage can then parse
        String requestString = IOUtils.toString(inputMessage.getBody(), "UTF-8");
        Map<String, String[]> requestMap = new LinkedHashMap<>();
        for (String keyValue : requestString.split("&")) { //each key value is delimited by &
            String[] pairs = keyValue.split("=", 2); // = pairs a key to a value
            requestMap.put(pairs[0], pairs[1].split(",")); // , splits multiple values for that key
        }
        return new IPNMessage(requestMap);
    }

    @Override
    protected void writeInternal(IPNMessage ipnMessage, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {

    }
}

在 readINternal() 中,向我传递了一个 HttpInputMessage 对象,它只有 getBody() 函数,它生成 HTTPRequest 的 InputStream。

我尝试编写自己的代码来解析和构建 ParameterMap,但如果 urlencoding 不同,它并不总是有效。

我是否可以从转换器中获取 Spring 的 WebRequestHttpServletRequest 对象并在那里使用很棒的 getParameterMap () 函数?

TL;DR

是否可以在 MessageConverter 中使用 WebRequest 或 HTTPServletRequest 而不是 HttpInput,这样我就可以使用很棒的 getParameterMap() 函数,而不是重新发明轮子?

谢谢

看看SpringFormHttpMessageConverter是如何实现的。它使用 & 标记请求参数,就像您的解决方案一样。但是,如果提供,它会确定要从 Content-Type 请求 header 使用的字符集。否则它使用默认的 UTF-8

//extract from FormHttpMessageConverter
public MultiValueMap<String, String> read(Class<? extends MultiValueMap<String, ?>> clazz,
            HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {

        MediaType contentType = inputMessage.getHeaders().getContentType();
        Charset charset = (contentType.getCharSet() != null ? contentType.getCharSet() : this.charset);
        String body = StreamUtils.copyToString(inputMessage.getBody(), charset);

        String[] pairs = StringUtils.tokenizeToStringArray(body, "&");
        MultiValueMap<String, String> result = new LinkedMultiValueMap<String, String>(pairs.length);
        for (String pair : pairs) {
            int idx = pair.indexOf('=');
            if (idx == -1) {
                result.add(URLDecoder.decode(pair, charset.name()), null);
            }
            else {
                String name = URLDecoder.decode(pair.substring(0, idx), charset.name());
                String value = URLDecoder.decode(pair.substring(idx + 1), charset.name());
                result.add(name, value);
            }
        }
        return result;
    }

您可以使用以下代码简单地获取当前请求

HttpServletRequest httpRequest = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();