Java Spring MessageConverter HTTP 415响应?

Java Spring MessageConverter HTTP 415响应?,java,spring,spring-mvc,paypal,Java,Spring,Spring Mvc,Paypal,我想使用SpringMVC的MessageConverter来实例化一个名为IPNMessage的对象 Paypal IPN消息以纯文本格式出现,我想将其反序列化为IPNMessage对象 cmd=_notify-validate&payment_type=即时支付日期=2016年4月8日星期五09:40:07 GMT+0100(GMT标准时间)&付款状态=已完成和地址状态=已确认和付款人状态=已验证和名字=约翰和姓氏=史密斯和付款人电子邮件=buyer@paypalsandbox.com&付款

我想使用SpringMVC的MessageConverter来实例化一个名为IPNMessage的对象

Paypal IPN消息以
纯文本
格式出现,我想将其反序列化为IPNMessage对象

cmd=_notify-validate&payment_type=即时支付日期=2016年4月8日星期五09:40:07 GMT+0100(GMT标准时间)&付款状态=已完成和地址状态=已确认和付款人状态=已验证和名字=约翰和姓氏=史密斯和付款人电子邮件=buyer@paypalsandbox.com&付款人id=TESTBUYERID01&address\u name=John Smith&address\u country=United States&address\u country\u code=US&address\u zip=95131&address\u state=CA&address\u city=San Jose&address\u street=123任意街道与商业=seller@paypalsandbox.com&收件人/电子邮件=seller@paypalsandbox.com&接收机识别码=seller@paypalsandbox.com&居住国=美国&商品名称1=某物&商品编号1=AK-1234&税收=2.02&货币=美元&货币费用=0.44&货币总额=12.34&货币总额=12.34&货币总额=12.34&货币处理=2.06&货币处理=1.67&货币运输=3.02&货币运输=1.02&货币类型=手推车&货币id=297973429&通知版本=2.1&定制=xyz123&发票=abc1234&测试ipn=1&验证签名=AFCWXV21C7FD0V3BYYRCPSSRL31A4TQREBG4G7QEUK.b0lBrPhTpK8o

消息转换类:

    public class PaypalIPNHttpMessageConverter extends AbstractHttpMessageConverter<IPNMessage> {

    public PaypalIPNHttpMessageConverter() {
        super(new MediaType("application", "text-plain"), MediaType.ALL);
    }

    @Override
    protected boolean supports(Class<?> clazz) {
        return false;
    }

    @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 {

    }
}
当我发出POST请求时,我得到一个HTTP 415,表示我的请求主体不受支持

我是否缺少Spring的进一步配置


注意:我在message converter类中放置了断点,但未到达断点,因此此问题发生在更高层,但不确定在何处。

IPNMessage
有一个需要请求的构造函数。因此,最简单的解决方案是如下更改您的方法:

public void processPaypalIPNRequest(HttpServletRequest request) {
  paypalDelegate.processPaypalIPNRequest(new IPNMessage(request));
}

如果您想要自己的消息转换器,那么理想情况下,它还可以执行新的IPNMessage(request)

问题在于MessageConverter中的supports()方法,而不是评估类签名与IPNMessage(它正在生成)相同

@覆盖
受保护的布尔支持(类clazz){
return clazz==IPNMessage.class;
}

这导致Spring在到达控制器之前抛出更高级别的HTTP415错误。

您没有为自定义转换器指定支持的媒体类型。通过
setSupportedMediaTypes
添加
MediaType.APPLICATION\u FORM\u URLENCODED
。这是怎么回事?抱歉?更改PayPalipHttpMessageConverter上的超级调用。PaypalIPN发送一个
应用程序/x-www-form-urlencoded
请求,而不是
text/plain
。谢谢,但我仍然收到HTP 415错误。是否还需要在context.xml中指定媒体类型?您可能需要注册您创建的自定义转换器。有点类似的。谢谢,不过我也试过了。但是,由于我的控制器方法使用签名
processPaypalIPNRequest(IPNMessage request)
实现我的接口,如果我尝试使用HTTPServletRequest,它会破坏接口约定:(很抱歉没有分享这些详细信息。谢谢,我已经解决了。请c.f.我的答案
    @Override
@Auditable
@RequestMapping(value = "/processPaypalIPNRequest.do", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void processPaypalIPNRequest(@RequestBody IPNMessage ipnMessage) {
    paypalDelegate.processPaypalIPNRequest(ipnMessage);
}
public void processPaypalIPNRequest(HttpServletRequest request) {
  paypalDelegate.processPaypalIPNRequest(new IPNMessage(request));
}
@Override
protected boolean supports(Class<?> clazz) {
    return clazz == IPNMessage.class;
}