Groovy httpBuilder POST XML 具有基本身份验证

Groovy httpBuilder POST XML with Basic Authentication

我正在尝试向 Restful WS 发送一个 POST 请求,请求最初是 xml,响应也是如此。

我还需要发送基本身份验证。 起初我遇到了 类 没有被定义的问题,幸运的是它用了 6 个罐子来解决这个问题。

现在我不断收到以下信息: 捕获:groovyx.net.http.HttpResponseException:错误请求

听起来它不喜欢 POST 请求。我尝试了不同的方法,包括 RESTClient,我尝试通过传递文件或作为字符串 var 以其原始 xml 格式委托请求。 我不完全理解 post 或 httpBuilder 中的请求方法之间的区别。

如果有人能帮助指出我做错了什么,将不胜感激

def http = new HTTPBuilder('http://some_IP:some_Port/')
http.auth.basic('userName','password')
http.post(path:'/path/ToServlet')

http.post(POST,XML)
{

  delegate.contentType="text/xml"
  delegate.headers['Content-Type']="text/xml"
  //delegate.post(getClass().getResource("/query.xml"))
 // body = getClass().getResource("/query.xml")
   body = 
   {
      mkp.xmlDeclaration()

        Request{
          Header{
                     Command('Retrieve')
                     EntityIdentifiers
                     {
                       Identifier(Value:'PhoneNumber', Type:'TelephoneNumber')
                      }
                                  EntityName('Subscriber')
                  }
         }
   }
}

万一我在我的请求中翻译了 XML 错误,这里是它的 XML 版本:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Provisioning xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Request>
    <Header>
        <Command>Retrieve</Command>
        <EntityIdentifiers>
            <Identifier Value="phoneNumber" Type="TelephoneNumber" />
        </EntityIdentifiers>
        <EntityName>Subscriber</EntityName>
    </Header>
</Request>
</Provisioning>

看起来您正在处理 post 请求,但两者的格式都不正确。尝试这样的事情:

def writer = new StringWriter()

def req = new MarkupBuilder(writer)
req.mkp.xmlDeclaration(version:"1.0", encoding:"utf-8")
req.Provisioning {
    Request {
        Header {
            Command('Retrieve')
            EntityIdentifiers {
                Identifier(Value:'PhoneNumber', Type:'TelephoneNumber')
            }
            EntityName('Subscriber')
        }
    }
}

def http = new HTTPBuilder('http://some_IP:some_Port/path/ToServlet')
http.auth.basic('userName','password')
http.post(contentType:XML, query:writer) { resp, xml ->
    // do something with response
}

好的,一段时间后我收集到解决方案是将 groovy 库升级到 2.4 以及 httpClient4.0.1 和 httpBuilder 4.x

这似乎已经成功了,因为我最初使用的是 groovy 1.5.5 您的另一个选择是使用 Java 和 Groovy 一起 Java 建立连接,希望使用 URL 和 HttpURLConnection 类那里有足够的例子。 请注意,这不是 SSL,如果您想使用 SSL 和 https

,可能需要采取额外的步骤
import groovy.xml.*
import groovy.util.XmlSlurper.*
import groovy.util.slurpersupport.GPathResult.*


import groovyx.net.http.HTTPBuilder

import groovyx.net.http.EncoderRegistry
import java.net.URLEncoder
import java.net.URLEncoder.*
import org.apache.http.client.*
import org.apache.http.client.HttpResponseException
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.conn.ssl.*
import org.apache.http.conn.ssl.TrustStrategy

import static java.net.URLEncoder.encode
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.HTTPBuilder.request
import static groovyx.net.http.Method.POST
//import static groovyx.net.http.RESTClient.*


def SMSCmirrorServerTor = "http://IP:PORT"
def SMSCmirrorServerMntrl = "http://IP:PORT"


def msisdn = args[0]

//Connect to method HTTP xml URL encoded request, XML response
def connectSMSC(server, MSISDN)
{
  // Variables used for the response
  def result = ""
  //Variables used for request
  // one way is to use raw xml
  def rawXML = """
  <Provisioning xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
          <Request>
                  <Header>
                          make sure your <xml> is well formatted use xml formatter online if need be
                  </Header>
          </Request>
  </Provisioning>"""

    def http = new HTTPBuilder(server)
    http.auth.basic('username','password')
    http.contentType = TEXT
    http.headers = [Accept: 'application/xml', charset: 'UTF-8']

    http.request(POST)
    {
      uri.path = 'Servlet or WS/Path'
      requestContentType = URLENC
      body = "provRequest=" + encode(rawXML,"UTF-8")


      response.success = { resp, xml ->

        def xmlParser = new XmlSlurper().parse(xml)
        //Helps if you know in advance the XML response tree structure at this point it's only xmlSlurper doing the work to parse your xml response
        def ResponseStatus = xmlParser.Response.Header.ResponseStatus
        result += "Response Status: " + ResponseStatus.toString() + "\n================\n"

        def ResponseHeader = xmlParser.Response.Header.Errors.Error
        ResponseHeader.children().each
        {
          result += "\n${it.name()}: " + it.text().toString() + "\n"

        }

        def xmlDataRootNode = xmlParser.Response.Data.Subscriber
        xmlDataRootNode.children().each
        {

          if (it.name() == 'UserDevices')
          {
            result += "\n" + it.UserDevice.name() + " :" + "\n-----------------\n"
            it.UserDevice.children().each
            {
              result += it.name() + " :" + it.text().toString() + "\n"
            }
          }
          else
          {
             result += "\n${it.name()}: " + it.text().toString() + "\n"
          }

        }//End of each iterator on childNodes

        if (ResponseStatus.text().toString() == "Failure")
        {
          def ErrorCode = resp.status
          result += "Failed to process command. Bad request or wrong input"
          //result += "\nHTTP Server returned error code: " + ErrorCode.toString()
          // Note this error is for bad input server will still return status code 200 meaning o.k. unlike err 401 unathorized or err 500 those are http errors so be mindful of which error handling we're talking about here application layer vs http protocol layer error handling
        }

      }//End of response.success closure
    }//End of http.request(POST) method 

  result
}//end of connectSMSC method


//the following is only in case server A is down we can try server B 
def finalResponse=""
try
{
  finalResponse += connectSMSC(SMSCmirrorServerTor,msisdn)

}

catch(org.apache.http.conn.HttpHostConnectException e)
{

  finalResponse += "Encountered HTTP Connection Error\n ${e}\n Unable to connect to host ${SMSCmirrorServerTor}\n Trying to connect to mirror server ${SMSCmirrorServerMntrl} instead\n"
  finalResponse += connectSMSC(SMSCmirrorServerMntrl,msisdn)
}
catch (groovyx.net.http.HttpResponseException ex)
{

  finalResponse += "Encountered HTTP Connection Error Code: ${ex.statusCode}\n"
  finalResponse += connectSMSC(SMSCmirrorServerMntrl,msisdn)
}
/*
*
* java.lang.IllegalArgumentException: port out of range:

*/
catch(java.lang.IllegalArgumentException e)
{
 finalResponse += "Error: " + e
}

catch(java.io.IOException e)
{

  finalResponse += "IO Error: " + e
  finalResponse += connectSMSC(SMSCmirrorServerMntrl,msisdn)
}
catch(java.io.FileNotFoundException e)
{

  finalResponse += "IO Error: " + e
  finalResponse += connectSMSC(SMSCmirrorServerMntrl,msisdn)
}


println finalResponse.toString()