2016-04-12 3 views
0

Я использую Spring's AbstractHttpMessageConverter, чтобы я мог создать экземпляр моего собственного объекта.Получить параметры запроса HTTP в Spring HTTPMessageConverter

Преобразователь

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(), который производит InputStream из HTTPRequest.

Я попытался написать свой собственный код для разбора и создания ParameterMap, но он не всегда работает, если urlencoding отличается.

Есть в любом случае я могу получить весны WebRequest или HttpServletRequest объект из конвертера и использовать там функцию замечательный getParameterMap()?

TL; DR

Есть в любом случае использовать WebRequest или HTTPServletRequest в MessageConverter вместо HTTPInput, так что я могу использовать замечательную getParameterMap функцию(), вместо того, чтобы изобретать колесо?

Благодаря

+0

Вы можете, как правило, только autowire HttpServletRequest к весне управляемых бобов (например, просто добавьте это в поле: '@Autowired HttpServletRequest запрос;'). Имейте в виду, что Spring framework не предназначен для доступа к параметрам url в конвертерах сообщений. Могут быть лучшие места для подключения вашей функциональности (преобразователи?)? –

ответ

2

Посмотрите на то, как это реализовано в Spring FormHttpMessageConverter. Он токенизирует параметр запроса, используя & так же, как ваше решение. Однако он прерывает кодировку для использования из заголовка запроса Content-Type, если это предусмотрено. В противном случае он использует по умолчанию 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; 
    }