在 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 的 WebRequest 或 HttpServletRequest 对象并在那里使用很棒的 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();
我正在使用 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 的 WebRequest 或 HttpServletRequest 对象并在那里使用很棒的 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();