axis1.4 客户端调用webservice接口返回错误:no SOAPAction header!

服务端使用webservice框架axis1.4开发,客户端发送的报文中,HTTP head 没有SOAPAction
返回报文:
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <soapenv:Fault>
   <faultcode xmlns:ns1="http://xml.apache.org/axis/">ns1:Client.NoSOAPAction</faultcode>
   <faultstring>no SOAPAction header!</faultstring>
   <detail>
    <ns2:hostname xmlns:ns2="http://xml.apache.org/axis/">host1</ns2:hostname>
   </detail>
  </soapenv:Fault>
 </soapenv:Body>
</soapenv:Envelope> 




原因:
     这是axis1.4的一个bug,正常代码应该是在校验客户端访问的HTTP头部信息时,获取SOAPAction,如果为空,则直接取request.getContextPath();看axis源码org.apache.axis.transport.http.AxisServlet类中的getSoapAction(HttpServletRequest req);这个方法确实是想这么写来着,但是写法上有问题,才会出现这个bug。
   下面是axisServlet中的getSoapAction代码:
 
/**
     * Extract the SOAPAction header.
     * if SOAPAction is null then we'll we be forced to scan the body for it.
     * if SOAPAction is "" then use the URL
     * @param req incoming request
     * @return the action
     * @throws AxisFault
     */
    private String getSoapAction(HttpServletRequest req) throws AxisFault {
        String soapAction = req.getHeader(HTTPConstants.HEADER_SOAP_ACTION );
        if (soapAction == null) {
            String contentType = req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE );
            if(contentType != null) {
                int index = contentType.indexOf( "action" );
                if(index != -1){
                    soapAction = contentType.substring(index + 7);
                }
            }
        }
        if ( isDebug) {
            log.debug( "HEADER_SOAP_ACTION:" + soapAction);
            /**
             * Technically, if we don't find this header, we should probably fault.
             * It's required in the SOAP HTTP binding.
             */
        }
        if (soapAction == null) {
            AxisFault af = new AxisFault( "Client.NoSOAPAction" ,
                                         Messages. getMessage( "noHeader00",
                    "SOAPAction" ),
                                         null, null);
            exceptionLog .error(Messages.getMessage( "genFault00" ), af);
            throw af;
        }
        // the SOAP 1.1 spec & WS-I 1.0 says:
        // soapaction    = "SOAPAction" ":" [ <"> URI-reference <"> ]
        // some implementations leave off the quotes
        // we strip them if they are present
        if (soapAction.startsWith( "\"" ) && soapAction.endsWith("\"" )
            && soapAction.length() >= 2) {
            int end = soapAction.length() - 1;
            soapAction = soapAction.substring(1, end);
        }
        if (soapAction.length() == 0) {
            soapAction = req.getContextPath(); // Is this right?
        }
        return soapAction;
    }



上面代码一目了然,就是说在尝试取 req.getHeader(" SOAPAction " )和 req.getHeader(" Content-Type " )中的action都为空时,就直接记录到 AxisFault  类中,返回给客户端。然后下面的    if  (soapAction.length() == 0) {   soapAction = req.getContextPath();  // Is this right?  }
不会执行到


解决方法:
     根据上面所述,有两个方法:
     1.要求客户端访问时,在HTTP header中必须有SOAPAction(soapaction的内容是什么我感觉不重要,即便为空字符串我测试也是可以正常的。)
     2.就是修改服务端axis bug,首先想到的就是自定义一个servlet然后继承AxisServlet,改写getSoapAction 代码,但是会发现getSoapAction是private的,所以只能copy整个AxisServlet代码修改getSoapAction部分(只需把写AxisFault部分代码放在最后面,注意上面中的if语句中,soapAction.length()==0 要改一下,因为如果soapAction为空这样会抛出空指针异常的。),然后修改web.xml中配置的servlet为自定义的类路径。

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值